Browse Source

first commit

master
陈福行 6 years ago
commit
82b78befae
64 changed files with 3706 additions and 0 deletions
  1. 13
    0
      .gitignore
  2. 224
    0
      .idea/codeStyles/Project.xml
  3. 5
    0
      .idea/codeStyles/codeStyleConfig.xml
  4. 6
    0
      .idea/compiler.xml
  5. 3
    0
      .idea/dictionaries/xing.xml
  6. 6
    0
      .idea/encodings.xml
  7. 18
    0
      .idea/gradle.xml
  8. 14
    0
      .idea/misc.xml
  9. 12
    0
      .idea/runConfigurations.xml
  10. BIN
      aibrushDemo.jks
  11. 1
    0
      app/.gitignore
  12. 29
    0
      app/build.gradle
  13. BIN
      app/libs/ToothbrushLibrary.jar
  14. 21
    0
      app/proguard-rules.pro
  15. 26
    0
      app/src/androidTest/java/aicare/net/cn/aibrushdemo/ExampleInstrumentedTest.java
  16. 48
    0
      app/src/main/AndroidManifest.xml
  17. 146
    0
      app/src/main/java/aicare/net/cn/aibrushdemo/DeviceDialog.java
  18. 82
    0
      app/src/main/java/aicare/net/cn/aibrushdemo/DeviceListAdapter.java
  19. 20
    0
      app/src/main/java/aicare/net/cn/aibrushdemo/InitApplication.java
  20. 1032
    0
      app/src/main/java/aicare/net/cn/aibrushdemo/MainActivity.java
  21. 52
    0
      app/src/main/java/aicare/net/cn/aibrushdemo/WelcomeActivity.java
  22. 95
    0
      app/src/main/java/aicare/net/cn/aibrushdemo/utils/AppUtils.java
  23. 173
    0
      app/src/main/java/aicare/net/cn/aibrushdemo/utils/SPUtils.java
  24. 114
    0
      app/src/main/java/aicare/net/cn/aibrushdemo/utils/T.java
  25. 34
    0
      app/src/main/res/drawable-v24/ic_launcher_foreground.xml
  26. 9
    0
      app/src/main/res/drawable/btn_clear_log_bg.xml
  27. 171
    0
      app/src/main/res/drawable/ic_launcher_background.xml
  28. 19
    0
      app/src/main/res/drawable/ic_rssi_bar.xml
  29. 365
    0
      app/src/main/res/layout/activity_main.xml
  30. 23
    0
      app/src/main/res/layout/activity_welcome.xml
  31. 14
    0
      app/src/main/res/layout/device_list_empty.xml
  32. 52
    0
      app/src/main/res/layout/device_list_row.xml
  33. 44
    0
      app/src/main/res/layout/dialog_device.xml
  34. 5
    0
      app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  35. 5
    0
      app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  36. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher.png
  37. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher_round.png
  38. BIN
      app/src/main/res/mipmap-hdpi/ic_rssi_0_bar.png
  39. BIN
      app/src/main/res/mipmap-hdpi/ic_rssi_1_bar.png
  40. BIN
      app/src/main/res/mipmap-hdpi/ic_rssi_2_bars.png
  41. BIN
      app/src/main/res/mipmap-hdpi/ic_rssi_3_bars.png
  42. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher.png
  43. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher_round.png
  44. BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher.png
  45. BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
  46. BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  47. BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
  48. BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  49. BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
  50. 106
    0
      app/src/main/res/values-zh-rCN/arrays.xml
  51. 123
    0
      app/src/main/res/values-zh-rCN/strings.xml
  52. 121
    0
      app/src/main/res/values/arrays.xml
  53. 8
    0
      app/src/main/res/values/colors.xml
  54. 5
    0
      app/src/main/res/values/dimens.xml
  55. 125
    0
      app/src/main/res/values/strings.xml
  56. 15
    0
      app/src/main/res/values/styles.xml
  57. 17
    0
      app/src/test/java/aicare/net/cn/aibrushdemo/ExampleUnitTest.java
  58. 27
    0
      build.gradle
  59. 15
    0
      gradle.properties
  60. BIN
      gradle/wrapper/gradle-wrapper.jar
  61. 6
    0
      gradle/wrapper/gradle-wrapper.properties
  62. 172
    0
      gradlew
  63. 84
    0
      gradlew.bat
  64. 1
    0
      settings.gradle

+ 13
- 0
.gitignore View File

@@ -0,0 +1,13 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild

+ 224
- 0
.idea/codeStyles/Project.xml View File

@@ -0,0 +1,224 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="android" withSubpackages="true" static="false" />
<emptyLine />
<package name="com" withSubpackages="true" static="false" />
<emptyLine />
<package name="junit" withSubpackages="true" static="false" />
<emptyLine />
<package name="net" withSubpackages="true" static="false" />
<emptyLine />
<package name="org" withSubpackages="true" static="false" />
<emptyLine />
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="true" />
<emptyLine />
</value>
</option>
<option name="RIGHT_MARGIN" value="100" />
<AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true" />
</AndroidXmlCodeStyleSettings>
<JavaCodeStyleSettings>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="99" />
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value />
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="android" withSubpackages="true" static="false" />
<emptyLine />
<package name="com" withSubpackages="true" static="false" />
<emptyLine />
<package name="junit" withSubpackages="true" static="false" />
<emptyLine />
<package name="net" withSubpackages="true" static="false" />
<emptyLine />
<package name="org" withSubpackages="true" static="false" />
<emptyLine />
<package name="java" withSubpackages="true" static="false" />
<emptyLine />
<package name="javax" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="false" />
<emptyLine />
<package name="" withSubpackages="true" static="true" />
<emptyLine />
</value>
</option>
</JavaCodeStyleSettings>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>
<codeStyleSettings language="XML">
<option name="FORCE_REARRANGE_MODE" value="1" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_NAMESPACE>Namespace:</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_NAMESPACE>Namespace:</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_width</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_height</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:layout_.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:width</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:height</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>

+ 5
- 0
.idea/codeStyles/codeStyleConfig.xml View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default (1)" />
</state>
</component>

+ 6
- 0
.idea/compiler.xml View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="9" />
</component>
</project>

+ 3
- 0
.idea/dictionaries/xing.xml View File

@@ -0,0 +1,3 @@
<component name="ProjectDictionaryState">
<dictionary name="xing" />
</component>

+ 6
- 0
.idea/encodings.xml View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8" addBOMForNewFiles="with NO BOM">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

+ 18
- 0
.idea/gradle.xml View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

+ 14
- 0
.idea/misc.xml View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CMakeSettings">
<configurations>
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
</configurations>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

+ 12
- 0
.idea/runConfigurations.xml View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

BIN
aibrushDemo.jks View File


+ 1
- 0
app/.gitignore View File

@@ -0,0 +1 @@
/build

+ 29
- 0
app/build.gradle View File

@@ -0,0 +1,29 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 28
defaultConfig {
applicationId "aicare.net.cn.aibrushdemo"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation files('libs/ToothbrushLibrary.jar')
}

BIN
app/libs/ToothbrushLibrary.jar View File


+ 21
- 0
app/proguard-rules.pro View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

+ 26
- 0
app/src/androidTest/java/aicare/net/cn/aibrushdemo/ExampleInstrumentedTest.java View File

@@ -0,0 +1,26 @@
package aicare.net.cn.aibrushdemo;

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();

assertEquals("aicare.net.cn.aibrushdemo", appContext.getPackageName());
}
}

+ 48
- 0
app/src/main/AndroidManifest.xml View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:tools="http://schemas.android.com/tools"
package="aicare.net.cn.aibrushdemo"
xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name=".InitApplication"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".WelcomeActivity"
android:launchMode="singleTop"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/AppTheme">

</activity>

<service android:name="aicare.net.cn.toothbrushlibrary.toothbrush.ToothbrushService"/>
</application>

</manifest>

+ 146
- 0
app/src/main/java/aicare/net/cn/aibrushdemo/DeviceDialog.java View File

@@ -0,0 +1,146 @@
package aicare.net.cn.aibrushdemo;

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

import aicare.net.cn.toothbrushlibrary.entity.BrushDevice;

import static android.R.id.empty;
import static android.R.id.list;

/**
* Created by Suzy on 2016/10/26.
*/

public class DeviceDialog extends Dialog {

private DeviceListAdapter adapter;
private Button scanButton;
private Context context;
private OnDeviceScanListener listener;
private boolean scanning;
private List<BrushDevice> listValues;
private ListView listView;

public void setScanning(boolean scanning) {
this.scanning = scanning;
}

public interface OnDeviceScanListener {
void scan();
void stop();
void connect(BrushDevice brushDevice);
}

public DeviceDialog(Context context, OnDeviceScanListener listener) {
super(context);
this.context = context;
this.listener = listener;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_device);
setTitle(R.string.scanner_title);
listValues = new ArrayList<>();
initViews();
initEvents();

}

private void initEvents() {
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(final AdapterView<?> parent, final View view, final int position, final long id) {
stopScanDevice();
dismiss();
final BrushDevice d = (BrushDevice) adapter.getItem(position);
listener.connect(d);
}
});


scanButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (v.getId() == R.id.action_cancel) {
if (scanning) {
stopScanDevice();
dismiss();
} else {
startScanDevice();
}
}
}
});
}

private void initViews() {
listView = (ListView) findViewById(list);
TextView textView = (TextView) findViewById(empty);
if (listValues.isEmpty()) {
listView.setEmptyView(textView);
}
adapter = new DeviceListAdapter(context, listValues);
listView.setAdapter(adapter);
scanButton = (Button) findViewById(R.id.action_cancel);
}

private final static int SCAN_DURATION = 5000;

private Handler handler = new Handler();

public void startScanDevice() {
clearDevices();
scanButton.setText(R.string.scanner_action_cancel);
if (!scanning) {
listener.scan();
handler.postDelayed(stopScanRunnable, SCAN_DURATION);
}
}

private Runnable stopScanRunnable = new Runnable() {
@Override
public void run() {
stopScanDevice();
}
};

private void stopScanDevice() {
if (scanning) {
scanButton.setText(R.string.scanner_action_scan);
listener.stop();
}
}

public void setDevice(BrushDevice device) {
if (device!=null&&!listValues.contains(device)) {
listValues.add(device);
}

adapter.notifyDataSetChanged();
}

private void clearDevices() {
listValues.clear();
adapter.notifyDataSetChanged();
}

@Override
public void dismiss() {
super.dismiss();
handler.removeCallbacks(stopScanRunnable);
stopScanDevice();
}
}

+ 82
- 0
app/src/main/java/aicare/net/cn/aibrushdemo/DeviceListAdapter.java View File

@@ -0,0 +1,82 @@
/*******************************************************************************
* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
* <p>
* The information contained herein is property of Nordic Semiconductor ASA. Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
* Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided. This heading must NOT be removed from the file.
******************************************************************************/
package aicare.net.cn.aibrushdemo;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

import aicare.net.cn.toothbrushlibrary.entity.BrushDevice;

/**
* DeviceListAdapter class is list adapter for showing scanned Devices name, address and RSSI image based on RSSI values.
*/
public class DeviceListAdapter extends BaseAdapter {
private static final int NO_RSSI = -1000;

private final List<BrushDevice> listValues;
private final Context context;

public DeviceListAdapter(Context context, List<BrushDevice> listValues) {
this.context = context;
this.listValues = listValues;
}

@Override
public int getCount() {
return listValues.size();
}

@Override
public Object getItem(int position) {
return listValues.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View view, ViewGroup parent) {
ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = LayoutInflater.from(context).inflate(R.layout.device_list_row, null);
holder.name = (TextView) view.findViewById(R.id.name);
holder.address = (TextView) view.findViewById(R.id.address);
holder.rssi = (ImageView) view.findViewById(R.id.rssi);
holder.did = (TextView) view.findViewById(R.id.did);
view.setTag(holder);
}
holder = (ViewHolder) view.getTag();
final BrushDevice device = (BrushDevice) getItem(position);
final String name = device.getName();
holder.name.setText(name != null ? name : context.getString(R.string.not_available));
holder.address.setText(device.getAddress());
if (device.getRssi() != NO_RSSI) {
final int rssiPercent = (int) (100.0f * (127.0f + device.getRssi()) / (127.0f + 20.0f));
holder.rssi.setImageLevel(rssiPercent);
holder.rssi.setVisibility(View.VISIBLE);
}
holder.did.setText(device.getManufacturerId() + "_" + device.getModelId());
return view;
}

private class ViewHolder {
private TextView name;
private TextView address;
private ImageView rssi;
private TextView did;
}
}

+ 20
- 0
app/src/main/java/aicare/net/cn/aibrushdemo/InitApplication.java View File

@@ -0,0 +1,20 @@
package aicare.net.cn.aibrushdemo;

import android.app.Application;

import aicare.net.cn.toothbrushlibrary.utils.FileUtils;

/**
* Created by Suzy on 2016/10/22.
*/

public class InitApplication extends Application {

private final static String DIRECTORY_NAME = "BrushDemo";

@Override
public void onCreate() {
super.onCreate();
FileUtils.createFileDirectories(DIRECTORY_NAME);
}
}

+ 1032
- 0
app/src/main/java/aicare/net/cn/aibrushdemo/MainActivity.java
File diff suppressed because it is too large
View File


+ 52
- 0
app/src/main/java/aicare/net/cn/aibrushdemo/WelcomeActivity.java View File

@@ -0,0 +1,52 @@
package aicare.net.cn.aibrushdemo;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import aicare.net.cn.aibrushdemo.utils.AppUtils;
import aicare.net.cn.aibrushdemo.utils.T;

/**
* Created by Suzy on 2016/5/10.
*/
public class WelcomeActivity extends AppCompatActivity {
private TextView tv_show_version;

private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
initViews();
if (ensureBLESupported()) {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
openActivity(MainActivity.class);
WelcomeActivity.this.finish();
}
}, 2000);
}else {
T.showLong(this, R.string.not_support_ble);
this.finish();
}
}

protected boolean ensureBLESupported() {
return getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
}

protected void openActivity(Class<?> cls) {
Intent intent = new Intent(this, cls);
startActivity(intent);
}

private void initViews() {
tv_show_version = (TextView) this.findViewById(R.id.tv_show_version);
tv_show_version.setText(String.format(getResources().getString(R.string.version), AppUtils.getVersionName(this)));
}
}

+ 95
- 0
app/src/main/java/aicare/net/cn/aibrushdemo/utils/AppUtils.java View File

@@ -0,0 +1,95 @@
package aicare.net.cn.aibrushdemo.utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.location.LocationManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;

//跟App相关的辅助类
public class AppUtils {

private AppUtils() {
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");

}

/**
* 获取应用程序名称
*/
public static String getAppName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
int labelRes = packageInfo.applicationInfo.labelRes;
return context.getResources().getString(labelRes);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}

/**
* [获取应用程序版本名称信息]
*
* @param context
* @return 当前应用的版本名称
*/
public static String getVersionName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
return packageInfo.versionName;

} catch (NameNotFoundException e) {
e.printStackTrace();
}
return null;
}

/**
* 获取手机IMEI
*
* @param context
* @return 手机IMEI
*/
@SuppressLint("MissingPermission")
public static String getIMEI(Context context) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return telephonyManager.getDeviceId();
}


/**
* 手机是否开启位置服务
*/
public static boolean isLocServiceEnable(Context context) {
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (gps || network) {
return true;
}
return false;
}


/**
* 进入定位服务
*/
public static void startLocationActivity(Activity activity, int code) {
Intent localIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
if (activity.getPackageManager().resolveActivity(localIntent,
PackageManager.MATCH_DEFAULT_ONLY) != null) {
activity.startActivityForResult(localIntent, code);
}
}
}

+ 173
- 0
app/src/main/java/aicare/net/cn/aibrushdemo/utils/SPUtils.java View File

@@ -0,0 +1,173 @@
package aicare.net.cn.aibrushdemo.utils;

import android.content.Context;
import android.content.SharedPreferences;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

public class SPUtils {
public SPUtils() {
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}

/**
* 保存在手机里面的文件名
*/
public static final String FILE_NAME = "share_data";

/**
* 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
*
* @param context
* @param key
* @param object
*/
public static void put(Context context, String key, Object object) {

SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();

if (object instanceof String) {
editor.putString(key, (String) object);
} else if (object instanceof Integer) {
editor.putInt(key, (Integer) object);
} else if (object instanceof Boolean) {
editor.putBoolean(key, (Boolean) object);
} else if (object instanceof Float) {
editor.putFloat(key, (Float) object);
} else if (object instanceof Long) {
editor.putLong(key, (Long) object);
} else {
editor.putString(key, object.toString());
}

SharedPreferencesCompat.apply(editor);
}

/**
* 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
*
* @param context
* @param key
* @param defaultObject
* @return
*/
public static Object get(Context context, String key, Object defaultObject) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);

if (defaultObject instanceof String) {
return sp.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer) {
return sp.getInt(key, (Integer) defaultObject);
} else if (defaultObject instanceof Boolean) {
return sp.getBoolean(key, (Boolean) defaultObject);
} else if (defaultObject instanceof Float) {
return sp.getFloat(key, (Float) defaultObject);
} else if (defaultObject instanceof Long) {
return sp.getLong(key, (Long) defaultObject);
}

return null;
}

/**
* 移除某个key值已经对应的值
*
* @param context
* @param key
*/
public static void remove(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
SharedPreferencesCompat.apply(editor);
}

/**
* 清除所有数据
*
* @param context
*/
public static void clear(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
SharedPreferencesCompat.apply(editor);
}

/**
* 查询某个key是否已经存在
*
* @param context
* @param key
* @return
*/
public static boolean contains(Context context, String key) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
return sp.contains(key);
}

/**
* 返回所有的键值对
*
* @param context
* @return
*/
public static Map<String, ?> getAll(Context context) {
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
return sp.getAll();
}

/**
* 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
*
* @author zhy
*
*/
private static class SharedPreferencesCompat {
private static final Method sApplyMethod = findApplyMethod();

/**
* 反射查找apply的方法
*
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private static Method findApplyMethod() {
try {
Class clz = SharedPreferences.Editor.class;
return clz.getMethod("apply");
} catch (NoSuchMethodException e) {
}

return null;
}

/**
* 如果找到则使用apply执行,否则使用commit
*
* @param editor
*/
public static void apply(SharedPreferences.Editor editor) {
try {
if (sApplyMethod != null) {
sApplyMethod.invoke(editor);
return;
}
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
editor.commit();
}
}

}

+ 114
- 0
app/src/main/java/aicare/net/cn/aibrushdemo/utils/T.java View File

@@ -0,0 +1,114 @@
package aicare.net.cn.aibrushdemo.utils;

import android.content.Context;
import android.widget.Toast;

//Toast统一管理类
public class T {

private T() {
/* cannot be instantiated */
throw new UnsupportedOperationException("cannot be instantiated");
}

private static Toast mToast;

/**
* 短时间显示Toast
*
* @param context
* @param message
*/
public static void showShort(Context context, CharSequence message) {
if (mToast == null) {
mToast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
} else {
mToast.setText(message);
mToast.setDuration(Toast.LENGTH_SHORT);
}
mToast.show();
}

/**
* 短时间显示Toast
*
* @param context
* @param message
*/
public static void showShort(Context context, int message) {
if (mToast == null) {
mToast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
} else {
mToast.setText(message);
mToast.setDuration(Toast.LENGTH_SHORT);
}
mToast.show();
}

/**
* 长时间显示Toast
*
* @param context
* @param message
*/
public static void showLong(Context context, CharSequence message) {
if (mToast == null) {
mToast = Toast.makeText(context, message, Toast.LENGTH_LONG);
} else {
mToast.setText(message);
mToast.setDuration(Toast.LENGTH_LONG);
}
mToast.show();
}

/**
* 长时间显示Toast
*
* @param context
* @param message
*/
public static void showLong(Context context, int message) {
if (mToast == null) {
mToast = Toast.makeText(context, message, Toast.LENGTH_LONG);
} else {
mToast.setText(message);
mToast.setDuration(Toast.LENGTH_LONG);
}
mToast.show();
}

/**
* 自定义显示Toast时间
*
* @param context
* @param message
* @param duration
*/
public static void show(Context context, CharSequence message, int duration) {
if (mToast == null) {
mToast = Toast.makeText(context, message, duration);
} else {
mToast.setText(message);
mToast.setDuration(duration);
}
mToast.show();
}

/**
* 自定义显示Toast时间
*
* @param context
* @param message
* @param duration
*/
public static void show(Context context, int message, int duration) {
if (mToast == null) {
mToast = Toast.makeText(context, message, duration);
} else {
mToast.setText(message);
mToast.setDuration(duration);
}
mToast.show();
}

}

+ 34
- 0
app/src/main/res/drawable-v24/ic_launcher_foreground.xml View File

@@ -0,0 +1,34 @@
<vector xmlns:aapt="http://schemas.android.com/aapt"
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0"/>
<item
android:color="#00000000"
android:offset="1.0"/>
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1"/>
</vector>

+ 9
- 0
app/src/main/res/drawable/btn_clear_log_bg.xml View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<solid android:color="@android:color/transparent"/>
<stroke
android:width="1dp"
android:color="@color/colorPrimary"/>
</shape>

+ 171
- 0
app/src/main/res/drawable/ic_launcher_background.xml View File

@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#008577"
android:pathData="M0,0h108v108h-108z"/>
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8"/>
</vector>

+ 19
- 0
app/src/main/res/drawable/ic_rssi_bar.xml View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
The information contained herein is property of Nordic Semiconductor ASA.
Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
This heading must NOT be removed from the file.
-->
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:maxLevel="10"
android:drawable="@mipmap/ic_rssi_0_bar" />
<item android:maxLevel="28"
android:drawable="@mipmap/ic_rssi_1_bar" />
<item android:maxLevel="45"
android:drawable="@mipmap/ic_rssi_2_bars" />
<item android:maxLevel="100"
android:drawable="@mipmap/ic_rssi_3_bars" />
</level-list>

+ 365
- 0
app/src/main/res/layout/activity_main.xml View File

@@ -0,0 +1,365 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">

<Button
android:id="@+id/btn_connect_state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/not_connect_device"/>


<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">

<Button
android:id="@+id/btn_on_off"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/on_off"/>

<Button
android:id="@+id/btn_query_history"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/query_history"/>

<Button
android:id="@+id/btn_cancel_history"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/cancel_history"/>

<Button
android:id="@+id/btn_delete_history"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/delete_history"/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:orientation="horizontal"
android:visibility="gone">

<EditText
android:id="@+id/et_device_sn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:hint="@string/set_sn_hint"
android:maxLines="1"/>

<Button
android:id="@+id/btn_set_sn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/set_sn"/>

<Button
android:id="@+id/btn_query_device_sn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/query_device_sn"/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:orientation="horizontal">

<EditText
android:id="@+id/et_manufacturer_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Manufacturer Id"
android:inputType="number"
android:maxLines="1"/>

<EditText
android:id="@+id/et_model_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Model Id"
android:inputType="number"
android:maxLines="1"/>

<Button
android:id="@+id/btn_set_did_two"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/set_did"/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:orientation="horizontal">

<EditText
android:id="@+id/et_did"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:hint="@string/set_did_hint"
android:inputType="number"
android:maxLines="1"/>

<Button
android:id="@+id/btn_set_did"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/set_did"/>

<Button
android:id="@+id/btn_get_did"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/get_did"/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center"
android:orientation="horizontal">

<EditText
android:id="@+id/et_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:hint="@string/set_name_hint"
android:maxLines="1"/>

<Button
android:id="@+id/btn_set_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/set_name"/>

<Button
android:id="@+id/btn_get_mode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/get_mode"/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">

<Button
android:id="@+id/btn_query_work_state"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/query_work_state"/>

<Button
android:id="@+id/btn_query_battery_state"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/query_battery_state"/>

<Button
android:id="@+id/btn_set_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/set_time"/>

<Button
android:id="@+id/btn_query_time"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/query_time"/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@string/work_mode"/>

<LinearLayout
android:id="@+id/ll_tv_freq_duty"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:orientation="horizontal">

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@string/work_feq"/>

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@string/work_duty"/>
</LinearLayout>

<TextView
android:id="@+id/tv_preset_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="center"
android:text="@string/preset_id"
android:visibility="gone"/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<Spinner
android:id="@+id/spinner_mode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>

<LinearLayout
android:id="@+id/ll_spinner_freq_duty"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:orientation="horizontal">

<Spinner
android:id="@+id/spinner_freq_level"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>

<Spinner
android:id="@+id/spinner_duty_level"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>

<Spinner
android:id="@+id/spinner_presett_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:visibility="gone"/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">

<TextView
android:id="@+id/tv_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/work_duration"/>

<SeekBar
android:id="@+id/seek_bar_duration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="24"/>
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">

<Button
android:id="@+id/btn_set_work_param"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/set_work_param"/>

<Button
android:id="@+id/btn_get_version"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/get_version"/>


<Button
android:id="@+id/btn_update"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/update"/>

<Button
android:id="@+id/btn_clear_log"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/clear_log"/>

</LinearLayout>
</LinearLayout>


<ListView
android:id="@+id/lv_show_info"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

+ 23
- 0
app/src/main/res/layout/activity_welcome.xml View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="true"
android:fitsSystemWindows="true"
android:orientation="vertical">

<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:text="@string/app_name"
android:textSize="22sp" />

<TextView
android:id="@+id/tv_show_version"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="5dp"/>
</LinearLayout>

+ 14
- 0
app/src/main/res/layout/device_list_empty.xml View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
The information contained herein is property of Nordic Semiconductor ASA.
Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
This heading must NOT be removed from the file.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:gravity="center_vertical"
android:text="@string/scanner_empty" />

+ 52
- 0
app/src/main/res/layout/device_list_row.xml View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
The information contained herein is property of Nordic Semiconductor ASA.
Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
This heading must NOT be removed from the file.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeightSmall"
android:orientation="vertical"
android:padding="6dp">

<ImageView
android:id="@+id/rssi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/ic_rssi_bar"
tools:ignore="contentDescription" />

<TextView
android:id="@+id/did"
android:layout_toLeftOf="@id/rssi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:textColor="#000000"
android:textSize="14sp" />

<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:textColor="#000000"
android:textSize="14sp" />

<TextView
android:id="@+id/address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/name"
android:textColor="#000000"
android:textSize="12sp" />

</RelativeLayout>

+ 44
- 0
app/src/main/res/layout/dialog_device.xml View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
The information contained herein is property of Nordic Semiconductor ASA.
Terms and conditions of usage are described in detail in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
Licensees are granted free, non-transferable use of the information. NO WARRANTY of ANY KIND is provided.
This heading must NOT be removed from the file.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#FFFFFF"
android:orientation="vertical">

<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:scrollbarStyle="outsideOverlay" />

<TextView
android:id="@android:id/empty"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="@string/scanner_empty"
android:gravity="center"
android:textSize="18sp"
android:paddingLeft="12dp"
android:paddingRight="12dp"/>

<Button
android:id="@+id/action_cancel"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/scanner_action_scan" />

</LinearLayout>

+ 5
- 0
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

+ 5
- 0
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png View File


BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.png View File


BIN
app/src/main/res/mipmap-hdpi/ic_rssi_0_bar.png View File


BIN
app/src/main/res/mipmap-hdpi/ic_rssi_1_bar.png View File


BIN
app/src/main/res/mipmap-hdpi/ic_rssi_2_bars.png View File


BIN
app/src/main/res/mipmap-hdpi/ic_rssi_3_bars.png View File


BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png View File


BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.png View File


BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png View File


BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.png View File


BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png View File


BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png View File


BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png View File


BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png View File


+ 106
- 0
app/src/main/res/values-zh-rCN/arrays.xml View File

@@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>

<string-array name="arr_freq_level">
<item>默认</item>
<item>1档(180Hz)</item>
<item>2档(200Hz)</item>
<item>3档(220Hz)</item>
<item>4档(240Hz)</item>
<item>5档(260Hz)</item>
<item>6档(280Hz)</item>
<item>7档(300Hz)</item>
<item>8档(320Hz)</item>
</string-array>

<string-array name="arr_duty_level">
<item>默认</item>
<item>1档(30%)</item>
<item>2档(40%)</item>
<item>3档(50%)</item>
<item>4档(60%)</item>
<item>5档(70%)</item>
<item>6档(80%)</item>
<item>7档(90%)</item>
<item>8档(100%)</item>
</string-array>

<string-array name="arr_duration">
<item>60s</item>
<item>70s</item>
<item>80s</item>
<item>90s</item>
<item>100s</item>
<item>110s</item>
<item>120s</item>
<item>130s</item>
<item>140s</item>
<item>150s</item>
<item>160s</item>
<item>170s</item>
<item>180s</item>
<item>190s</item>
<item>200s</item>
<item>210s</item>
<item>220s</item>
<item>230s</item>
<item>240s</item>
<item>250s</item>
<item>260s</item>
<item>270s</item>
<item>280s</item>
<item>290s</item>
<item>300s</item>
</string-array>

<string-array name="arr_work_state">
<item>初始化</item>
<item>启动</item>
<item>结束</item>
<item>低电,禁止启动</item>
<item>充电中,禁止启动</item>
</string-array>

<string-array name="arr_set_state">
<item>设置成功</item>
<item>设置失败</item>
<item>设置禁用</item>
</string-array>

<string-array name="arr_charger">
<item>未插入充电器</item>
<item>插入充电器</item>
</string-array>

<string-array name="arr_battery">
<item>未知</item>
<item>电池未充满</item>
<item>电池充满</item>
</string-array>

<string-array name="arr_power">
<item>未知</item>
<item>低电关机</item>
<item>电量正常</item>
<item>低电提醒</item>
</string-array>

<string-array name="arr_strength">
<item>力度正常</item>
<item>力度过大</item>
</string-array>

<string-array name="arr_work_node">
<item>0节点</item>
<item>1节点</item>
<item>2节点</item>
<item>3节点</item>
<item>4节点</item>
</string-array>

<string-array name="arr_auth_state">
<item>用户授权</item>
<item>待授权</item>
<item>已授权</item>
</string-array>
</resources>

+ 123
- 0
app/src/main/res/values-zh-rCN/strings.xml View File

@@ -0,0 +1,123 @@
<resources>
<string name="app_name">电动牙刷Demo</string>

<string name="not_support_ble">您的设备支持BLE!</string>
<string name="not_connect_device">未连接设备,点击扫描</string>

<string name="connected_device">已连接设备:%1$s</string>

<string name="query_work_state">查询工作状态</string>
<string name="query_battery_state">查询电池状态</string>
<string name="query_time">查询时间</string>
<string name="query_device_sn">查询设备ID</string>
<string name="query_history">查询历史数据</string>
<string name="cancel_history">取消历史数据</string>
<string name="delete_history">删除历史数据</string>
<string name="set_work_param">设置工作参数</string>
<string name="get_version">读版本</string>
<string name="set_time">设置时间</string>
<string name="set_sn">设置ID</string>
<string name="set_sn_hint">请输入ID(0~9, a~f, A~F)</string>

<string name="work_mode">模式</string>
<string name="work_feq">频率</string>
<string name="work_duty">占空比</string>
<string name="work_duration">持续时间:%1$s</string>
<string name="clear_log">清空Log</string>
<string name="update">升级</string>

<string name="unknown_command">未知命令</string>

<string name="on_off">开/关</string>
<string name="version">当前版本:%1$s</string>

<!-- 工作状态 -->
<string name="work_state">工作状态:</string>
<string name="work_state_mode">; 模式:</string>
<string name="work_state_feq">; 频率:</string>
<string name="preset_id">预置模式ID</string>
<string name="work_state_duty">; 占空比:</string>
<string name="work_state_duration">; 持续时间:</string>
<string name="work_state_efforts">; 力度:</string>
<string name="work_state_node">; 工作节点:</string>

<!--电源状态-->
<string name="power_status">电源状态:</string>
<string name="battery_status">; 电池状态:</string>
<string name="charger_status">; 电量状态:</string>
<string name="current_voltage">; 当前电压:</string>

<string name="device_id">设备ID:</string>
<string name="device_time">设备当前时间:</string>
<string name="history_count">历史记录总条数:</string>
<string name="set_param_status">设置工作参数状态: </string>
<string name="set_time_status">设置时间状态: </string>
<string name="set_id_status">设置ID状态: </string>
<string name="cancel_history_status">取消历史数据发送状态:</string>
<string name="delete_history_status">删除历史数据:</string>

<!--历史记录-->
<string name="history">历史记录:[</string>
<string name="history_id">序号:</string>
<string name="history_mode">; 模式:</string>

<!--工作数据-->
<string name="work_data">工作数据:[</string>
<string name="work_data_mode">模式:</string>
<string name="work_data_preset_id">; 编号: </string>
<string name="work_data_feq">; 频率:</string>
<string name="work_data_duty">; 占空比:</string>
<string name="work_data_duration">; 持续时间:</string>
<string name="work_data_start_time">; 起始时间:</string>
<string name="work_data_work_time">; 工作时长:</string>
<string name="work_data_intensity_count">; 力度过大次数:</string>
<string name="work_data_intensity_time">; 力度过大时长:</string>
<string name="work_data_left_time">; 左边刷牙时长: </string>
<string name="work_data_right_time">; 右边刷牙时长: </string>

<string name="custom_tips">自定义模式下,频率和占空比的档位不能设置为默认!</string>
<string name="device_id_null">设备ID不能为空</string>
<string name="device_id_format">设备ID不符合(0~9,a~f,A~F)格式,长度不能超过8</string>

<string name="select_file">请选择文件-----设备版本:%1$s</string>
<string name="update_error">升级失败</string>
<string name="update_ing">正在升级</string>
<string name="update_success">升级成功</string>
<string name="no_file">没有文件</string>
<string name="ok">确定</string>
<string name="cancel">取消</string>
<string name="reboot_now">是否重启?</string>
<string name="yes">是</string>
<string name="no">否</string>
<string name="scanner_action_scan">搜索</string>
<string name="scanner_title">选择设备:</string>
<string name="scanner_action_cancel">退出</string>
<string name="scanner_empty">没有发现设备</string>
<string name="not_available">n/a</string>

<string name="disconnected">已与设备断开连接</string>
<string name="select_right_file">请选择正确文件或高版本文件升级</string>

<string name="auth_state">授权状态: </string>

<string name="set_did_state">设置DID状态: </string>
<string name="set_name_state">设置设备名状态: </string>

<string name="get_electricity">电量</string>
<string name="set_did">设置DID</string>
<string name="get_did">获取DID</string>
<string name="input_did_hint">DID格式为123_123</string>
<string name="set_did_hint">请输入我司提供的DID.</string>
<string name="did_null">DID不能为空</string>

<string name="set_name">设置设备名</string>
<string name="get_mode">读档位</string>
<string name="set_name_hint">请输入设备名</string>
<string name="name_too_long">名字太长</string>
<string name="manufacturer_id_error">厂商ID需大于1和小于1023</string>
<string name="model_id_error">型号ID需大于0和小于63</string>

<string name="hint">提示</string>
<string name="permissions">请求使用定位权限搜索蓝牙设备</string>
<string name="permissions_server">没有开启定位服务</string>
</resources>

+ 121
- 0
app/src/main/res/values/arrays.xml View File

@@ -0,0 +1,121 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>


<string-array name="arr_mode">
<item>Clean</item>
<item>White</item>
<item>Massage</item>
<item>Sensitive</item>
<item>Customize</item>
<item>DIY</item>
<item>Polish</item>
<item>Gum Care</item>
<item>Refresh</item>
<item>Mascare</item>
<item>Soft</item>
</string-array>

<string-array name="arr_freq_level">
<item>Default</item>
<item>Level1(180Hz)</item>
<item>Level2(200Hz)</item>
<item>Level3(220Hz)</item>
<item>Level4(240Hz)</item>
<item>Level5(260Hz)</item>
<item>Level6(280Hz)</item>
<item>Level7(300Hz)</item>
<item>Level8(320Hz)</item>
</string-array>

<string-array name="arr_duty_level">
<item>Default</item>
<item>Level1(30%)</item>
<item>Level2(40%)</item>
<item>Level3(50%)</item>
<item>Level4(60%)</item>
<item>Level5(70%)</item>
<item>Level6(80%)</item>
<item>Level7(90%)</item>
<item>Level8(100%)</item>
</string-array>

<string-array name="arr_duration">
<item>60s</item>
<item>70s</item>
<item>80s</item>
<item>90s</item>
<item>100s</item>
<item>110s</item>
<item>120s</item>
<item>130s</item>
<item>140s</item>
<item>150s</item>
<item>160s</item>
<item>170s</item>
<item>180s</item>
<item>190s</item>
<item>200s</item>
<item>210s</item>
<item>220s</item>
<item>230s</item>
<item>240s</item>
<item>250s</item>
<item>260s</item>
<item>270s</item>
<item>280s</item>
<item>290s</item>
<item>300s</item>
</string-array>

<string-array name="arr_work_state">
<item>Initialization</item>
<item>Start up</item>
<item>End</item>
<item>Low, ban starts</item>
<item>Charging,ban starts</item>
</string-array>

<string-array name="arr_set_state">
<item>Setting Success</item>
<item>Setting Failed</item>
<item>Setting Disabled</item>
</string-array>

<string-array name="arr_charger">
<item>Not into the charger</item>
<item>Into the charger</item>
</string-array>

<string-array name="arr_battery">
<item>Unknown</item>
<item>The battery is not full</item>
<item>Battery full</item>
</string-array>

<string-array name="arr_power">
<item>Unknown</item>
<item>Low power shutdown</item>
<item>Normal power</item>
<item>Low power remind</item>
</string-array>

<string-array name="arr_strength">
<item>The intensity of the normal</item>
<item>The intensity is too large</item>
</string-array>

<string-array name="arr_work_node">
<item>Node0</item>
<item>Node1</item>
<item>Node2</item>
<item>Node3</item>
<item>Node4</item>
</string-array>
<string-array name="arr_auth_state">
<item>User Auth</item>
<item>To be authorized</item>
<item>Authorized</item>
</string-array>
</resources>

+ 8
- 0
app/src/main/res/values/colors.xml View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>

<color name="headerBackgroundColor">#009ada</color>
</resources>

+ 5
- 0
app/src/main/res/values/dimens.xml View File

@@ -0,0 +1,5 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

+ 125
- 0
app/src/main/res/values/strings.xml View File

@@ -0,0 +1,125 @@
<resources>
<string name="app_name">ToothbrushDemo</string>

<string name="not_support_ble">Your device does not support BLE!</string>
<string name="not_connect_device">Not connected devices, click to scan</string>

<string name="connected_device">Connected Devices:%1$s</string>

<string name="query_work_state">Query Work State</string>
<string name="query_battery_state">Query Battery</string>
<string name="query_time">Query Time</string>
<string name="query_device_sn">Query ID</string>
<string name="query_history">Query History</string>
<string name="cancel_history">Cancel History</string>
<string name="delete_history">Delete History</string>
<string name="set_work_param">Set Work Param</string>
<string name="get_version">Get Version</string>
<string name="set_time">Set Time</string>
<string name="set_sn">Set ID</string>
<string name="set_sn_hint">Please enter ID(0~9, a~f, A~F)</string>

<string name="work_mode">Mode</string>
<string name="work_feq">Frequency</string>
<string name="preset_id">PresetId</string>
<string name="work_duty">Duty</string>
<string name="work_duration">Duration: %1$s</string>
<string name="clear_log">Clear</string>
<string name="update">Update</string>

<string name="unknown_command">Unknown</string>

<string name="on_off">On/Off</string>

<string name="version">Version: %1$s</string>

<!-- 工作状态 -->
<string name="work_state">Work State: </string>
<string name="work_state_mode">; Mode: </string>
<string name="work_state_feq">; Frequency: </string>
<string name="work_state_duty">; Duty: </string>
<string name="work_state_duration">; Duration: </string>
<string name="work_state_efforts">; Efforts: </string>
<string name="work_state_node">; Node: </string>

<!--电源状态-->
<string name="power_status">Power Status: </string>
<string name="battery_status">; Battery Status: </string>
<string name="charger_status">; Charger Status: </string>
<string name="current_voltage">; Current Voltage: </string>

<string name="device_id">Device id: </string>
<string name="device_time">Device Time: </string>
<string name="history_count">The total number of recorded history: </string>
<string name="set_param_status">Set param state: </string>
<string name="set_time_status">Set time state: </string>
<string name="set_id_status">Set id state: </string>
<string name="cancel_history_status">Cancel Historical data transmission status: </string>
<string name="delete_history_status">Delete the historical data: </string>

<!--历史记录-->
<string name="history">History: [</string>
<string name="history_id">; Id: </string>
<string name="history_mode">; Mode: </string>

<!--工作数据-->
<string name="work_data">Work Data: [</string>
<string name="work_data_mode">Mode: </string>
<string name="work_data_preset_id">; PresetId: </string>
<string name="work_data_feq">; Frequency: </string>
<string name="work_data_duty">; Duty: </string>
<string name="work_data_duration">; Duration: </string>
<string name="work_data_start_time">; Start Time: </string>
<string name="work_data_work_time">; Work Time: </string>
<string name="work_data_intensity_count">; The intensity is too large number of: </string>
<string name="work_data_intensity_time">; The intensity is too large time: </string>
<string name="work_data_left_time">; The left brushing time: </string>
<string name="work_data_right_time">; The right brushing time: </string>

<string name="custom_tips">Custom mode, frequency and duty cycle of the gear can not be set as the default!</string>
<string name="device_id_null">Device ID can not be empty</string>
<string name="device_id_format">Device ID does not conform (0 ~ 9, a ~ f, A ~ F) format, the length can not exceed 8</string>

<string name="select_file">Please select file-----Device Version:%1$s</string>
<string name="update_error">Update Error</string>
<string name="update_ing">Updating</string>
<string name="update_success">Update Success</string>
<string name="no_file">No File</string>
<string name="ok">Ok</string>
<string name="cancel">Cancel</string>
<string name="reboot_now">Reboot now?</string>
<string name="yes">Yes</string>
<string name="no">No</string>

<string name="scanner_action_scan">Scan</string>
<string name="scanner_title">Select Device:</string>
<string name="scanner_action_cancel">Cancel</string>
<string name="scanner_empty">No Device</string>
<string name="not_available">n/a</string>

<string name="disconnected">Disconnected</string>
<string name="select_right_file">Please select the correct file or high version to upgrade</string>
<string name="auth_state">Auth State: </string>

<string name="set_did_state">Set DID state: </string>
<string name="set_name_state">Set name state: </string>

<string name="get_electricity">Electricity</string>
<string name="set_did">Set DID</string>
<string name="get_did">Get DID</string>
<string name="input_did_hint">DID format is 123_123</string>
<string name="set_did_hint">Please enter the DID provided by our company.</string>
<string name="did_null">DID can not be empty</string>

<string name="set_name">Set Name</string>
<string name="get_mode">Get Gear</string>
<string name="set_name_hint">Please enter the device name.</string>
<string name="name_too_long">The name is too long</string>
<string name="manufacturer_id_error">Manufacturer ID needs to be greater than 1 and less than 1023</string>
<string name="model_id_error">Model ID needs to be greater than 0 and less than 63</string>

<string name="hint">Tips</string>
<string name="permissions">Request to search for Bluetooth devices with targeting permissions</string>
<string name="permissions_server">Location service is not turned on</string>
</resources>

+ 15
- 0
app/src/main/res/values/styles.xml View File

@@ -0,0 +1,15 @@
<resources>

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimaryDark</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>

<!-- Base application theme. -->
<style name="NoTitleTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowNoTitle">true</item>
</style>
</resources>

+ 17
- 0
app/src/test/java/aicare/net/cn/aibrushdemo/ExampleUnitTest.java View File

@@ -0,0 +1,17 @@
package aicare.net.cn.aibrushdemo;

import org.junit.Test;

import static org.junit.Assert.*;

/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}

+ 27
- 0
build.gradle View File

@@ -0,0 +1,27 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

+ 15
- 0
gradle.properties View File

@@ -0,0 +1,15 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true



BIN
gradle/wrapper/gradle-wrapper.jar View File


+ 6
- 0
gradle/wrapper/gradle-wrapper.properties View File

@@ -0,0 +1,6 @@
#Mon Jul 01 18:16:00 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip

+ 172
- 0
gradlew View File

@@ -0,0 +1,172 @@
#!/usr/bin/env sh

##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn () {
echo "$*"
}

die () {
echo
echo "$*"
echo
exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`

# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option

if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi

# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")

# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"

# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi

exec "$JAVACMD" "$@"

+ 84
- 0
gradlew.bat View File

@@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windows variants

if not "%OS%" == "Windows_NT" goto win9xME_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega

+ 1
- 0
settings.gradle View File

@@ -0,0 +1 @@
include ':app'

Loading…
Cancel
Save