@@ -0,0 +1,7 @@ | |||
*.iml | |||
.gradle | |||
/local.properties | |||
/.idea | |||
.DS_Store | |||
/build | |||
/captures |
@@ -0,0 +1,567 @@ | |||
# Body fat scale SDK Instructions - Android | |||
[](https://jitpack.io/#elinkthings/BodyFatScaleSDKRepositoryAndroid) | |||
[aar package download link](https://github.com/inet2018/BodyFatScaleSDKRepositoryAndroid/releases) | |||
[key registered address](http://sdk.aicare.net.cn) | |||
[中文文档](README_CN.md) | |||
This document is a guide for Android developers to integrate good figure-SDK-Android in Android 4.4 and above systems, mainly for some key usage examples | |||
## 1 Import SDK | |||
``` | |||
repositories { | |||
flatDir { | |||
dirs 'libs' | |||
} | |||
} | |||
Step 1. Add the JitPack repository to your build file | |||
Add it in your root build.gradle at the end of repositories: | |||
allprojects { | |||
repositories { | |||
... | |||
maven { url 'https://jitpack.io' } | |||
} | |||
} | |||
Step 2. Add the dependency | |||
dependencies { | |||
implementation 'com.github.elinkthings:BodyFatScaleSDKRepositoryAndroid:1.2.4' | |||
} | |||
You can also use aar package dependency,Please download it into the project's libs yourself | |||
``` | |||
## 2 permission settings | |||
``` | |||
<!-In most cases, you need to ensure that the device supports BLE .--> | |||
<uses-feature | |||
android: name = "android.hardware.bluetooth_le" | |||
android: required = "true" /> | |||
<uses-permission android: name = "android.permission.BLUETOOTH" /> | |||
<uses-permission android: name = "android.permission.BLUETOOTH_ADMIN" /> | |||
<!-Android 6.0 and above. Bluetooth scanning requires one of the following two permissions. You need to apply at run time .--> | |||
<uses-permission android: name = "android.permission.ACCESS_COARSE_LOCATION" /> | |||
<uses-permission android: name = "android.permission.ACCESS_FINE_LOCATION" /> | |||
<!-Optional. If your app need dfu function .--> | |||
<uses-permission android: name = "android.permission.INTERNET" /> | |||
``` | |||
> 6.0 and above systems need to locate permissions and need to obtain permissions manually | |||
## 3 start integration | |||
> Add below AndroidManifest.xml application tag | |||
``` | |||
<application> | |||
... | |||
<service android:name="aicare.net.cn.iweightlibrary.wby.WBYService"/> | |||
</application> | |||
``` | |||
> initialization [key registered address](http://sdk.aicare.net.cn) | |||
``` | |||
// Call in application | |||
AiFitSDK.getInstance ().init(this, key, secret); | |||
``` | |||
> You can directly make your own `Activity` class extend` BleProfileServiceReadyActivity` | |||
``` | |||
public class MyActivity extends BleProfileServiceReadyActivity | |||
@Override | |||
protected void onCreate (Bundle savedInstanceState) { | |||
super.onCreate (savedInstanceState); | |||
// Judge whether the mobile device supports Ble | |||
if (! ensureBLESupported ()) { | |||
T.showShort (this, R.string.not_support_ble); | |||
finish (); | |||
} | |||
// Judge whether there is positioning permission, this method is not encapsulated. The specific code can be obtained in the demo, or you can call the permission method in your own way. | |||
initPermissions (); | |||
// Judge whether Bluetooth is on, if you need to change the style, you can do it yourself | |||
if (! isBLEEnabled ()) { | |||
showBLEDialog (); | |||
} | |||
} | |||
``` | |||
## 4 scan the device, stop scanning the device, check the scan status | |||
The APIs related to scanning are as follows. For details, please refer to the BleProfileServiceReadyActivity class. For details, refer to the sample project. | |||
``` | |||
// Call the startScan method to start scanning | |||
startScan (); | |||
// The getAicareDevice (final BroadData broadData) interface will call back to get a body fat scale device that complies with the Aicare protocol | |||
@Override | |||
protected void getAicareDevice (BroadData broadData) { | |||
// Body fat scale equipment in compliance with Aicare protocol | |||
} | |||
// Call the stopScan method to stop scanning. This convenience is not recommended for customers to call | |||
stopScan (); | |||
// Call the isScanning method to see if it is scanning true: scanning; false: scanning stopped | |||
isScanning (); | |||
``` | |||
> Note: If it is a broadcast scale, you do not need to perform the connection operation. You can directly get the body fat data in the scan callback getAicareDevice (BroadData broadData) method. The broadcast scale calls stopScan () to get back no data. | |||
``` | |||
@Override | |||
protected void getAicareDevice (BroadData broadData) { | |||
// Broadcast scale can get data directly here | |||
if (broadData.getDeviceType () == AicareBleConfig.BM_09) { | |||
if (broadData.getSpecificData ()! = null) { | |||
BM09Data data = AicareBleConfig. | |||
getBm09Data (broadData.getAddress (), broadData.getSpecificData ()); | |||
} else if (broadData.getDeviceType () == AicareBleConfig.BM_15) { | |||
if (broadData.getSpecificData ()! = null) { | |||
BM15Data data = AicareBleConfig.getBm15Data (broadData.getAddress (), | |||
broadData.getSpecificData ()); | |||
} | |||
} else { | |||
if (broadData.getSpecificData ()! = null) { | |||
WeightData weightData = | |||
AicareBleConfig.getWeightData (broadData.getSpecificData ()); | |||
} | |||
} | |||
} | |||
``` | |||
## 5 connect the device, disconnect the device | |||
The APIs related to the connection are as follows, please refer to the BleProfileServiceReadyActivity class for details. | |||
``` | |||
// Call the startConnect method to connect the body fat scale device | |||
// can be obtained in the getAicareDevice (BroadData broadData) callback method. | |||
// If there is no filtering in getAicareDevice (BroadData broadData), the broadcast should be filtered when connecting, see the demo connection for details. | |||
startConnect (String address) | |||
// You can get the connection status in onStateChanged | |||
@Override | |||
public void onStateChanged (String deviceAddress, int state) { | |||
super.onStateChanged (deviceAddress, state); | |||
// state See the class description for specific status | |||
} | |||
// Call the disconnect method in WBYService.WBYBinder class to disconnect the body fat scale | |||
binder.disconnect () | |||
``` | |||
Use the `startConnect` method to connect to the body fat scale, use the` onStateChanged` method to monitor the status of the connection, and use the `onError` method to monitor for exceptions during the connection process, in order to facilitate additional processing and troubleshooting. Use the `isDeviceConnected` method to determine whether a connection has been established. | |||
## 6 Successful connection, accept the data returned by the scale | |||
The following methods or interfaces are automatically obtained directly after inheriting the BleProfileServiceReadyActivity class | |||
``` | |||
// OnServiceBinded method to get an instance of WBYService.WBYBinder | |||
@Override | |||
protected void onServiceBinded (WBYService.WBYBinder binder) { | |||
this.binder = binder; | |||
} | |||
// The change and stable weight data and temperature returned by the device (supported by AC03) | |||
@Override | |||
protected void onGetWeightData (WeightData weightData) { | |||
// If you want to get broadcast scale data here. Need to be in getAicareDevice (final BroadData broadData) method | |||
// Call onGetWeightData (WeightData weightData) to pass the data through | |||
} | |||
// Get the setting status in the onGetSettingStatus method. For details, see AicareBleConfig.SettingStatus | |||
@Override | |||
protected void onGetSettingStatus (int status) { | |||
} | |||
// Get the version number, measurement time, user number, and impedance value in the onGetResul method | |||
@Override | |||
protected void onGetResult (int index, String result) { | |||
} | |||
// Get the device to return historical data or body fat data. True is historical data. | |||
//Body fat data will only be generated after the current user is synchronized after STATE_INDICATION_SUCCESS | |||
@Override | |||
protected void onGetFatData (boolean isHistory, BodyFatData bodyFatData) { | |||
} | |||
// Get information about the number of decimal places returned by the device | |||
@Override | |||
protected void onGetDecimalInfo (DecimalInfo decimalInfo) { | |||
} | |||
// Algorithm sequence information returned by the device | |||
@Override | |||
protected void onGetAlgorithmInfo (AlgorithmInfo algorithmInfo) { | |||
} | |||
``` | |||
Note: Some of these interfaces or methods require APP to issue commands to body fat to return data. | |||
## 7 Call the algorithm to calculate the data in the SDK | |||
AicareBleConfig contains algorithms related to body fat data that can be called | |||
``` | |||
If the device returns impedance, there is no body fat data that can be calculated by calling the getBodyFatData method, and the algorithm can be obtained by calling the algorithm on the data in the BodyFatData object. | |||
as follows: | |||
AicareBleConfig.getBodyFatData (AlgorithmUtil.AlgorithmType.TYPE_AIC | |||
ARE, bodyFatData.getSex (), bodyFatData.getAge (), | |||
Double.valueOf (ParseData.getKgWeight (bodyFatData.getWeight (), | |||
bodyFatData.getDecimalInfo ())), bodyFatData .getHeight (), | |||
bodyFatData.getAdc ()); | |||
If you need to obtain 6 additional physical indicators such as fat-free weight and weight control, please call getMoreFatData to get a MoreFatData object. | |||
AicareBleConfig.getMoreFatData (int sex, int height, double weight, | |||
double bfr, double rom, double pp) | |||
``` | |||
## 8 Give instructions to the device | |||
Get an instance of WBYService.WBYBinder in BleProfileServiceReadyActivity.onServiceBinded (WBYService.WBYBinder binder), and call the method in binder | |||
``` | |||
@Override | |||
protected void onServiceBinded (WBYService.WBYBinder binder) { | |||
this.binder = binder; | |||
} | |||
// If the history is obtained | |||
binder.syncHistory (); | |||
// Part of the method of WBYBinder | |||
public class WBYBinder extends LocalBinder { | |||
/ ** | |||
* Get history | |||
* / | |||
@Deprecated | |||
public void syncHistory () { | |||
mManager.sendCmd (AicareBleConfig.SYNC_HISTORY, AicareBleConfig.UNIT_KG); | |||
} | |||
/ ** | |||
* Synchronize the current user | |||
* | |||
* @param user | |||
* / | |||
public void syncUser (User user) { | |||
if (user == null) { | |||
return; | |||
} | |||
mManager.syncUser (user); | |||
} | |||
/ ** | |||
* Synchronized user list | |||
* | |||
* @param userList | |||
* / | |||
@Deprecated | |||
public void syncUserList (List <User> userList) { | |||
mManager.syncUserList (userList); | |||
} | |||
/ ** | |||
* Sync current unit | |||
* | |||
* @param unit {@link AicareBleConfig # UNIT_KG} | |||
* {@link AicareBleConfig # UNIT_LB} | |||
* {@link AicareBleConfig # UNIT_ST} | |||
* {@link AicareBleConfig # UNIT_JIN} | |||
* / | |||
public void syncUnit (byte unit) { | |||
mManager.sendCmd (AicareBleConfig.SYNC_UNIT, unit); | |||
} | |||
/ ** | |||
* synchronised time | |||
* / | |||
@Deprecated | |||
public void syncDate () { | |||
mManager.syncDate (); | |||
} | |||
/ ** | |||
* Query Bluetooth version information | |||
* / | |||
@Deprecated | |||
public void queryBleVersion () { | |||
mManager.sendCmd (AicareBleConfig.GET_BLE_VERSION, AicareBleConfig.UNIT_KG); | |||
} | |||
/ ** | |||
* Update user information | |||
* | |||
* @param user | |||
* / | |||
@Deprecated | |||
public void updateUser (User user) { | |||
if (user == null) { | |||
return; | |||
} | |||
mManager.updateUser (user); | |||
} | |||
/ ** | |||
* Setting mode | |||
* / | |||
public void setMode (@ AicareBleConfig.MODE int cmd) { | |||
mManager.setMode (cmd); | |||
} | |||
/ ** | |||
* Check if authorized | |||
* / | |||
@Deprecated | |||
public void auth () { | |||
mManager.auth (); | |||
} | |||
/ ** | |||
* Set DID | |||
* | |||
* @param did | |||
* / | |||
@Deprecated | |||
public void setDID (int did) { | |||
mManager.sendDIDCmd (AicareBleConfig.SET_DID, did); | |||
} | |||
/ ** | |||
* Query DID | |||
* / | |||
@Deprecated | |||
public void queryDID () { | |||
mManager.sendDIDCmd (AicareBleConfig.QUERY_DID, 0); | |||
} | |||
/ ** | |||
* Get the number of decimal places | |||
* / | |||
public void getDecimalInfo () { | |||
mManager.getDecimalInfo (); | |||
} | |||
... | |||
} | |||
``` | |||
## 9 Class description | |||
//aicare.net.cn.iweightlibrary.entity: | |||
#### 1.AlgorithmInfo (Algorithm Sequence Information) | |||
``` | |||
Type Parameter //Description | |||
double weight // weight | |||
int algorithmId //algorithm ID | |||
int adc // impedance value | |||
DecimalInfo decimalInfo //number of decimal places | |||
``` | |||
#### 2.BM09Data (BM09 data) | |||
``` | |||
Type Parameter //Description | |||
int agreementType //agreement type | |||
int unitType //unit type | |||
DecimalInfo decimalInfo //Decimal places | |||
double weight //Weight | |||
int adc //impedance value | |||
double temp //temperature | |||
int algorithmId //algorithm ID | |||
int did //(currently useless) | |||
String bleVersion //Bluetooth version | |||
int bleType //Bluetooth type (0x09) | |||
String address //device address | |||
long timeMillis //measurement timestamp | |||
whether boolean //isStable is stable | |||
``` | |||
#### 3.BM15Data (BM15 data) | |||
``` | |||
Type Parameter name //Description | |||
String version //Bluetooth version | |||
int agreementType //agreementType | |||
int unitType //unitType | |||
double weight // weight | |||
int adc //impedance value | |||
double temp //temperature (if temp = 6553.5, the scale does not support temperature) | |||
int algorithmId //algorithm ID | |||
int did //(currently useless) | |||
int bleType// Bluetooth type (0x15) | |||
String address// device address | |||
``` | |||
#### 4.BodyFatData | |||
``` | |||
Type Parameter // Description | |||
String date //measurement date | |||
String time //time | |||
double weight //weight | |||
double bmi | |||
double bfr | |||
double sfr | |||
int uvi //visceral fat index | |||
double rom //muscle rate | |||
double bmr //basal metabolic rate | |||
double bm //bone mass | |||
double vwc //moisture content | |||
double bodyAge // | |||
double pp //protein rate | |||
int number | |||
int sex | |||
int age //(1; male; 2, female) | |||
int height | |||
int adc //impedance value | |||
``` | |||
#### 5.BroadData (broadcast data) | |||
``` | |||
Type Parameter Description | |||
String name //device name | |||
String address //device address | |||
boolean isBright //Whether the screen is bright | |||
int rssi //signal value | |||
byte [] specificData //broadcast data | |||
int deviceType //device type | |||
``` | |||
#### 6.DecimalInfo (decimal point information) | |||
``` | |||
Type Parameter Description | |||
int sourceDecimal // source data decimal places | |||
int kgDecimal //kg number of decimal places | |||
int lbDecimal //lb decimal places | |||
int stDecimal //st number of decimal places | |||
int kg //Graduation kg | |||
int lb //Graduation lb | |||
``` | |||
#### 7.User (User Information) | |||
``` | |||
Type Parameter name Description | |||
int id | |||
int sex | |||
int age //(1; male; 2, female) | |||
int height | |||
int weight | |||
int adc //impedance (deprecated) | |||
``` | |||
#### 8.WeightData (weight data) | |||
``` | |||
Type Parameter name Description | |||
int cmdType //command type (1, change; 2, stable; 3, in impedance measurement) | |||
double weight | |||
double temp //temperature (if the temperature is Double.MAX_VALUE, the scale does not support temperature) | |||
DecimalInfo decimalInfo | |||
int adc //impedance value | |||
int algorithmType // algorithm ID | |||
int unitType | |||
int deviceType //device type | |||
``` | |||
#### 9.cn.net.aicare.algorithmutil.BodyFatData(Calculated body fat data) | |||
``` | |||
Type Parameter name Description | |||
double bmi; Body mass index | |||
double bfr; body fat rate | |||
double sfr; Subcutaneous fat rate | |||
int uvi; Visceral fat index | |||
double rom; Rate of muscle | |||
int bmr; basal metabolic rate | |||
double bm; Bone Mass | |||
double vwc; Water content | |||
int bodyAge; physical bodyAge | |||
double pp; protein percentage | |||
``` | |||
#### 10.MoreFatData | |||
``` | |||
Type Parameter name Description | |||
double standardWeight; Standard weight | |||
double controlWeight; Weight control | |||
double fat; Fat mass | |||
double removeFatWeight; Fat-free weight | |||
double muscleMass; Muscle mass | |||
double protein; Protein amount | |||
MoreFatData.FatLevel fatLevel; Obesity grade | |||
public static enum FatLevel { | |||
UNDER, Underweight | |||
THIN, Thin | |||
NORMAL, standard | |||
OVER, Favor | |||
FAT; overweight | |||
} | |||
``` | |||
#### 11.BleProfileService Connection Status | |||
``` | |||
public static final int STATE_CONNECTING = 4; // connecting | |||
public static final int STATE_DISCONNECTED = 0; // disconnect | |||
public static final int STATE_CONNECTED = 1; // The connection was successful | |||
public static final int STATE_SERVICES_DISCOVERED = 2; // Discover services | |||
public static final int STATE_INDICATION_SUCCESS = 3; // Enable success | |||
public static final int STATE_TIME_OUT = 5; // connection timed out | |||
``` | |||
#### 12.AicareBleConfig.SettingStatus Status information returned by the device | |||
``` | |||
int NORMAL = 0; // Normal | |||
int LOW_POWER = 1; // Low power | |||
int LOW_VOLTAGE = 2; // Low voltage | |||
int ERROR = 3; // overload | |||
int TIME_OUT = 4; // timeout | |||
int UNSTABLE = 5; // Unstable | |||
int SET_UNIT_SUCCESS = 6; // Set unit success | |||
int SET_UNIT_FAILED = 7; // Set unit failed | |||
int SET_TIME_SUCCESS = 8; // Successfully set time | |||
int SET_TIME_FAILED = 9; // Failed to set time | |||
int SET_USER_SUCCESS = 10; // Set user successfully | |||
int SET_USER_FAILED = 11; // Failed to set user | |||
int UPDATE_USER_LIST_SUCCESS = 12; // Update user list successfully | |||
int UPDATE_USER_LIST_FAILED = 13; // Update user list failed | |||
int UPDATE_USER_SUCCESS = 14; // Update user successfully | |||
int UPDATE_USER_FAILED = 15; // Update user failed | |||
int NO_HISTORY = 16; // There is no historical data | |||
int HISTORY_START_SEND = 17; // historical data starts to be sent | |||
int HISTORY_SEND_OVER = 18; // historical data transmission is complete | |||
int NO_MATCH_USER = 19; // No matching users | |||
int ADC_MEASURED_ING = 20; // Impedance measurement | |||
int ADC_ERROR = 21; // Impedance measurement failed | |||
int REQUEST_DISCONNECT = 22; // The device requested to disconnect | |||
int SET_DID_SUCCESS = 23; // DID set successfully | |||
int SET_DID_FAILED = 24; // Set DID failed | |||
int DATA_SEND_END = 25; // Measured data transmission is complete | |||
int UNKNOWN = -1; // unknown | |||
``` | |||
#### 13.WBYService Bluetooth information returned by the device | |||
``` | |||
public final static int BLE_VERSION = 0; // Bluetooth version | |||
public final static int MCU_DATE = 1; // mcu date | |||
public final static int MCU_TIME = 2; // mcu time | |||
public final static int USER_ID = 3; // user number | |||
public final static int ADC = 4; // impedance value | |||
``` |
@@ -0,0 +1,567 @@ | |||
# 蓝牙体脂秤SDK使用说明 - Android | |||
[](https://jitpack.io/#elinkthings/BodyFatScaleSDKRepositoryAndroid) | |||
[aar包下载地址](https://github.com/inet2018/BodyFatScaleSDKRepositoryAndroid/releases) | |||
[key注册地址](http://sdk.aicare.net.cn) | |||
[English documentation](README.md) | |||
该文档为指导Android开发人员在Android 4.4及以上系统中集成好身材-SDK-Android,主要为一些关键的使用示例 | |||
## 一、导入SDK | |||
``` | |||
repositories { | |||
flatDir { | |||
dirs 'libs' | |||
} | |||
} | |||
步骤1.将JitPack存储库添加到您的构建文件中 | |||
将其添加到存储库末尾的root build.gradle中: | |||
allprojects { | |||
repositories { | |||
... | |||
maven { url 'https://jitpack.io' } | |||
} | |||
} | |||
步骤2.添加依赖项 | |||
dependencies { | |||
implementation 'com.github.elinkthings:BodyFatScaleSDKRepositoryAndroid:1.2.4' | |||
} | |||
也可以使用aar包依赖,请自行下载放到项目的libs中 | |||
``` | |||
## 二、权限设置 | |||
``` | |||
<!--In most cases, you need to ensure that the device supports BLE.--> | |||
<uses-feature | |||
android:name="android.hardware.bluetooth_le" | |||
android:required="true"/> | |||
<uses-permission android:name="android.permission.BLUETOOTH"/> | |||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/> | |||
<!--Android 6.0 and above. Bluetooth scanning requires one of the following two permissions. You need to apply at run time.--> | |||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> | |||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> | |||
<!--Optional. If your app need dfu function.--> | |||
<uses-permission android:name="android.permission.INTERNET"/> | |||
``` | |||
> 6.0及以上系统必须要定位权限,且需要手动获取权限 | |||
## 三、开始集成 | |||
> 在AndroidManifest.xml application标签下面增加 | |||
``` | |||
<application> | |||
... | |||
<service android:name="aicare.net.cn.iweightlibrary.wby.WBYService"/> | |||
</application> | |||
``` | |||
> 初始化 [key注册地址](http://sdk.aicare.net.cn) | |||
``` | |||
//在application中调用 | |||
AiFitSDK.getInstance().init(this, key, secret); | |||
``` | |||
> 你可以直接让你自己的`Activity`类继承`BleProfileServiceReadyActivity` | |||
``` | |||
public class MyActivity extends BleProfileServiceReadyActivity | |||
@Override | |||
protected void onCreate(Bundle savedInstanceState) { | |||
super.onCreate(savedInstanceState); | |||
//判断手机设备是否支持Ble | |||
if (!ensureBLESupported()) { | |||
T.showShort(this, R.string.not_support_ble); | |||
finish(); | |||
} | |||
//判断是否有定位权限,此方法没有进行封装具体代码可在demo中获得,也可按照自己方式去调用请求权限方法 | |||
initPermissions(); | |||
//判断蓝牙是否打开,若需要换样式,可自己去实现 | |||
if (!isBLEEnabled()) { | |||
showBLEDialog(); | |||
} | |||
} | |||
``` | |||
## 四、扫描设备,停止扫描设备,查看扫描状态 | |||
与扫描相关的API如下,详情参考BleProfileServiceReadyActivity类,具体使用参考sample工程 | |||
``` | |||
//调用startScan方法开启扫描 | |||
startScan(); | |||
//getAicareDevice(final BroadData broadData)接口会回调获取到符合Aicare协议的体脂秤设备 | |||
@Override | |||
protected void getAicareDevice(BroadData broadData) { | |||
//符合Aicare协议的体脂秤设备 | |||
} | |||
//调用stopScan方法停止扫描 该方便不建议客户自己调用 | |||
stopScan(); | |||
//调用isScanning方法查看是否在扫描 true:正在扫描; false:已停止扫描 | |||
isScanning(); | |||
``` | |||
> 注意: 如果为广播秤,不需要去执行连接操作,在扫描的回调getAicareDevice(BroadData broadData)方法中可以直接去获取到体脂数据,广播秤调用 stopScan()回获取不到数据 | |||
``` | |||
@Override | |||
protected void getAicareDevice(BroadData broadData) { | |||
//广播秤可以直接在此获取数据 | |||
if (broadData.getDeviceType() == AicareBleConfig.BM_09) { | |||
if (broadData.getSpecificData() != null) { | |||
BM09Data data = AicareBleConfig. | |||
getBm09Data(broadData.getAddress(),broadData.getSpecificData()); | |||
}else if (broadData.getDeviceType() == AicareBleConfig.BM_15) { | |||
if (broadData.getSpecificData() != null) { | |||
BM15Data data = AicareBleConfig.getBm15Data(broadData.getAddress(), | |||
broadData.getSpecificData()); | |||
} | |||
}else{ | |||
if (broadData.getSpecificData() != null) { | |||
WeightData weightData = | |||
AicareBleConfig.getWeightData(broadData.getSpecificData()); | |||
} | |||
} | |||
} | |||
``` | |||
## 五、连接设备,断开设备 | |||
与连接相关的API如下,详情参考BleProfileServiceReadyActivity类,具体使用参考sample工程。 | |||
``` | |||
//调用startConnect方法去连接体脂秤设备 需要传入体脂秤设备的mac地址 mac地址 | |||
//可以在getAicareDevice(BroadData broadData)回调方法中获得 。 | |||
//如果在getAicareDevice(BroadData broadData) 没有做过滤,连接时要去过滤掉广播称,详情见demo连接处 | |||
startConnect(String address) | |||
//在onStateChanged可以获取到连接状态 | |||
@Override | |||
public void onStateChanged(String deviceAddress, int state) { | |||
super.onStateChanged(deviceAddress, state); | |||
//state 具体状态看类说明 | |||
} | |||
//调用WBYService.WBYBinder类中disconnect方法去断开体脂秤 | |||
binder.disconnect() | |||
``` | |||
使用`startConnect`方法连接体脂秤,,使用`onStateChanged`方法监听连接的状态,使用`onError`方法监听连接过程中的异常,以便于进行额外的处理和问题排查。使用`isDeviceConnected`方法判断连接是否已经建立。 | |||
## 六 连接成功,接受秤返回的数据 | |||
以下方法或接口可直接在继承BleProfileServiceReadyActivity类后自动获得 | |||
``` | |||
//onServiceBinded方法中获得WBYService.WBYBinder的实例 | |||
@Override | |||
protected void onServiceBinded(WBYService.WBYBinder binder) { | |||
this.binder = binder; | |||
} | |||
//设备返回的变化和稳定的体重数据和温度(AC03才支持) | |||
@Override | |||
protected void onGetWeightData(WeightData weightData) { | |||
//如果想要在这里获取到广播秤数据。需要在getAicareDevice(final BroadData broadData)方法中 | |||
//调用onGetWeightData(WeightData weightData)去把数据透传过来 | |||
} | |||
//onGetSettingStatus方法中获得设置状态 详情查看AicareBleConfig.SettingStatus | |||
@Override | |||
protected void onGetSettingStatus(int status) { | |||
} | |||
//onGetResul方法中获得获得版本号,测量时间,用户编号,阻抗值 | |||
@Override | |||
protected void onGetResult(int index, String result) { | |||
} | |||
// 获得设备返回据历史数据或体脂数据 true为历史数据 | |||
@Override | |||
protected void onGetFatData(boolean isHistory, BodyFatData bodyFatData) { | |||
} | |||
//获取设备返回的小数点位数信息 | |||
@Override | |||
protected void onGetDecimalInfo(DecimalInfo decimalInfo) { | |||
} | |||
//设备返回的算法序列信息 | |||
@Override | |||
protected void onGetAlgorithmInfo(AlgorithmInfo algorithmInfo) { | |||
} | |||
``` | |||
> 注意:这些接口或方法部分需要APP给体脂下发命令才会有返回数据. | |||
## 七 调用SDK中的算法计算数据 | |||
在AicareBleConfig中包含有体脂数据相关的算法可供调用 | |||
``` | |||
如果设备返回阻抗,没有体脂数据可以调用getBodyFatData方法计算,通过 BodyFatData 对象中的数据调用算法得到cn.net.aicare.algorithmutil.BodyFatData | |||
如下: | |||
AicareBleConfig.getBodyFatData(AlgorithmUtil.AlgorithmType.TYPE_AIC | |||
ARE, bodyFatData.getSex(), bodyFatData.getAge(), | |||
Double.valueOf(ParseData.getKgWeight(bodyFatData.getWeight(), | |||
bodyFatData.getDecimalInfo())), bodyFatData .getHeight(), | |||
bodyFatData.getAdc()); | |||
如需要获取去脂体重,体重控制量等额外的 6 项身体指标,请调用getMoreFatData计算得到 MoreFatData 对象 | |||
AicareBleConfig.getMoreFatData(int sex, int height, double weight, | |||
double bfr, double rom, double pp) | |||
``` | |||
## 八 给设备下发指令 | |||
在BleProfileServiceReadyActivity.onServiceBinded(WBYService.WBYBinder binder)获得WBYService.WBYBinder的实例,调用binder里面方法 | |||
``` | |||
@Override | |||
protected void onServiceBinded(WBYService.WBYBinder binder) { | |||
this.binder = binder; | |||
} | |||
//如获取到历史记录 | |||
binder.syncHistory(); | |||
//WBYBinder的部分方法 | |||
public class WBYBinder extends LocalBinder { | |||
/** | |||
* 获取历史记录 | |||
*/ | |||
@Deprecated | |||
public void syncHistory() { | |||
mManager.sendCmd(AicareBleConfig.SYNC_HISTORY, AicareBleConfig.UNIT_KG); | |||
} | |||
/** | |||
* 同步当前用户 | |||
* | |||
* @param user | |||
*/ | |||
public void syncUser(User user) { | |||
if (user == null) { | |||
return; | |||
} | |||
mManager.syncUser(user); | |||
} | |||
/** | |||
* 同步用户列表 | |||
* | |||
* @param userList | |||
*/ | |||
@Deprecated | |||
public void syncUserList(List<User> userList) { | |||
mManager.syncUserList(userList); | |||
} | |||
/** | |||
* 同步当前单位 | |||
* | |||
* @param unit {@link AicareBleConfig#UNIT_KG} | |||
* {@link AicareBleConfig#UNIT_LB} | |||
* {@link AicareBleConfig#UNIT_ST} | |||
* {@link AicareBleConfig#UNIT_JIN} | |||
*/ | |||
public void syncUnit(byte unit) { | |||
mManager.sendCmd(AicareBleConfig.SYNC_UNIT, unit); | |||
} | |||
/** | |||
* 同步时间 | |||
*/ | |||
@Deprecated | |||
public void syncDate() { | |||
mManager.syncDate(); | |||
} | |||
/** | |||
* 查询蓝牙版本信息 | |||
*/ | |||
@Deprecated | |||
public void queryBleVersion() { | |||
mManager.sendCmd(AicareBleConfig.GET_BLE_VERSION, AicareBleConfig.UNIT_KG); | |||
} | |||
/** | |||
* 更新用户信息 | |||
* | |||
* @param user | |||
*/ | |||
@Deprecated | |||
public void updateUser(User user) { | |||
if (user == null) { | |||
return; | |||
} | |||
mManager.updateUser(user); | |||
} | |||
/** | |||
* 设置模式 | |||
*/ | |||
public void setMode(@AicareBleConfig.MODE int cmd) { | |||
mManager.setMode(cmd); | |||
} | |||
/** | |||
* 校验是否授权 | |||
*/ | |||
@Deprecated | |||
public void auth() { | |||
mManager.auth(); | |||
} | |||
/** | |||
* 设置DID | |||
* | |||
* @param did | |||
*/ | |||
@Deprecated | |||
public void setDID(int did) { | |||
mManager.sendDIDCmd(AicareBleConfig.SET_DID, did); | |||
} | |||
/** | |||
* 查询DID | |||
*/ | |||
@Deprecated | |||
public void queryDID() { | |||
mManager.sendDIDCmd(AicareBleConfig.QUERY_DID, 0); | |||
} | |||
/** | |||
* 获取小数位数 | |||
*/ | |||
public void getDecimalInfo() { | |||
mManager.getDecimalInfo(); | |||
} | |||
} | |||
``` | |||
## 九 类说明 | |||
//aicare.net.cn.iweightlibrary.entity | |||
#### 1.AlgorithmInfo(算法序列信息) | |||
``` | |||
类型 参数名 说明 | |||
double weight 体重 | |||
int algorithmId 算法ID | |||
int adc 阻抗值 | |||
DecimalInfo decimalInfo 小数点位数 | |||
``` | |||
#### 2.BM09Data(BM09数据) | |||
``` | |||
类型 参数名 说明 | |||
int agreementType 协议类型 | |||
int unitType 单位类型 | |||
DecimalInfo decimalInfp 小数点位数 | |||
double weight 体重 | |||
int adc 阻抗值 | |||
double temp 温度 | |||
int algorithmId 算法ID | |||
int did (目前无用) | |||
String bleVersion 蓝牙版本 | |||
int bleType 蓝牙类型(0x09) | |||
String address 设备地址 | |||
long timeMillis 测量时间戳 | |||
boolean isStable 是否稳定 | |||
``` | |||
#### 3.BM15Data(BM15数据) | |||
``` | |||
类型 参数名 说明 | |||
String version 蓝牙版本 | |||
int agreementType 协议类型 | |||
int unitType 单位类型 | |||
double weight 体重 | |||
int adc 阻抗值 | |||
double temp 温度(若temp=6553.5,则表示秤不支持温度) | |||
int algorithmId 算法ID | |||
int did (目前无用) | |||
int bleType 蓝牙类型(0x15) | |||
String address 设备地址 | |||
``` | |||
#### 4.BodyFatData(体脂数据) | |||
``` | |||
类型 参数名 说明 | |||
String date 测量日期 | |||
String time 测量时间 | |||
double weight 体重 | |||
double bmi 身体质量指数 | |||
double bfr 体脂率 | |||
double sfr 皮下脂肪率 | |||
int uvi 内脏脂肪指数 | |||
double rom 肌肉率 | |||
double bmr 基础代谢率 | |||
double bm 骨量 | |||
double vwc 水分率 | |||
double bodyAge 身体年龄 | |||
double pp 蛋白率 | |||
int number 编号 | |||
int sex 性别 | |||
int age 年龄(1、男;2、女) | |||
int height 身高 | |||
int adc 阻抗值 | |||
``` | |||
#### 5.BroadData(广播数据) | |||
``` | |||
类型 参数名 说明 | |||
String name 设备名 | |||
String address 设备地址 | |||
boolean isBright 是否亮屏 | |||
int rssi 信号值 | |||
byte[] specificData 广播数据 | |||
int deviceType 设备类型 | |||
``` | |||
#### 6.DecimalInfo(小数点位数信息) | |||
``` | |||
类型 参数名 说明 | |||
int sourceDecimal 源数据小数点位数 | |||
int kgDecimal kg小数点位数 | |||
int lbDecimal lb小数点位数 | |||
int stDecimal st小数点位数 | |||
int kgGraduation kg分度 | |||
int lbGraduation lb分度 | |||
``` | |||
#### 7.User(用户信息) | |||
``` | |||
类型 参数名 说明 | |||
int id 编号 | |||
int sex 性别 | |||
int age 年龄(1、男;2、女) | |||
int height 身高 | |||
int weight 体重 | |||
int adc 阻抗值(弃用) | |||
``` | |||
#### 8.WeightData(体重数据) | |||
``` | |||
类型 参数名 说明 | |||
int cmdType 命令类型(1、变化;2、稳定;3、阻抗测量中) | |||
double weight 体重 | |||
double temp 温度(若温度为Double.MAX_VALUE则表示秤不支持温度) | |||
DecimalInfo decimalInfo 小数点位数信息 | |||
int adc 阻抗值 | |||
int algorithmType 算法ID | |||
int unitType 单位类型 | |||
int deviceType 设备类型 | |||
``` | |||
#### 9.cn.net.aicare.algorithmutil.BodyFatData(计算得到的体脂数据) | |||
``` | |||
类型 参数名 说明 | |||
double bmi; 身体质量指数 | |||
double bfr; 体脂率 body fat rate | |||
double sfr; 皮下脂肪率 Subcutaneous fat rate | |||
int uvi; 内脏脂肪指数 | |||
double rom; 肌肉率 Rate of muscle | |||
int bmr; 基础代谢率 basal metabolic rate | |||
double bm; 骨骼质量 Bone Mass | |||
double vwc; 水含量 | |||
int bodyAge; 身体年龄 physical bodyAge | |||
double pp; 蛋白率 protein percentage | |||
``` | |||
#### 10.MoreFatData | |||
``` | |||
类型 参数名 说明 | |||
double standardWeight; 标准体重 | |||
double controlWeight; 体重控制量 | |||
double fat; 脂肪量 | |||
double removeFatWeight; 去脂体重 | |||
double muscleMass; 肌肉量 | |||
double protein; 蛋白量 | |||
MoreFatData.FatLevel fatLevel; 肥胖等级 | |||
public static enum FatLevel { | |||
UNDER, 体重不足 | |||
THIN, 偏瘦 | |||
NORMAL, 标准 | |||
OVER, 偏重 | |||
FAT; 超重 | |||
} | |||
``` | |||
#### 11.BleProfileService 连接状态 | |||
``` | |||
public static final int STATE_CONNECTING = 4; //连接中 | |||
public static final int STATE_DISCONNECTED = 0; //断开连接 | |||
public static final int STATE_CONNECTED = 1;//连接成功 | |||
public static final int STATE_SERVICES_DISCOVERED = 2;//发现服务 | |||
public static final int STATE_INDICATION_SUCCESS = 3;//使能成功 | |||
public static final int STATE_TIME_OUT = 5;//连接超时 | |||
``` | |||
#### 12.AicareBleConfig.SettingStatus 设备返回的状态信息 | |||
``` | |||
int NORMAL = 0;//正常 | |||
int LOW_POWER = 1;//低功耗 | |||
int LOW_VOLTAGE = 2;//低电压 | |||
int ERROR = 3;//超载 | |||
int TIME_OUT = 4;//超时 | |||
int UNSTABLE = 5;//称不稳定 | |||
int SET_UNIT_SUCCESS = 6;//设置单位成功 | |||
int SET_UNIT_FAILED = 7;//设置单位失败 | |||
int SET_TIME_SUCCESS = 8;//设置时间成功 | |||
int SET_TIME_FAILED = 9;//设置时间失败 | |||
int SET_USER_SUCCESS = 10;//设置用户成功 | |||
int SET_USER_FAILED = 11;//设置用户失败 | |||
int UPDATE_USER_LIST_SUCCESS = 12;//更新用户列表成功 | |||
int UPDATE_USER_LIST_FAILED = 13;//更新用户列表失败 | |||
int UPDATE_USER_SUCCESS = 14;//更新用户成功 | |||
int UPDATE_USER_FAILED = 15;//更新用户失败 | |||
int NO_HISTORY = 16;//没有历史数据 | |||
int HISTORY_START_SEND = 17;//历史数据开始发送 | |||
int HISTORY_SEND_OVER = 18;//历史数据发送完成 | |||
int NO_MATCH_USER = 19;//没有匹配的用户 | |||
int ADC_MEASURED_ING = 20;//阻抗测量中 | |||
int ADC_ERROR = 21;//阻抗测量失败 | |||
int REQUEST_DISCONNECT = 22;//设备请求断开 | |||
int SET_DID_SUCCESS = 23;//设置DID成功 | |||
int SET_DID_FAILED = 24;//设置DID失败 | |||
int DATA_SEND_END = 25;//测量数据发送完成 | |||
int UNKNOWN = -1;//未知 | |||
``` | |||
#### 13.WBYService 设备返回的蓝牙信息 | |||
``` | |||
public final static int BLE_VERSION = 0; //蓝牙版本 | |||
public final static int MCU_DATE = 1; //mcu日期 | |||
public final static int MCU_TIME = 2; //mcu 时间 | |||
public final static int USER_ID = 3; //用户编号 | |||
public final static int ADC = 4; //阻抗值 | |||
``` |
@@ -0,0 +1 @@ | |||
/build |
@@ -0,0 +1,43 @@ | |||
apply plugin: 'com.android.application' | |||
android { | |||
compileSdkVersion 28 | |||
defaultConfig { | |||
applicationId "aicare.net.cn.sdk.iweightdemo" | |||
minSdkVersion 18 | |||
targetSdkVersion 28 | |||
versionCode 5 | |||
versionName "1.2.4" | |||
} | |||
buildTypes { | |||
release { | |||
minifyEnabled false | |||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | |||
} | |||
} | |||
testOptions { | |||
unitTests.returnDefaultValues = true | |||
} | |||
// sourceSets { | |||
// main { | |||
// jniLibs.srcDirs = ['libs'] | |||
// } | |||
// } | |||
repositories { | |||
flatDir { | |||
dirs 'libs' | |||
} | |||
} | |||
} | |||
dependencies { | |||
implementation fileTree(include: ['*.jar'], dir: 'libs') | |||
implementation 'androidx.appcompat:appcompat:1.1.0' | |||
implementation 'com.google.android.material:material:1.1.0' | |||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' | |||
testImplementation 'junit:junit:4.12' | |||
implementation 'com.github.elinkthings:BodyFatScaleSDKRepositoryAndroid:1.2.4' | |||
} |
@@ -0,0 +1,17 @@ | |||
# Add project specific ProGuard rules here. | |||
# By default, the flags in this file are appended to flags specified | |||
# in F:\AndroidSdk\sdk/tools/proguard/proguard-android.txt | |||
# You can edit the include path and order by changing the proguardFiles | |||
# directive in build.gradle. | |||
# | |||
# For more details, see | |||
# http://developer.android.com/guide/developing/tools/proguard.html | |||
# Add any project specific keep options here: | |||
# 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 *; | |||
#} |
@@ -0,0 +1,31 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |||
package="aicare.net.cn.iweightdemo"> | |||
<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.INTERNET"/> | |||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> | |||
<application | |||
android:allowBackup="true" | |||
android:icon="@mipmap/ic_launcher" | |||
android:label="@string/app_name" | |||
android:supportsRtl="true" | |||
android:theme="@style/AppTheme"> | |||
<activity | |||
android:name=".MyActivity" | |||
android:theme="@style/AppTheme.NoActionBar"> | |||
<intent-filter> | |||
<action android:name="android.intent.action.MAIN"/> | |||
<category android:name="android.intent.category.LAUNCHER"/> | |||
</intent-filter> | |||
</activity> | |||
<service android:name="aicare.net.cn.iweightlibrary.wby.WBYService"/> | |||
</application> | |||
</manifest> |
@@ -0,0 +1,926 @@ | |||
package aicare.net.cn.iweightdemo; | |||
import android.Manifest; | |||
import android.app.AlertDialog; | |||
import android.content.DialogInterface; | |||
import android.content.Intent; | |||
import android.content.pm.PackageManager; | |||
import android.net.Uri; | |||
import android.os.Build; | |||
import android.os.Bundle; | |||
import android.os.Handler; | |||
import android.provider.Settings; | |||
import android.text.TextUtils; | |||
import android.view.Menu; | |||
import android.view.MenuItem; | |||
import android.view.View; | |||
import android.widget.ArrayAdapter; | |||
import android.widget.Button; | |||
import android.widget.ListView; | |||
import android.widget.RadioGroup; | |||
import android.widget.SeekBar; | |||
import android.widget.TextView; | |||
import com.google.android.material.floatingactionbutton.FloatingActionButton; | |||
import com.google.android.material.snackbar.Snackbar; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import aicare.net.cn.iweightdemo.scan.DeviceDialog; | |||
import aicare.net.cn.iweightdemo.utils.T; | |||
import aicare.net.cn.iweightlibrary.AiFitSDK; | |||
import aicare.net.cn.iweightlibrary.bleprofile.BleProfileService; | |||
import aicare.net.cn.iweightlibrary.bleprofile.BleProfileServiceReadyActivity; | |||
import aicare.net.cn.iweightlibrary.entity.AlgorithmInfo; | |||
import aicare.net.cn.iweightlibrary.entity.BM09Data; | |||
import aicare.net.cn.iweightlibrary.entity.BM15Data; | |||
import aicare.net.cn.iweightlibrary.entity.BodyFatData; | |||
import aicare.net.cn.iweightlibrary.entity.BroadData; | |||
import aicare.net.cn.iweightlibrary.entity.DecimalInfo; | |||
import aicare.net.cn.iweightlibrary.entity.User; | |||
import aicare.net.cn.iweightlibrary.entity.WeightData; | |||
import aicare.net.cn.iweightlibrary.utils.AicareBleConfig; | |||
import aicare.net.cn.iweightlibrary.utils.L; | |||
import aicare.net.cn.iweightlibrary.utils.ParseData; | |||
import aicare.net.cn.iweightlibrary.wby.WBYService; | |||
import androidx.annotation.NonNull; | |||
import androidx.appcompat.app.ActionBar; | |||
import androidx.appcompat.widget.Toolbar; | |||
import androidx.coordinatorlayout.widget.CoordinatorLayout; | |||
import androidx.core.app.ActivityCompat; | |||
import static aicare.net.cn.iweightdemo.R.string.weight; | |||
public class MyActivity extends BleProfileServiceReadyActivity implements DeviceDialog.OnDeviceScanListener, View.OnClickListener { | |||
private final static String TAG = "MyActivity"; | |||
private Menu menu; | |||
private Toolbar toolbar; | |||
private DeviceDialog devicesDialog; | |||
private WBYService.WBYBinder binder; | |||
private Button btn_sync_history, btn_sync_list, btn_sync_user, btn_sync_time, btn_version; | |||
private RadioGroup rg_change_unit; | |||
private TextView tv_age, tv_height, tv_weight, tv_temp, text_view_weight, tv_adc, tv_did; | |||
private SeekBar seek_bar_age, seek_bar_height, seek_bar_weight, seek_bar_adc; | |||
private RadioGroup rg_sex; | |||
private ListView lv_data; | |||
private ArrayAdapter listAdapter; | |||
private List<String> dataList = new ArrayList<>(); | |||
private List<User> userList = new ArrayList<>(); | |||
private User user = null; | |||
private byte unit = AicareBleConfig.UNIT_KG; | |||
private Button btn_query_did; | |||
private FloatingActionButton fab_log; | |||
private CoordinatorLayout coordinator_layout; | |||
private boolean showListView = false; | |||
private BroadData cacheBroadData; | |||
private boolean isNewBM15TestData; | |||
@Override | |||
protected void onCreate(Bundle savedInstanceState) { | |||
super.onCreate(savedInstanceState); | |||
AiFitSDK.getInstance().init(this,"eadecf060bd49872","00005acc8e56e34dfc2995062c"); | |||
setContentView(R.layout.activity_my); | |||
initData(); | |||
initViews(); | |||
initEvents(); | |||
if (!ensureBLESupported()) { | |||
T.showShort(this, R.string.not_support_ble); | |||
finish(); | |||
} | |||
initPermissions(); | |||
if (!isBLEEnabled()) { | |||
showBLEDialog(); | |||
} | |||
devicesDialog = new DeviceDialog(this, this); | |||
} | |||
@Override | |||
protected void onResume() { | |||
super.onResume(); | |||
if (this.binder == null) { | |||
bindService(null); | |||
} | |||
} | |||
private void initData() { | |||
user = new User(1, 2, 28, 170, 768, 551); | |||
userList.add(user); | |||
} | |||
private void initViews() { | |||
toolbar = findViewById(R.id.toolbar); | |||
setSupportActionBar(toolbar); | |||
ActionBar supportActionBar = getSupportActionBar(); | |||
if (supportActionBar != null) { | |||
supportActionBar.setTitle("V" + BuildConfig.VERSION_NAME); | |||
} | |||
coordinator_layout = findViewById(R.id.coordinator_layout); | |||
btn_sync_history = findViewById(R.id.btn_sync_history); | |||
btn_sync_list = findViewById(R.id.btn_sync_list); | |||
btn_sync_user = findViewById(R.id.btn_sync_user); | |||
btn_sync_time = findViewById(R.id.btn_sync_time); | |||
btn_version = findViewById(R.id.btn_version); | |||
rg_change_unit = findViewById(R.id.rg_change_unit); | |||
rg_change_unit.check(R.id.rb_kg); | |||
tv_age = findViewById(R.id.tv_age); | |||
setAgeText(); | |||
tv_height = findViewById(R.id.tv_height); | |||
setHeightText(); | |||
tv_weight = findViewById(R.id.tv_weight); | |||
tv_temp = findViewById(R.id.tv_temp); | |||
tv_did = findViewById(R.id.tv_did); | |||
text_view_weight = findViewById(R.id.text_view_weight); | |||
setWeightText(); | |||
tv_adc = findViewById(R.id.tv_adc); | |||
setAdcText(); | |||
seek_bar_age = findViewById(R.id.seek_bar_age); | |||
seek_bar_age.setMax(82); | |||
seek_bar_age.setProgress(user.getAge() - 18); | |||
seek_bar_height = findViewById(R.id.seek_bar_height); | |||
seek_bar_height.setMax(205); | |||
seek_bar_height.setProgress(user.getHeight() - 50); | |||
seek_bar_weight = findViewById(R.id.seek_bar_weight); | |||
seek_bar_weight.setMax(1800); | |||
seek_bar_weight.setProgress(user.getWeight()); | |||
seek_bar_adc = findViewById(R.id.seek_bar_adc); | |||
seek_bar_adc.setMax(1000); | |||
seek_bar_adc.setProgress(user.getAdc()); | |||
rg_sex = findViewById(R.id.rg_sex); | |||
if (user.getSex() == 1) { | |||
rg_sex.check(R.id.rb_male); | |||
} else { | |||
rg_sex.check(R.id.rb_female); | |||
} | |||
lv_data = findViewById(R.id.lv_data); | |||
listAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList); | |||
lv_data.setAdapter(listAdapter); | |||
btn_query_did = findViewById(R.id.btn_query_did); | |||
fab_log = findViewById(R.id.fab_log); | |||
showListView(); | |||
} | |||
private void showListView() { | |||
lv_data.setVisibility(showListView ? View.VISIBLE : View.GONE); | |||
showListView = !showListView; | |||
} | |||
private void setAdcText() { | |||
tv_adc.setText(getString(R.string.adc, String.valueOf(user.getAdc()))); | |||
} | |||
private void setWeightText() { | |||
text_view_weight.setText(getString(weight, String.valueOf(user.getWeight() / 10d))); | |||
} | |||
private void setHeightText() { | |||
tv_height.setText(getString(R.string.height, user.getHeight())); | |||
} | |||
private void setAgeText() { | |||
tv_age.setText(getString(R.string.age, user.getAge())); | |||
} | |||
private void initEvents() { | |||
btn_sync_history.setOnClickListener(this); | |||
btn_sync_list.setOnClickListener(this); | |||
btn_sync_user.setOnClickListener(this); | |||
btn_sync_time.setOnClickListener(this); | |||
btn_version.setOnClickListener(this); | |||
btn_query_did.setOnClickListener(this); | |||
rg_change_unit.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { | |||
@Override | |||
public void onCheckedChanged(RadioGroup group, int checkedId) { | |||
if (isDeviceConnected()) { | |||
switch (checkedId) { | |||
case R.id.rb_kg: | |||
unit = AicareBleConfig.UNIT_KG; | |||
binder.syncUnit(AicareBleConfig.UNIT_KG); | |||
break; | |||
case R.id.rb_lb: | |||
unit = AicareBleConfig.UNIT_LB; | |||
binder.syncUnit(AicareBleConfig.UNIT_LB); | |||
break; | |||
case R.id.rb_st: | |||
unit = AicareBleConfig.UNIT_ST; | |||
binder.syncUnit(AicareBleConfig.UNIT_ST); | |||
break; | |||
case R.id.rb_jin: | |||
unit = AicareBleConfig.UNIT_JIN; | |||
binder.syncUnit(AicareBleConfig.UNIT_JIN); | |||
break; | |||
} | |||
} | |||
} | |||
}); | |||
rg_sex.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { | |||
@Override | |||
public void onCheckedChanged(RadioGroup group, int checkedId) { | |||
switch (checkedId) { | |||
case R.id.rb_male: | |||
user.setSex(1); | |||
break; | |||
case R.id.rb_female: | |||
user.setSex(2); | |||
break; | |||
} | |||
} | |||
}); | |||
seek_bar_age.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { | |||
@Override | |||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { | |||
user.setAge(progress + 18); | |||
setAgeText(); | |||
} | |||
@Override | |||
public void onStartTrackingTouch(SeekBar seekBar) { | |||
} | |||
@Override | |||
public void onStopTrackingTouch(SeekBar seekBar) { | |||
} | |||
}); | |||
seek_bar_height.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { | |||
@Override | |||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { | |||
user.setHeight(progress + 50); | |||
setHeightText(); | |||
} | |||
@Override | |||
public void onStartTrackingTouch(SeekBar seekBar) { | |||
} | |||
@Override | |||
public void onStopTrackingTouch(SeekBar seekBar) { | |||
} | |||
}); | |||
seek_bar_weight.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { | |||
@Override | |||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { | |||
user.setWeight(progress); | |||
setWeightText(); | |||
} | |||
@Override | |||
public void onStartTrackingTouch(SeekBar seekBar) { | |||
} | |||
@Override | |||
public void onStopTrackingTouch(SeekBar seekBar) { | |||
} | |||
}); | |||
seek_bar_adc.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { | |||
@Override | |||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { | |||
user.setAdc(progress); | |||
setAdcText(); | |||
} | |||
@Override | |||
public void onStartTrackingTouch(SeekBar seekBar) { | |||
} | |||
@Override | |||
public void onStopTrackingTouch(SeekBar seekBar) { | |||
} | |||
}); | |||
fab_log.setOnClickListener(this); | |||
} | |||
private void setDefault() { | |||
tv_weight.setText(R.string.default_weight); | |||
tv_temp.setText(R.string.default_temp); | |||
tv_did.setText(R.string.default_DID); | |||
} | |||
@Override | |||
public void onClick(View v) { | |||
if (v.getId() == R.id.fab_log) { | |||
showListView(); | |||
return; | |||
} | |||
if (isDeviceConnected()) { | |||
switch (v.getId()) { | |||
case R.id.btn_sync_history: | |||
binder.syncHistory(); | |||
break; | |||
case R.id.btn_sync_list: | |||
binder.syncUserList(userList); | |||
break; | |||
case R.id.btn_sync_user: | |||
binder.syncUser(user); | |||
break; | |||
case R.id.btn_sync_time: | |||
binder.syncDate(); | |||
break; | |||
case R.id.btn_query_did: | |||
binder.queryDID(); | |||
break; | |||
case R.id.btn_version: | |||
binder.queryBleVersion(); | |||
break; | |||
} | |||
} | |||
} | |||
@Override | |||
public boolean onCreateOptionsMenu(Menu menu) { | |||
this.menu = menu; | |||
getMenuInflater().inflate(R.menu.main, menu); | |||
return true; | |||
} | |||
@Override | |||
public boolean onOptionsItemSelected(MenuItem item) { | |||
switch (item.getItemId()) { | |||
case R.id.action_scan: | |||
if (!isBLEEnabled()) { | |||
showBLEDialog(); | |||
} else { | |||
if (isDeviceConnected()) { | |||
binder.disconnect(); | |||
} else { | |||
if (cacheBroadData == null) { | |||
devicesDialog.show(); | |||
devicesDialog.startScan(); | |||
} else { | |||
cacheBroadData = null; | |||
setStateTitle("", BleProfileService.STATE_DISCONNECTED); | |||
stopLeScan(); | |||
} | |||
} | |||
} | |||
break; | |||
} | |||
return true; | |||
} | |||
@Override | |||
protected void onServiceBinded(WBYService.WBYBinder binder) { | |||
this.binder = binder; | |||
L.e("2017-11-20", TAG + ", onServiceBinded: binder = " + binder); | |||
} | |||
@Override | |||
protected void onServiceUnbinded() { | |||
this.binder = null; | |||
L.e("2017-11-20", TAG + ", onServiceUnbinded"); | |||
} | |||
@Override | |||
protected void getAicareDevice(final BroadData broadData) { | |||
if (broadData != null) { | |||
L.e(TAG, broadData.toString()); | |||
if (devicesDialog.isShowing()) { | |||
devicesDialog.setDevice(broadData); | |||
} | |||
if (cacheBroadData != null && TextUtils | |||
.equals(cacheBroadData.getAddress(), broadData.getAddress())) { | |||
if (broadData.getDeviceType() == AicareBleConfig.BM_09) { | |||
if (broadData.getSpecificData() != null) { | |||
BM09Data data = AicareBleConfig | |||
.getBm09Data(broadData.getAddress(), broadData.getSpecificData()); | |||
if (isNewData(data) && data.getWeight() != 0) { | |||
showInfo(data.toString(), false); | |||
tv_did.setText("DID:" + data.getDid()); | |||
} | |||
} | |||
} else if (broadData.getDeviceType() == AicareBleConfig.BM_15) { | |||
if (broadData.getSpecificData() != null) { | |||
rg_change_unit.setOnCheckedChangeListener(null); | |||
BM15Data data = AicareBleConfig | |||
.getBm15Data(broadData.getAddress(), broadData.getSpecificData()); | |||
WeightData weightData = new WeightData(); | |||
weightData.setAdc(data.getAdc()); | |||
weightData.setCmdType(data.getAgreementType()); | |||
weightData.setDeviceType(broadData.getDeviceType()); | |||
switch (data.getUnitType()) { | |||
case 1: | |||
unit = AicareBleConfig.UNIT_KG; | |||
rg_change_unit.check(R.id.rb_kg); | |||
weightData.setDecimalInfo(new DecimalInfo(1, 1, 1, 1, 1, 2)); | |||
break; | |||
case 2: | |||
unit = AicareBleConfig.UNIT_LB; | |||
rg_change_unit.check(R.id.rb_lb); | |||
weightData.setDecimalInfo(new DecimalInfo(1, 1, 1, 1, 1, 2)); | |||
break; | |||
case 3: | |||
unit = AicareBleConfig.UNIT_ST; | |||
rg_change_unit.check(R.id.rb_st); | |||
weightData.setDecimalInfo(new DecimalInfo(1, 1, 1, 1, 1, 2)); | |||
break; | |||
case 4: | |||
unit = AicareBleConfig.UNIT_KG; | |||
rg_change_unit.check(R.id.rb_kg); | |||
weightData.setDecimalInfo(new DecimalInfo(1, 1, 1, 1, 1, 1)); | |||
break; | |||
case 5: | |||
unit = AicareBleConfig.UNIT_LB; | |||
rg_change_unit.check(R.id.rb_lb); | |||
weightData.setDecimalInfo(new DecimalInfo(1, 1, 1, 1, 1, 1)); | |||
break; | |||
case 6: | |||
unit = AicareBleConfig.UNIT_ST; | |||
rg_change_unit.check(R.id.rb_st); | |||
weightData.setDecimalInfo(new DecimalInfo(1, 1, 1, 1, 1, 1)); | |||
break; | |||
} | |||
weightData.setWeight(data.getWeight()); | |||
weightData.setTemp(data.getTemp()); | |||
onGetWeightData(weightData); | |||
if (isNewData(data) && data.getWeight() != 0) { | |||
tv_did.setText("DID:" + data.getDid()); | |||
} | |||
} | |||
} else { | |||
if (broadData.getSpecificData() != null) { | |||
WeightData weightData = AicareBleConfig | |||
.getWeightData(broadData.getSpecificData()); | |||
onGetWeightData(weightData); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
private BM09Data bm09Data; | |||
private boolean isNewData(BM09Data data) { | |||
if (bm09Data == null) { | |||
bm09Data = data; | |||
return true; | |||
} | |||
if (bm09Data.getWeight() != data.getWeight()) { | |||
bm09Data = data; | |||
return true; | |||
} | |||
return false; | |||
} | |||
private BM15Data mBM15Data; | |||
private boolean isNewData(BM15Data data) { | |||
if (mBM15Data == null) { | |||
mBM15Data = data; | |||
return true; | |||
} | |||
if (mBM15Data.getWeight() != data.getWeight()) { | |||
mBM15Data = data; | |||
return true; | |||
} | |||
return false; | |||
} | |||
@Override | |||
protected void onDestroy() { | |||
stopScan(); | |||
if (isDeviceConnected()) { | |||
this.binder.disconnect(); | |||
} | |||
super.onDestroy(); | |||
} | |||
private Handler handler = new Handler(); | |||
private void startLeScan() { | |||
startScan(); | |||
} | |||
private void stopLeScan() { | |||
stopScan(); | |||
} | |||
@Override | |||
public void scan() { | |||
startScan(); | |||
devicesDialog.setScanning(true); | |||
} | |||
@Override | |||
public void stop() { | |||
stopScan(); | |||
devicesDialog.setScanning(false); | |||
} | |||
@Override | |||
public void connect(BroadData device) { | |||
if (device.getDeviceType() == AicareBleConfig.TYPE_WEI_BROAD || device | |||
.getDeviceType() == AicareBleConfig.TYPE_WEI_TEMP_BROAD || device | |||
.getDeviceType() == AicareBleConfig.BM_09 || device | |||
.getDeviceType() == AicareBleConfig.BM_15) { | |||
cacheBroadData = device; | |||
showInfo(getString(R.string.state_bound, device.getAddress()), true); | |||
setStateTitle(device.getAddress(), -1); | |||
startLeScan(); | |||
} else { | |||
startConnect(device.getAddress()); | |||
} | |||
} | |||
@Override | |||
public void onStateChanged(String deviceAddress, int state) { | |||
super.onStateChanged(deviceAddress, state); | |||
switch (state) { | |||
case BleProfileService.STATE_CONNECTED: | |||
showInfo(getString(R.string.state_connected, deviceAddress), true); | |||
setStateTitle(deviceAddress, state); | |||
break; | |||
case BleProfileService.STATE_DISCONNECTED: | |||
showInfo(getString(R.string.state_disconnected), true); | |||
setStateTitle(deviceAddress, state); | |||
break; | |||
case BleProfileService.STATE_SERVICES_DISCOVERED: | |||
showInfo(getString(R.string.state_service_discovered), true); | |||
break; | |||
case BleProfileService.STATE_INDICATION_SUCCESS: | |||
showInfo(getString(R.string.state_indication_success), true); | |||
break; | |||
case BleProfileService.STATE_TIME_OUT: | |||
showInfo(getString(R.string.state_time_out), true); | |||
break; | |||
case BleProfileService.STATE_CONNECTING: | |||
showInfo(getString(R.string.state_connecting), true); | |||
break; | |||
} | |||
} | |||
private void showInfo(String str, boolean showSnackBar) { | |||
if (showSnackBar) | |||
showSnackBar(str); | |||
String time = ParseData.getCurrentTime() + "\n----" + str; | |||
dataList.add(time); | |||
listAdapter.notifyDataSetChanged(); | |||
lv_data.setSelection(dataList.size() - 1); | |||
} | |||
private void setStateTitle(final String deviceAddress, final int state) { | |||
switch (state) { | |||
case BleProfileService.STATE_CONNECTED: | |||
L.e(TAG, "STATE_CONNECTED"); | |||
toolbar.setSubtitle(deviceAddress); | |||
menu.getItem(0).setTitle(R.string.disconnect); | |||
break; | |||
case BleProfileService.STATE_DISCONNECTED: | |||
L.e(TAG, "STATE_DISCONNECTED"); | |||
toolbar.setSubtitle(""); | |||
menu.getItem(0).setTitle(R.string.start_scan); | |||
setDefault(); | |||
break; | |||
case -1: | |||
toolbar.setSubtitle(deviceAddress); | |||
menu.getItem(0).setTitle(R.string.unbound); | |||
break; | |||
} | |||
} | |||
@Override | |||
public void onError(final String errMsg, final int errCode) { | |||
L.e(TAG, "Message = " + errMsg + " errCode = " + errCode); | |||
showInfo(getString(R.string.state_error, errMsg, errCode), true); | |||
} | |||
@Override | |||
public void onGetWeightData(final WeightData weightData) { | |||
if (weightData == null) | |||
return; | |||
setWeighDataText(AicareBleConfig | |||
.getWeight(weightData.getWeight(), unit, weightData.getDecimalInfo())); | |||
if (weightData.getTemp() != Double.MAX_VALUE) { | |||
tv_temp.setText(getString(R.string.temp, String.valueOf(weightData.getTemp()))); | |||
} | |||
if (weightData.getDeviceType() == AicareBleConfig.BM_15) { | |||
if (weightData.getCmdType() != 3) { | |||
isNewBM15TestData = true; | |||
showInfo(weightData.toString(), false); | |||
} | |||
if (weightData.getCmdType() == 3 && weightData.getAdc() > 0 && isNewBM15TestData) { | |||
isNewBM15TestData = false; | |||
BodyFatData bm15BodyFatData = AicareBleConfig | |||
.getBM15BodyFatData(weightData, user.getSex(), user.getAge(), user | |||
.getHeight()); | |||
showInfo(bm15BodyFatData.toString(), true); | |||
} | |||
} | |||
} | |||
private void setWeighDataText(String weight) { | |||
tv_weight.setText(getString(R.string.weight, weight)); | |||
} | |||
@Override | |||
public void onGetSettingStatus(@AicareBleConfig.SettingStatus int status) { | |||
L.e(TAG, "SettingStatus = " + status); | |||
switch (status) { | |||
case AicareBleConfig.SettingStatus.NORMAL: | |||
showInfo(getString(R.string.settings_status, getString(R.string.normal)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.LOW_POWER: | |||
showInfo(getString(R.string.settings_status, getString(R.string.low_power)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.LOW_VOLTAGE: | |||
showInfo(getString(R.string.settings_status, getString(R.string.low_voltage)), | |||
true); | |||
break; | |||
case AicareBleConfig.SettingStatus.ERROR: | |||
showInfo(getString(R.string.settings_status, getString(R.string.error)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.TIME_OUT: | |||
showInfo(getString(R.string.settings_status, getString(R.string.time_out)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.UNSTABLE: | |||
showInfo(getString(R.string.settings_status, getString(R.string.unstable)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.SET_UNIT_SUCCESS: | |||
showInfo(getString(R.string.settings_status, | |||
getString(R.string.set_unit_success)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.SET_UNIT_FAILED: | |||
showInfo(getString(R.string.settings_status, getString(R.string.set_unit_failed)) | |||
, true); | |||
break; | |||
case AicareBleConfig.SettingStatus.SET_TIME_SUCCESS: | |||
showInfo(getString(R.string.settings_status, | |||
getString(R.string.set_time_success)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.SET_TIME_FAILED: | |||
showInfo(getString(R.string.settings_status, getString(R.string.set_time_failed)) | |||
, true); | |||
break; | |||
case AicareBleConfig.SettingStatus.SET_USER_SUCCESS: | |||
showInfo(getString(R.string.settings_status, | |||
getString(R.string.set_user_success)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.SET_USER_FAILED: | |||
showInfo(getString(R.string.settings_status, getString(R.string.set_user_failed)) | |||
, true); | |||
break; | |||
case AicareBleConfig.SettingStatus.UPDATE_USER_LIST_SUCCESS: | |||
showInfo(getString(R.string.settings_status, | |||
getString(R.string.update_user_list_success)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.UPDATE_USER_LIST_FAILED: | |||
showInfo(getString(R.string.settings_status, | |||
getString(R.string.update_user_list_failed)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.UPDATE_USER_SUCCESS: | |||
showInfo(getString(R.string.settings_status, | |||
getString(R.string.update_user_success)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.UPDATE_USER_FAILED: | |||
showInfo(getString(R.string.settings_status, | |||
getString(R.string.update_user_failed)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.NO_HISTORY: | |||
showInfo(getString(R.string.settings_status, getString(R.string.no_history)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.HISTORY_START_SEND: | |||
showInfo(getString(R.string.settings_status, | |||
getString(R.string.history_start_send)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.HISTORY_SEND_OVER: | |||
showInfo(getString(R.string.settings_status, | |||
getString(R.string.history_send_over)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.NO_MATCH_USER: | |||
showInfo(getString(R.string.settings_status, getString(R.string.no_match_user)), | |||
true); | |||
break; | |||
case AicareBleConfig.SettingStatus.ADC_MEASURED_ING: | |||
showInfo(getString(R.string.settings_status, | |||
getString(R.string.adc_measured_ind)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.ADC_ERROR: | |||
showInfo(getString(R.string.settings_status, getString(R.string.adc_error)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.UNKNOWN: | |||
showInfo(getString(R.string.settings_status, getString(R.string.unknown)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.REQUEST_DISCONNECT: | |||
showInfo(getString(R.string.settings_status, | |||
getString(R.string.request_disconnect)), true); | |||
break; | |||
case AicareBleConfig.SettingStatus.DATA_SEND_END: | |||
showInfo(getString(R.string.settings_status, getString(R.string.data_send_end)), | |||
true); | |||
break; | |||
} | |||
} | |||
@Override | |||
public void onGetResult(final int index, final String result) { | |||
L.e(TAG, "index = " + index + "; result = " + result); | |||
switch (index) { | |||
case WBYService.BLE_VERSION: | |||
showInfo(getString(R.string.ble_version, result), true); | |||
break; | |||
case WBYService.USER_ID: | |||
showInfo(getString(R.string.user_id, result), true); | |||
break; | |||
case WBYService.MCU_DATE: | |||
showInfo(getString(R.string.mcu_date, result), true); | |||
break; | |||
case WBYService.MCU_TIME: | |||
showInfo(getString(R.string.mcu_time, result), true); | |||
break; | |||
case WBYService.ADC: | |||
showInfo(getString(R.string.adc, result), true); | |||
break; | |||
} | |||
} | |||
@Override | |||
public void onGetFatData(boolean isHistory, final BodyFatData bodyFatData) { | |||
L.e(TAG, "isHistory = " + isHistory + "; BodyFatData = " + bodyFatData.toString()); | |||
if (isHistory) { | |||
showInfo(getString(R.string.history_data, bodyFatData.toString()), true); | |||
} else { | |||
showInfo(getString(R.string.body_fat_data, bodyFatData.toString()), true); | |||
seek_bar_weight.setProgress((int) (Double.valueOf(AicareBleConfig | |||
.getWeight(bodyFatData.getWeight(), AicareBleConfig.UNIT_KG, bodyFatData | |||
.getDecimalInfo())) * 10)); | |||
if (bodyFatData.getAdc() != 0) { | |||
seek_bar_adc.setProgress(bodyFatData.getAdc()); | |||
} | |||
if (isDeviceConnected() && bodyFatData.getAdc() != 0) { | |||
/*userList.clear(); | |||
userList.add(user);*/ | |||
handler.postDelayed(updateRunnable, 50); | |||
} | |||
} | |||
} | |||
private Runnable updateRunnable = new Runnable() { | |||
@Override | |||
public void run() { | |||
binder.updateUser(user); | |||
} | |||
}; | |||
@Override | |||
public void onGetDID(int did) { | |||
showInfo(getString(R.string.did, did), true); | |||
tv_did.setText("DID:" + did); | |||
} | |||
@Override | |||
protected void onGetDecimalInfo(DecimalInfo decimalInfo) { | |||
if (decimalInfo == null) | |||
return; | |||
L.e(TAG, decimalInfo.toString()); | |||
String decimalStr = (getString(R.string.source_decimal, decimalInfo | |||
.getSourceDecimal())) + (getString(R.string.kg_decimal, decimalInfo | |||
.getKgDecimal())) + (getString(R.string.lb_decimal, decimalInfo | |||
.getLbDecimal())) + (getString(R.string.st_decimal, decimalInfo | |||
.getStDecimal())) + (getString(R.string.kg_graduation, decimalInfo | |||
.getKgGraduation())) + (getString(R.string.lb_graduation, decimalInfo | |||
.getLbGraduation())); | |||
showInfo(decimalStr, true); | |||
} | |||
@Override | |||
protected void onGetAlgorithmInfo(AlgorithmInfo algorithmInfo) { | |||
if (algorithmInfo == null) | |||
return; | |||
String algorithmStr = (getString(R.string.adc, String | |||
.valueOf(algorithmInfo.getAdc())) + (getString(R.string.algorithm_id, algorithmInfo | |||
.getAlgorithmId()))); | |||
showInfo(algorithmStr, true); | |||
} | |||
private void showSnackBar(String info) { | |||
Snackbar snackbar = Snackbar.make(coordinator_layout, info, Snackbar.LENGTH_SHORT); | |||
snackbar.show(); | |||
} | |||
private void initPermissions() { | |||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |||
ActivityCompat | |||
.requestPermissions(this, | |||
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1); | |||
} | |||
} | |||
@Override | |||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, | |||
@NonNull int[] grantResults) { | |||
super.onRequestPermissionsResult(requestCode, permissions, grantResults); | |||
if (requestCode != 1) { | |||
return; | |||
} | |||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { | |||
} else { | |||
if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[0])) { | |||
new AlertDialog.Builder(this).setTitle(R.string.tips).setMessage(R.string.tips_hint) | |||
.setPositiveButton(R.string.query, new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
Intent intent = | |||
new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); | |||
Uri uri = Uri.fromParts("package", getApplicationContext() | |||
.getPackageName(), null); | |||
intent.setData(uri); | |||
startActivity(intent); | |||
} | |||
}) | |||
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
if (dialog != null) { | |||
dialog.cancel(); | |||
} | |||
} | |||
}).show(); | |||
} else { | |||
new AlertDialog.Builder(this).setTitle(R.string.tips).setMessage(R.string.tips_hint) | |||
.setPositiveButton(R.string.query, new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
Intent intent = | |||
new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); | |||
Uri uri = Uri.fromParts("package", getApplicationContext() | |||
.getPackageName(), null); | |||
intent.setData(uri); | |||
startActivity(intent); | |||
} | |||
}) | |||
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
if (dialog != null) { | |||
dialog.cancel(); | |||
} | |||
} | |||
}).show(); | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,145 @@ | |||
package aicare.net.cn.iweightdemo.scan; | |||
import android.app.Dialog; | |||
import android.content.Context; | |||
import android.os.Bundle; | |||
import android.view.View; | |||
import android.view.Window; | |||
import android.view.WindowManager; | |||
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.iweightdemo.R; | |||
import aicare.net.cn.iweightlibrary.entity.BroadData; | |||
/** | |||
* 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<BroadData> listValues; | |||
private ListView listView; | |||
private final BroadData.AddressComparator comparator = new BroadData.AddressComparator(); | |||
public void setScanning(boolean scanning) { | |||
this.scanning = scanning; | |||
} | |||
public interface OnDeviceScanListener { | |||
void scan(); | |||
void stop(); | |||
void connect(BroadData device); | |||
} | |||
public DeviceDialog(Context context, OnDeviceScanListener listener) { | |||
super(context, R.style.Dialog); | |||
this.context = context; | |||
this.listener = listener; | |||
} | |||
@Override | |||
protected void onCreate(Bundle savedInstanceState) { | |||
super.onCreate(savedInstanceState); | |||
setContentView(R.layout.dialog_device); | |||
Window window = this.getWindow(); | |||
WindowManager.LayoutParams lp = window.getAttributes(); | |||
lp.width = WindowManager.LayoutParams.MATCH_PARENT; | |||
window.setAttributes(lp); | |||
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(); | |||
listener.connect((BroadData) adapter.getItem(position)); | |||
} | |||
}); | |||
scanButton.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View v) { | |||
if (v.getId() == R.id.action_cancel) { | |||
if (scanning) { | |||
stopScanDevice(); | |||
dismiss(); | |||
} else { | |||
startScan(); | |||
} | |||
} | |||
} | |||
}); | |||
} | |||
private void initViews() { | |||
listView = (ListView) findViewById(android.R.id.list); | |||
adapter = new DeviceListAdapter(context, listValues); | |||
listView.setAdapter(adapter); | |||
scanButton = (Button) findViewById(R.id.action_cancel); | |||
} | |||
public void startScan() { | |||
clearDevices(); | |||
TextView textView = (TextView) findViewById(android.R.id.empty); | |||
textView.setVisibility(View.GONE); | |||
if (listValues.isEmpty()) { | |||
listView.setEmptyView(textView); | |||
} | |||
scanButton.setText(R.string.scanner_action_cancel); | |||
if (!scanning) { | |||
listener.scan(); | |||
} | |||
} | |||
private void stopScanDevice() { | |||
if (scanning) { | |||
scanButton.setText(R.string.scanner_action_scan); | |||
listener.stop(); | |||
} | |||
} | |||
public void setDevice(BroadData device) { | |||
comparator.address = device.getAddress(); | |||
final int index = listValues.indexOf(comparator); | |||
if (index >= 0) { | |||
BroadData previousDevice = listValues.get(index); | |||
previousDevice.setRssi(device.getRssi()); | |||
previousDevice.setName(device.getName()); | |||
previousDevice.setBright(device.isBright()); | |||
adapter.notifyDataSetChanged(); | |||
return; | |||
} | |||
listValues.add(device); | |||
adapter.notifyDataSetChanged(); | |||
} | |||
private void clearDevices() { | |||
listValues.clear(); | |||
adapter.notifyDataSetChanged(); | |||
} | |||
@Override | |||
public void dismiss() { | |||
super.dismiss(); | |||
stopScanDevice(); | |||
} | |||
} |
@@ -0,0 +1,83 @@ | |||
/******************************************************************************* | |||
* 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.iweightdemo.scan; | |||
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.iweightdemo.R; | |||
import aicare.net.cn.iweightlibrary.entity.BroadData; | |||
/** | |||
* 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<BroadData> listValues; | |||
private final Context context; | |||
public DeviceListAdapter(Context context, List<BroadData> 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.flag = (TextView) view.findViewById(R.id.flag); | |||
view.setTag(holder); | |||
} | |||
holder = (ViewHolder) view.getTag(); | |||
BroadData device = (BroadData) getItem(position); | |||
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) { | |||
int rssiPercent = (int) (100.0f * (127.0f + device.getRssi()) / (127.0f + 20.0f)); | |||
holder.rssi.setImageLevel(rssiPercent); | |||
holder.rssi.setVisibility(View.VISIBLE); | |||
} | |||
holder.flag.setVisibility(device.isBright() ? View.VISIBLE : View.GONE); | |||
return view; | |||
} | |||
private class ViewHolder { | |||
private TextView name; | |||
private TextView address; | |||
private ImageView rssi; | |||
private TextView flag; | |||
} | |||
} |
@@ -0,0 +1,114 @@ | |||
package aicare.net.cn.iweightdemo.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(); | |||
} | |||
} |
@@ -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> |
@@ -0,0 +1,31 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<vector xmlns:android="http://schemas.android.com/apk/res/android" | |||
android:width="1854dp" | |||
android:height="1024dp" | |||
android:viewportWidth="1854" | |||
android:viewportHeight="1024"> | |||
<path | |||
android:fillColor="#ffffff" | |||
android:pathData="M779.97 218.289c-76.493 10.511-144.229 60.728-178.095 131.966-16.934 | |||
36.204-18.685 43.793-18.685 97.514 0 51.384 2.335 62.48 16.349 91.092 8.758 | |||
18.101 15.765 34.452 15.765 36.203 0 2.335-28.613 4.087-64.231 | |||
4.087h-64.231l-1.168-174.007-1.751-173.424-113.863-3.503v454.289l18.685 | |||
4.087c27.443 5.255 945.365 3.503 959.378-2.335 | |||
11.094-4.087-8.175-8.176-70.071-12.847-16.935-1.751-16.349-2.335 14.598-19.853 | |||
42.042-24.525 75.325-57.808 94.595-96.931 16.935-32.7 32.7-112.697 | |||
26.275-129.63-3.504-8.176-18.685-9.343-129.63-9.343h-125.543v93.427h61.311c33.867 | |||
0 61.311 2.335 61.311 5.255 0 11.678-32.7 43.794-55.472 53.722-82.916 | |||
37.954-172.256-24.525-172.256-120.288 0-39.705 9.343-65.399 31.532-89.34 | |||
50.801-54.889 122.623-56.64 172.256-4.672l20.437 | |||
21.021h121.454l-3.504-15.182c-8.175-30.948-50.801-81.749-91.092-107.441-80.581-51.384-209.626-44.377-278.529 | |||
14.598-13.43 11.094-26.861 20.438-30.948 20.438-3.503 | |||
0-13.43-7.008-22.189-15.182-8.758-8.176-27.444-21.021-42.042-28.027-51.968-26.861-92.258-33.283-150.651-25.692zM862.303 | |||
324.562c28.028 12.847 43.209 28.612 59.56 60.728 24.525 48.466 18.101 | |||
108.61-16.349 150.651-42.626 51.384-115.032 56.64-165.833 | |||
12.263-29.196-25.692-42.626-57.223-42.626-102.185 0-58.393 28.028-103.938 | |||
75.909-123.208 21.605-8.758 67.734-7.591 89.34 1.751zM1026.384 627.032c16.934 | |||
14.014 35.618 28.028 42.042 32.115 8.758 5.255-6.423 7.007-74.742 8.758-91.675 | |||
1.751-97.514-0.584-51.968-24.525 11.678-5.84 27.443-17.517 35.035-25.692 | |||
8.175-8.176 15.182-15.182 16.349-15.182 1.167 0 15.765 11.094 33.283 24.525z" /> | |||
</vector> |
@@ -0,0 +1,54 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||
xmlns:tools="http://schemas.android.com/tools" | |||
android:id="@+id/coordinator_layout" | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent" | |||
android:fitsSystemWindows="true" | |||
tools:context="aicare.net.cn.iweightdemo.MyActivity"> | |||
<com.google.android.material.appbar.AppBarLayout | |||
android:id="@+id/appbar" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:theme="@style/AppTheme.AppBarOverlay"> | |||
<androidx.appcompat.widget.Toolbar | |||
android:id="@+id/toolbar" | |||
android:layout_width="match_parent" | |||
android:layout_height="?attr/actionBarSize" | |||
android:background="?attr/colorPrimary" | |||
app:popupTheme="@style/AppTheme.PopupOverlay" /> | |||
</com.google.android.material.appbar.AppBarLayout> | |||
<androidx.constraintlayout.widget.ConstraintLayout | |||
android:id="@+id/content" | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent" | |||
android:layout_margin="@dimen/activity_horizontal_margin" | |||
app:layout_behavior="@string/appbar_scrolling_view_behavior"> | |||
<include layout="@layout/content_my" /> | |||
</androidx.constraintlayout.widget.ConstraintLayout> | |||
<ListView | |||
android:id="@+id/lv_data" | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent" | |||
android:background="#EEFFFFFF" | |||
android:visibility="gone" | |||
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> | |||
<com.google.android.material.floatingactionbutton.FloatingActionButton | |||
android:id="@+id/fab_log" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:layout_margin="@dimen/fab_margin" | |||
android:src="@drawable/log" | |||
app:layout_anchor="@id/content" | |||
app:layout_anchorGravity="bottom|right" /> | |||
</androidx.coordinatorlayout.widget.CoordinatorLayout> |
@@ -0,0 +1,231 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<merge android:id="@+id/content_my" | |||
xmlns:android="http://schemas.android.com/apk/res/android" | |||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||
xmlns:tools="http://schemas.android.com/tools" | |||
android:focusable="true" | |||
android:focusableInTouchMode="true" | |||
tools:context="aicare.net.cn.iweightdemo.MyActivity" | |||
tools:showIn="@layout/activity_my"> | |||
<RadioGroup | |||
android:id="@+id/rg_sex" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:gravity="center" | |||
android:orientation="horizontal"> | |||
<RadioButton | |||
android:id="@+id/rb_male" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:layout_marginRight="40dp" | |||
android:checked="true" | |||
android:text="@string/male"/> | |||
<RadioButton | |||
android:id="@+id/rb_female" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/female"/> | |||
</RadioGroup> | |||
<TextView | |||
android:id="@+id/tv_age" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:padding="5dp" | |||
android:text="@string/age" | |||
app:layout_constraintTop_toBottomOf="@id/rg_sex"/> | |||
<SeekBar | |||
android:id="@+id/seek_bar_age" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
app:layout_constraintTop_toBottomOf="@id/tv_age" | |||
app:layout_constraintRight_toRightOf="parent" /> | |||
<TextView | |||
android:id="@+id/tv_height" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:padding="5dp" | |||
android:text="@string/height" | |||
app:layout_constraintTop_toBottomOf="@id/seek_bar_age"/> | |||
<SeekBar | |||
android:id="@+id/seek_bar_height" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
app:layout_constraintTop_toBottomOf="@id/tv_height" | |||
/> | |||
<TextView | |||
android:id="@+id/text_view_weight" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:padding="5dp" | |||
android:text="@string/weight" | |||
app:layout_constraintTop_toBottomOf="@id/seek_bar_height"/> | |||
<SeekBar | |||
android:id="@+id/seek_bar_weight" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
app:layout_constraintTop_toBottomOf="@id/text_view_weight"/> | |||
<TextView | |||
android:id="@+id/tv_adc" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:padding="5dp" | |||
android:text="@string/adc" | |||
app:layout_constraintTop_toBottomOf="@id/seek_bar_weight"/> | |||
<SeekBar | |||
android:id="@+id/seek_bar_adc" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
app:layout_constraintTop_toBottomOf="@id/tv_adc"/> | |||
<Button | |||
android:id="@+id/btn_sync_list" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/sync_list" | |||
android:layout_marginTop="10dp" | |||
app:layout_constraintLeft_toLeftOf="parent" | |||
app:layout_constraintRight_toRightOf="parent" | |||
app:layout_constraintTop_toBottomOf="@id/seek_bar_adc"/> | |||
<Button | |||
android:id="@+id/btn_sync_history" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/sync_history" | |||
app:layout_constraintRight_toLeftOf="@id/btn_sync_list" | |||
app:layout_constraintTop_toTopOf="@id/btn_sync_list"/> | |||
<Button | |||
android:id="@+id/btn_sync_user" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/sync_user" | |||
app:layout_constraintLeft_toRightOf="@id/btn_sync_list" | |||
app:layout_constraintTop_toTopOf="@id/btn_sync_list"/> | |||
<Button | |||
android:id="@+id/btn_sync_time" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/sync_time" | |||
app:layout_constraintLeft_toLeftOf="parent" | |||
app:layout_constraintRight_toRightOf="parent" | |||
app:layout_constraintTop_toBottomOf="@id/btn_sync_history" | |||
/> | |||
<Button | |||
android:id="@+id/btn_query_did" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/query_did" | |||
app:layout_constraintEnd_toStartOf="@id/btn_sync_time" | |||
app:layout_constraintTop_toTopOf="@id/btn_sync_time"/> | |||
<Button | |||
android:id="@+id/btn_version" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/get_version" | |||
app:layout_constraintLeft_toRightOf="@id/btn_sync_time" | |||
app:layout_constraintTop_toTopOf="@id/btn_sync_time"/> | |||
<RadioGroup | |||
android:id="@+id/rg_change_unit" | |||
android:layout_width="match_parent" | |||
android:layout_height="40dp" | |||
android:gravity="center_vertical" | |||
android:orientation="horizontal" | |||
app:layout_constraintTop_toBottomOf="@id/btn_sync_time"> | |||
<RadioButton | |||
android:id="@+id/rb_kg" | |||
android:layout_width="0dp" | |||
android:layout_height="wrap_content" | |||
android:layout_weight="1" | |||
android:text="@string/unit_kg"/> | |||
<RadioButton | |||
android:id="@+id/rb_lb" | |||
android:layout_width="0dp" | |||
android:layout_height="wrap_content" | |||
android:layout_weight="1" | |||
android:text="@string/unit_lb"/> | |||
<RadioButton | |||
android:id="@+id/rb_st" | |||
android:layout_width="0dp" | |||
android:layout_height="wrap_content" | |||
android:layout_weight="1" | |||
android:text="@string/unit_st"/> | |||
<RadioButton | |||
android:id="@+id/rb_jin" | |||
android:layout_width="0dp" | |||
android:layout_height="wrap_content" | |||
android:layout_weight="1" | |||
android:text="@string/unit_jin"/> | |||
</RadioGroup> | |||
<androidx.constraintlayout.widget.Guideline | |||
android:id="@+id/guideline" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:orientation="vertical" | |||
app:layout_constraintGuide_percent="0.5"/> | |||
<TextView | |||
android:id="@+id/tv_weight" | |||
android:layout_width="0dp" | |||
android:layout_height="wrap_content" | |||
android:gravity="center" | |||
android:padding="10dp" | |||
android:text="@string/default_weight" | |||
android:textSize="18sp" | |||
app:layout_constraintLeft_toLeftOf="parent" | |||
app:layout_constraintRight_toRightOf="@id/guideline" | |||
app:layout_constraintTop_toBottomOf="@id/rg_change_unit"/> | |||
<TextView | |||
android:id="@+id/tv_temp" | |||
android:layout_width="0dp" | |||
android:layout_height="wrap_content" | |||
android:gravity="center" | |||
android:padding="10dp" | |||
android:text="@string/default_temp" | |||
android:textSize="18sp" | |||
app:layout_constraintBottom_toBottomOf="@id/tv_weight" | |||
app:layout_constraintLeft_toRightOf="@id/guideline" | |||
app:layout_constraintRight_toRightOf="parent" | |||
app:layout_constraintTop_toTopOf="@id/tv_weight"/> | |||
<TextView | |||
android:id="@+id/tv_did" | |||
android:layout_width="0dp" | |||
android:layout_height="wrap_content" | |||
android:gravity="center" | |||
android:padding="10dp" | |||
android:text="@string/default_DID" | |||
android:textSize="18sp" | |||
app:layout_constraintLeft_toLeftOf="parent" | |||
app:layout_constraintRight_toRightOf="@id/guideline" | |||
app:layout_constraintTop_toBottomOf="@id/tv_weight"/> | |||
</merge> |
@@ -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" /> |
@@ -0,0 +1,51 @@ | |||
<?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/flag" | |||
android:layout_toLeftOf="@id/rssi" | |||
android:layout_centerVertical="true" | |||
android:layout_marginRight="10dp" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:text="@string/light" /> | |||
<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> |
@@ -0,0 +1,45 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<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"> | |||
<TextView | |||
android:id="@android:id/title" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:padding="10dp" | |||
android:textColor="@android:color/black" | |||
android:text="@string/scanner_title" | |||
android:textSize="18sp" /> | |||
<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:gravity="center" | |||
android:paddingLeft="12dp" | |||
android:paddingRight="12dp" | |||
android:text="@string/scanner_empty" | |||
android:textSize="18sp" /> | |||
<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> |
@@ -0,0 +1,9 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<menu xmlns:android="http://schemas.android.com/apk/res/android" | |||
xmlns:app="http://schemas.android.com/apk/res-auto"> | |||
<item | |||
android:id="@+id/action_scan" | |||
android:title="@string/start_scan" | |||
android:orderInCategory="100" | |||
app:showAsAction="ifRoom"/> | |||
</menu> |
@@ -0,0 +1,9 @@ | |||
<resources> | |||
<style name="AppTheme.NoActionBar"> | |||
<item name="windowActionBar">false</item> | |||
<item name="windowNoTitle">true</item> | |||
<item name="android:windowDrawsSystemBarBackgrounds">true</item> | |||
<item name="android:statusBarColor">@android:color/transparent</item> | |||
</style> | |||
</resources> |
@@ -0,0 +1,6 @@ | |||
<resources> | |||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml | |||
(such as screen margins) for screens with more than 820dp of available width. This | |||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> | |||
<dimen name="activity_horizontal_margin">64dp</dimen> | |||
</resources> |
@@ -0,0 +1,111 @@ | |||
<resources> | |||
<string name="app_name">体脂秤Demo</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="start_scan">扫描</string> | |||
<string name="disconnect">断开连接</string> | |||
<string name="unbound">解绑</string> | |||
<string name="not_support_ble">设备不支持BLE!</string> | |||
<string name="sync_history">同步历史</string> | |||
<string name="sync_list">同步列表</string> | |||
<string name="sync_user">同步用户</string> | |||
<string name="sync_time">同步时间</string> | |||
<string name="update_user">更新用户</string> | |||
<string name="set_pregnancy">孕妇模式</string> | |||
<string name="remove_pregnancy">普通人模式</string> | |||
<string name="unit_kg">千克</string> | |||
<string name="unit_lb">英磅</string> | |||
<string name="unit_st">英石</string> | |||
<string name="unit_jin">斤</string> | |||
<string name="male">男</string> | |||
<string name="female">女</string> | |||
<string name="age">年龄: %1$d</string> | |||
<string name="height">身高: %1$d</string> | |||
<string name="weight">体重: %1$s</string> | |||
<string name="temp">温度: %1$s</string> | |||
<string name="default_value">--</string> | |||
<string name="default_weight">体重: —</string> | |||
<string name="default_temp">温度: —</string> | |||
<string name="default_DID">DID: —</string> | |||
<string name="state_connected">已连接设备: %1$s</string> | |||
<string name="state_bound">已绑定设备: %1$s</string> | |||
<string name="state_disconnected">已与设备断开连接</string> | |||
<string name="state_service_discovered">已发现服务</string> | |||
<string name="state_indication_success">使能成功</string> | |||
<string name="state_time_out">连接超时</string> | |||
<string name="state_connecting">连接中…</string> | |||
<string name="state_error">连接异常, 异常信息: %1$s; 错误码: %2$d</string> | |||
<string name="settings_status">状态: %1$s</string> | |||
<string name="normal">正常</string> | |||
<string name="low_power">低功耗</string> | |||
<string name="low_voltage">低电压</string> | |||
<string name="error">超载</string> | |||
<string name="time_out">超时</string> | |||
<string name="unstable">称不稳定</string> | |||
<string name="set_unit_success">设置单位成功</string> | |||
<string name="set_unit_failed">设置单位失败</string> | |||
<string name="set_time_success">设置时间成功</string> | |||
<string name="set_time_failed">设置时间失败</string> | |||
<string name="set_user_success">设置用户成功</string> | |||
<string name="set_user_failed">设置用户失败</string> | |||
<string name="update_user_list_success">更新用户列表成功</string> | |||
<string name="update_user_list_failed">更新用户列表失败</string> | |||
<string name="update_user_success">更新用户成功</string> | |||
<string name="update_user_failed">更新用户失败</string> | |||
<string name="no_history">没有历史数据</string> | |||
<string name="history_start_send">历史数据开始发送</string> | |||
<string name="history_send_over">历史数据发送完成</string> | |||
<string name="no_match_user">没有匹配的用户</string> | |||
<string name="adc_measured_ind">阻抗值测量中</string> | |||
<string name="adc_error">阻抗值测量失败</string> | |||
<string name="unknown">未知</string> | |||
<string name="request_disconnect">蓝牙请求断开</string> | |||
<string name="data_send_end">测量数据发送完成</string> | |||
<string name="body_fat_data">体脂数据: %1$s</string> | |||
<string name="history_data">历史数据: %1$s</string> | |||
<string name="ble_version">BLE版本: %1$s</string> | |||
<string name="user_id">用户编号: %1$s</string> | |||
<string name="mcu_date">测量日期: %1$s</string> | |||
<string name="mcu_time">测量时间: %1$s</string> | |||
<string name="adc">阻抗: %1$s</string> | |||
<string name="did">DID: %1$d</string> | |||
<string name="clear_log">清空Log</string> | |||
<string name="btn_get_decimal">获取小数位数</string> | |||
<string name="get_version">获取版本</string> | |||
<string name="query_did">查询DID</string> | |||
<string name="no_data">保存失败,没有数据!</string> | |||
<string name="save_failed">保存失败</string> | |||
<string name="save_ing">正在保存…</string> | |||
<string name="save_ing_progress">正在保存… %1$d</string> | |||
<string name="save_success">保存成功,路径:\n文件管理器-iWeightDemo-%1$s</string> | |||
<string name="query">确定</string> | |||
<string name="Setting_mode_succeeded">设置模式成功!</string> | |||
<string name="setting_mode_failed">设置模式失败!</string> | |||
<string name="algorithm_id">算法ID: %d</string> | |||
<string name="kg_decimal">Kg小数位: %d</string> | |||
<string name="kg_graduation"> kg分度: %d</string> | |||
<string name="lb_decimal">Lb 小数位: %d</string> | |||
<string name="lb_graduation">lb 分度: %d</string> | |||
<string name="light">亮</string> | |||
<string name="st_decimal">St 小数位: %d</string> | |||
<string name="source_decimal">源数据小数位数: %d</string> | |||
<string name="sync_record">同步记录</string> | |||
<string name="cancel">取消</string> | |||
<string name="tips">提示</string> | |||
<string name="tips_hint">请求使用定位权限搜索蓝牙设备</string> | |||
</resources> |
@@ -0,0 +1,6 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<resources> | |||
<color name="colorPrimary">#3F51B5</color> | |||
<color name="colorPrimaryDark">#303F9F</color> | |||
<color name="colorAccent">#FF4081</color> | |||
</resources> |
@@ -0,0 +1,6 @@ | |||
<resources> | |||
<!-- Default screen margins, per the Android Design guidelines. --> | |||
<dimen name="activity_horizontal_margin">16dp</dimen> | |||
<dimen name="activity_vertical_margin">16dp</dimen> | |||
<dimen name="fab_margin">16dp</dimen> | |||
</resources> |
@@ -0,0 +1,108 @@ | |||
<resources> | |||
<string name="app_name">iWeightDemo</string> | |||
<string name="scanner_action_scan">Scan</string> | |||
<string name="scanner_title">Select device:</string> | |||
<string name="scanner_action_cancel">Quit</string> | |||
<string name="scanner_empty">No device</string> | |||
<string name="not_available">n/a</string> | |||
<string name="start_scan">Scan</string> | |||
<string name="disconnect">Disconnect</string> | |||
<string name="not_support_ble">Phone does not support ble!</string> | |||
<string name="sync_user">Sync User</string> | |||
<string name="sync_record">Sync Record</string> | |||
<string name="unit_kg">kg</string> | |||
<string name="unit_lb">lb</string> | |||
<string name="unit_st">st</string> | |||
<string name="unit_jin">jin</string> | |||
<string name="male">Male</string> | |||
<string name="female">Female</string> | |||
<string name="age">Age: %d</string> | |||
<string name="height">Height: %d</string> | |||
<string name="weight">Weight: %s</string> | |||
<string name="temp">Temp: %s</string> | |||
<string name="default_value">--</string> | |||
<string name="default_weight">Weight: --.--</string> | |||
<string name="default_temp">Temp: --.--</string> | |||
<string name="state_connected">Connected device: %s</string> | |||
<string name="state_bound">Bind device: %s</string> | |||
<string name="state_disconnected">Disconnected from device.</string> | |||
<string name="state_service_discovered">Service found.</string> | |||
<string name="state_indication_success">Indication success.</string> | |||
<string name="state_time_out">Connection timed out.</string> | |||
<string name="state_connecting">Connecting…</string> | |||
<string name="unbound">Untied</string> | |||
<string name="state_error">Connection exception, exception information: %1$s; code: %2$d</string> | |||
<string name="settings_status">Status: %s</string> | |||
<string name="normal">Normal.</string> | |||
<string name="low_power">Screen off.</string> | |||
<string name="low_voltage">Low voltage.</string> | |||
<string name="error">Weighing overload.</string> | |||
<string name="time_out">Weighing timeout.</string> | |||
<string name="set_unit_success">Set unit success.</string> | |||
<string name="set_unit_failed">Set unit failed.</string> | |||
<string name="set_user_success">Set user success</string> | |||
<string name="set_user_failed">Set user failed.</string> | |||
<string name="adc_measured_ind">Impedance measurement…</string> | |||
<string name="adc_error">Impedance measurement failed.</string> | |||
<string name="source_decimal">Source data decimal digit: %d</string> | |||
<string name="kg_decimal">Kg decimal digit: %d</string> | |||
<string name="lb_decimal">Lb decimal digit: %d</string> | |||
<string name="lb_graduation">lb division: %d</string> | |||
<string name="algorithm_id">Algorithm ID: %d</string> | |||
<string name="body_fat_data">Body fat data: %s</string> | |||
<string name="ble_version">BLE Version: %s</string> | |||
<string name="user_id">User ID: %s</string> | |||
<string name="mcu_date">Weighting Date: %s</string> | |||
<string name="mcu_time">Weighting Time: %s</string> | |||
<string name="adc">Impedance value: %s</string> | |||
<string name="light">Light</string> | |||
<string name="btn_get_decimal">Get decimal places</string> | |||
<string name="clear_log">Clear Log</string> | |||
<string name="data_send_end">Measurement data sent</string> | |||
<string name="default_DID">DID: —</string> | |||
<string name="did">DID: %1$d</string> | |||
<string name="history_data">Historical data:%1$s</string> | |||
<string name="history_send_over">Completed sending of historical data</string> | |||
<string name="history_start_send">Historical data starts to be sent</string> | |||
<string name="no_data">Save failed with no data!</string> | |||
<string name="no_history">No historical data</string> | |||
<string name="no_match_user">No matching users</string> | |||
<string name="query">determine</string> | |||
<string name="query_did">Query DID</string> | |||
<string name="remove_pregnancy">Normal mode</string> | |||
<string name="request_disconnect">Bluetooth request to disconnect</string> | |||
<string name="save_failed">Save failed</string> | |||
<string name="save_ing">Saving…</string> | |||
<string name="save_ing_progress">Saving… %1$d</string> | |||
<string name="save_success">Saved successfully, path: File Manager-iWeightDemo-% 1 $ s</string> | |||
<string name="set_pregnancy">Maternity Mode</string> | |||
<string name="set_time_failed">Setting the time failed</string> | |||
<string name="set_time_success">Set time successfully</string> | |||
<string name="sync_history">Sync history</string> | |||
<string name="sync_list">Sync list</string> | |||
<string name="sync_time">synchronised time</string> | |||
<string name="unknown">unknown</string> | |||
<string name="unstable">Unstable</string> | |||
<string name="update_user">Update user</string> | |||
<string name="update_user_failed">Update user failed</string> | |||
<string name="update_user_list_failed">Update user list failed</string> | |||
<string name="update_user_list_success">User list updated successfully</string> | |||
<string name="update_user_success">Update user succeeded</string> | |||
<string name="get_version">Get version</string> | |||
<string name="Setting_mode_succeeded">Setting mode succeeded!</string> | |||
<string name="setting_mode_failed">Setting mode failed!</string> | |||
<string name="kg_graduation">kg division: %d</string> | |||
<string name="st_decimal">St decimal digit: %d</string> | |||
<string name="cancel">Cancel</string> | |||
<string name="tips">Tips</string> | |||
<string name="tips_hint">Request search for Bluetooth devices using location permissions</string> | |||
</resources> |
@@ -0,0 +1,23 @@ | |||
<resources> | |||
<!-- Base application theme. --> | |||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> | |||
<!-- Customize your theme here. --> | |||
<item name="colorPrimary">@color/colorPrimary</item> | |||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> | |||
<item name="colorAccent">@color/colorAccent</item> | |||
</style> | |||
<style name="AppTheme.NoActionBar"> | |||
<item name="windowActionBar">false</item> | |||
<item name="windowNoTitle">true</item> | |||
</style> | |||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/> | |||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/> | |||
<style name="Dialog" parent="Theme.AppCompat.Dialog"> | |||
<item name="android:windowNoTitle">true</item> | |||
</style> | |||
</resources> |
@@ -0,0 +1,26 @@ | |||
// Top-level build file where you can add configuration options common to all sub-projects/modules. | |||
buildscript { | |||
repositories { | |||
jcenter() | |||
google() | |||
} | |||
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 { | |||
jcenter() | |||
google() | |||
maven { url 'https://jitpack.io' } | |||
} | |||
} | |||
task clean(type: Delete) { | |||
delete rootProject.buildDir | |||
} |
@@ -0,0 +1,20 @@ | |||
# 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. | |||
# Default value: -Xmx10248m -XX:MaxPermSize=256m | |||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 | |||
# 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 | |||
android.enableJetifier=true | |||
android.useAndroidX=true |
@@ -0,0 +1,6 @@ | |||
#Thu Jul 12 16:16:09 CST 2018 | |||
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 |
@@ -0,0 +1,160 @@ | |||
#!/usr/bin/env bash | |||
############################################################################## | |||
## | |||
## Gradle start up script for UN*X | |||
## | |||
############################################################################## | |||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |||
DEFAULT_JVM_OPTS="" | |||
APP_NAME="Gradle" | |||
APP_BASE_NAME=`basename "$0"` | |||
# 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 | |||
case "`uname`" in | |||
CYGWIN* ) | |||
cygwin=true | |||
;; | |||
Darwin* ) | |||
darwin=true | |||
;; | |||
MINGW* ) | |||
msys=true | |||
;; | |||
esac | |||
# 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 | |||
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" ] ; 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 | |||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules | |||
function splitJvmOpts() { | |||
JVM_OPTS=("$@") | |||
} | |||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS | |||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" | |||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" |
@@ -0,0 +1,90 @@ | |||
@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 | |||
@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= | |||
set DIRNAME=%~dp0 | |||
if "%DIRNAME%" == "" set DIRNAME=. | |||
set APP_BASE_NAME=%~n0 | |||
set APP_HOME=%DIRNAME% | |||
@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 Windowz variants | |||
if not "%OS%" == "Windows_NT" goto win9xME_args | |||
if "%@eval[2+2]" == "4" goto 4NT_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=%* | |||
goto execute | |||
:4NT_args | |||
@rem Get arguments from the 4NT Shell from JP Software | |||
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 |
@@ -0,0 +1 @@ | |||
include ':app' |