Bläddra i källkod

Update documentation

master
陈福行 4 år sedan
förälder
incheckning
462b467046
4 ändrade filer med 4 tillägg och 1401 borttagningar
  1. Binär
      Body fat scale SDK instructions.pdf
  2. 4
    704
      README.md
  3. 0
    697
      README_CN.md
  4. Binär
      体脂秤SDK使用说明.pdf

Binär
Body fat scale SDK instructions.pdf Visa fil


+ 4
- 704
README.md Visa fil

@@ -1,707 +1,7 @@
[TOC]
EN
http://doc.elinkthings.com/web/#/4?page_id=71

# Body fat scale SDK Instructions - Android
CN
http://doc.elinkthings.com/web/#/4?page_id=24

[![](https://jitpack.io/v/elinkthings/BodyFatScaleSDKRepositoryAndroid.svg)](https://jitpack.io/#elinkthings/BodyFatScaleSDKRepositoryAndroid)

[aar package download link](https://github.com/elinkthings/BodyFatScaleSDKRepositoryAndroid/releases)

[key registered address](http://sdk.aicare.net.cn)



## Overview
- What is elink body fat scale SDK?

> The elink body fat scale SDK is a Bluetooth development tool provided to elink partners. The SDK implements and encapsulates the elink Bluetooth protocol and is responsible for the communication between the mobile phone App and the Bluetooth body fat scale device. Bluetooth body fat scale application.

- Scope of application

> Partners who need to personalize their Android Bluetooth body fat scale APP.



## Conditions of Use
1. Minimum version android4.4 (API 19)
2. The Bluetooth version used by the device requires 4.0 and above

## 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




```

## 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

## Start access
> First configure the key and secret for the SDK, [application address](http://sdk.aicare.net.cn)

```
  // Called in the application of the main project
  AiFitSDK.getInstance (). Init (this, key, secret);
```

> Add below AndroidManifest.xml application tag

```
<application>
...

<service android:name="aicare.net.cn.iweightlibrary.wby.WBYService"/>

</application>

```


> 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 ();
        }
    }
 
    
```

## 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
 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 ());
                        
                    }
           }
           
    }
```
      

## 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.

## 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.

## Call the algorithm to calculate the data in the SDK
- If the device returns impedance, and there is no body fat data, you can obtain the BodyFatData object by inheriting the onGetFatData method in BleProfileServiceReadyActivity, and call the AicareBleConfig.getBodyFatData method to calculate the cn.net.aicare.algorithmutil.BodyFatData object
Instructions:
```
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 get 6 additional body indicators such as body fat removal and weight control, please call AicareBleConfig.getMoreFatData to get MoreFatData object
Instructions:

```
AicareBleConfig.getMoreFatData (int sex, int height, double weight,
double bfr, double rom, double pp)

```

## 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 ();
        }

        ...
}

```

## Class description

- aicare.net.cn.iweightlibrary.entity.AlgorithmInfo (Algorithm Sequence Information)


| Type | Parameter |Description
| ---|---|---
| double |weight | weight
| int | algorithmId |algorithm ID
| int | adc | impedance value
| DecimalInfo| decimalInfo|number of decimal places


- 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


- BM15Data (BM15 data)

| Type | Parameter |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


- 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


- 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


- 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


- User (User Information)

| Type | Parameter |Description
| ---|---|---
| int| id|
| int |sex|
| int |age |(1; male; 2, female)
| int |height|
| int |weight|
| int |adc|impedance (deprecated)



- WeightData (weight data)

| Type | Parameter |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



- cn.net.aicare.algorithmutil.BodyFatData(Calculated body fat data)

| Type | Parameter |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




- MoreFatData

| Type | Parameter |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
}
```

- 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
```

- 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
```

- 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
```

## Version History

| Version number | Update time | Author | Update information
| ---- | --- | ----- | -----
| 1.0 | 2017/02/15 | Suzy | Preliminary version
| 1.0.1 | 2017/07/31 | Suzy | Fix some data conversion bugs
| 1.0.2 | 2017/09/11 | Suzy | The type in the instruction is set according to the type of device actually connected
| 1.0.3 | 2017/11/16 | Suzy | Code optimization
| 1.0.4 | 2018/07/12 | Suzy | compatible broadcast scale
| 1.0.5 | 2018/01/15 | Suzy | New protocol compatible
| 1.0.6 | 2018/02/25 | Suzy | Function optimization
| 1.0.7 | 2018/02/28 | Suzy | Encapsulated decimal point class
| 1.0.8 | 2018/03/14 | Suzy | Fix the bug of wrong body age
| 1.0.9 | 2018/4/9 | Suzy | Compatible with BM09 protocol
| 1.1.1 | 2018/5/10 | Suzy | Compatible with kg / lb indexing protocol
| 1.1.2 | 2018/5/11 | Suzy | Solve the bug that the st unit data is inconsistent with the scale display
| 1.1.3 | 2018/6/22 | Suzy | Solve the bug that the decimal point is sometimes not available
| 1.1.4 | 2018/7/7 | Suzy | Compatible with BM15 protocol
| 1.1.5 | 2018/7/20 | Suzy | Compatible algorithm ID protocol
| 1.1.7 | 2019/04/30 | Stan | Add BM15 body fat data calculation algorithm
| 1.1.8 | 2019/06/6 | Stan | Modify the original data to lb, st calculation error problem
| 1.1.9 | 2019/12/19 | Xing | Add history
| 1.2.0 | 2019/1/17 | Xing | Update and optimize Bluetooth library
| 1.2.1 | 2020/3/19 | Xing | Increase the calculation method of body fat data and the algorithm of lean body mass etc.
| 1.2.2 | 2020/3/23 | Xing | Modify SDK to gradle form dependency
| 1.2.3 | 2020/4/2 | Xing | Add key verification, modify the dependent environment to androidx
| 1.2.4 | 2020/4/10 | Xing | Fix known bugs


## FAQ

- How to judge whether the currently scanned BroadData (device) is a broadcast scale or a connected scale?
1. According to the value of deviceType attribute of BroadData:
deviceType == AicareBleConfig.TYPE_WEI_BROAD is a broadcast scale without temperature
deviceType == AicareBleConfig.TYPE_WEI_TEMP_BROAD is a broadcast scale with temperature
deviceType == AicareBleConfig.TYPE_WEI is a connected scale without temperature
deviceType == AicareBleConfig.TYPE_WEI_TEMP is a connected scale with temperature

- Which units does the Bluetooth protocol support?
1. Units only support up to 4 types (kg, lb, st, kg), please refer to the factory settings of the scale for specific units supported.

- Can't scan the Bluetooth device?
1. Check whether the permissions of the App are normal. The 6.0 and above systems must locate the permissions and need to manually obtain the permissions
2. Check whether the location service of the mobile phone is turned on, some mobile phones may need to turn on the GPS
3. Unplug the battery and restart the scale
4. Whether it is connected by other mobile phones (when the scale is not connected, the Bluetooth icon on the weighing pan will continue to flash)

- Which devices are supported?
1. Support BM series connection scale, BM15 broadcast scale

- How does the connected scale determine the end of measurement?
1. OnGetFatData () method callback means the measurement is completed

- How do broadcast scales determine the end of measurement?
1. All the data of the broadcast scale is returned from getAicareDevice and parsed to get the WeightData object. GetCmdType () == 3 in WeightData means the measurement is completed, please refer to the demo for details

- The data displayed by the scale is inconsistent with the data received by the app
1. The SDK will request decimals by default, and you can use getDecimalInfo () in WBYBinder to actively obtain decimals
2. When the app calculates the weight, it needs to pass in DecimalInfo (decimal object) for calculation

```
DecimalInfo {
    private int sourceDecimal; // The source data decimal places
    private int kgDecimal; // kg decimal places
    private int lbDecimal; // lb decimal places
    private int stDecimal; // st decimal places
    private int kgGraduation; // kg division
    private int lbGraduation; // lb division
}
```

- Why can I only measure my weight and no other body fat data?
1. You must take off your shoes and socks and stand barefoot on the electrode pads of the body fat scale to measure body fat data.

- When weighing, the scale always displays Error, and the app shows that the impedance measurement has failed. What is the reason?
1. Take off your shoes and socks and barefoot stand on the electrode pad of the body fat scale to measure, and then Error will no longer be displayed.

- How to provide feedback to technical support staff efficiently?
1. The SDK will print the log on the console, please save the log as txt and send it to the technical staff when feedback the problem
2. When feeding back the problem, describe the operation before and after the problem as clearly as possible. It is best to record a video to tell how to reproduce the problem.

- Are there any criteria and copy for body fat data?
1. Body fat determination standards may vary from manufacturer to manufacturer, and there is currently no industry-recognized reference standard. The following are the standards used by our company for reference only: [《Bluetooth Body Fat Scale Judgment Standard and Mini Program Copy 20200416》](https://shimo.im/sheets/8dGqCgyhX9P6Xpcw/GX3qk/)



## Contact Us
Shenzhen elink things Co., Ltd.

Phone: 0755-81773367

Official website: www.elinkthings.com

Email: app@elinkthings.com

+ 0
- 697
README_CN.md Visa fil

@@ -1,697 +0,0 @@
[TOC]

# 蓝牙体脂秤SDK使用说明 - Android

[![](https://jitpack.io/v/elinkthings/BodyFatScaleSDKRepositoryAndroid.svg)](https://jitpack.io/#elinkthings/BodyFatScaleSDKRepositoryAndroid)

[aar包下载地址](https://github.com/elinkthings/BodyFatScaleSDKRepositoryAndroid/releases)

[key申请地址](http://sdk.aicare.net.cn)



## 概述
- 什么是elink体脂秤SDK ?

> elink体脂秤SDK 是提供给elink合作伙伴的蓝牙开发工具,该SDK对elink蓝牙协议进行了实现和封装,负责手机App与蓝牙体脂秤设备之间的通信,旨在方便合作伙伴定制自己的蓝牙体脂秤应用。

- 适用范围

> 需要个性化定制自己的 Android 蓝牙体脂秤 APP 的合作伙伴。



## 使用条件
1,最低版本 android4.4(API 19)
2,设备所使用的蓝牙版本需要4.0及以上
3,依赖环境androidx

## 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及以上系统必须要定位权限,且需要手动获取权限

## 开始接入

> 首先给SDK配置key和secret,[申请地址](http://sdk.aicare.net.cn)

```
//在主项目的application中调用
AiFitSDK.getInstance().init(this, key, secret);
```

> 在AndroidManifest.xml application标签下面增加

```
<application>
...

<service android:name="aicare.net.cn.iweightlibrary.wby.WBYService"/>

</application>

```


> 你可以直接让你自己的`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中的算法库
- 如果设备返回阻抗,没有体脂数据可以通过继承BleProfileServiceReadyActivity中的onGetFatData方法获得 BodyFatData 对象,调用AicareBleConfig.getBodyFatData方法计算得到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 项身体指标,请调用调用AicareBleConfig.getMoreFatData计算得到 MoreFatData 对象
使用方法:

```
AicareBleConfig.getMoreFatData(int sex, int height, double weight,
double bfr, double rom, double pp)

```

## APP给设备下发指令
在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.AlgorithmInfo(算法序列信息)

| 类型| 参数名| 说明
| ---|---|---
| double | weight |体重
| int | algorithmId |算法ID
| int | adc |阻抗值
| DecimalInfo | decimalInfo |小数点位数



- 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 |是否稳定


- 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 |设备地址


- 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 |阻抗值



- BroadData(广播数据)

| 类型| 参数名| 说明
| ---|---|---
| String |name |设备名
| String |address |设备地址
| boolean |isBright |是否亮屏
| int |rssi |信号值
| byte[] |specificData |广播数据
| int |deviceType |设备类型


- DecimalInfo(小数点位数信息)

| 类型| 参数名| 说明
| ---|---|---
| int| sourceDecimal |源数据小数点位数
| int| kgDecimal |kg小数点位数
| int| lbDecimal |lb小数点位数
| int| stDecimal |st小数点位数
| int| kgGraduation |kg分度
| int| lbGraduation |lb分度


- User(用户信息)

| 类型| 参数名| 说明
| ---|---|---
| int|id |编号
| int|sex |性别
| int|age |年龄(1、男;2、女)
| int|height |身高
| int|weight |体重
| int|adc |阻抗值(弃用)


- WeightData(体重数据)

| 类型| 参数名| 说明
| ---|---|---
| int| cmdType| 命令类型(1、变化;2、稳定;3、阻抗测量中)
| double| weight| 体重
| double| temp |温度(若温度为Double.MAX_VALUE则表示秤不支持温度)
| DecimalInfo| decimalInfo| 小数点位数信息
| int| adc |阻抗值
| int| algorithmType| 算法ID
| int| unitType |单位类型
| int| deviceType |设备类型


- 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



- 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; 超重
}
```


- 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;//连接超时
```
- 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;//未知
```
- 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; //阻抗值
```
## 版本历史

|版本号|更新时间|作者|更新信息|
|:----|:---|:-----|-----|
|1.0|2017/2/15|Suzy|初步版本
|1.0.1|2017/7/31|Suzy|修复部分数据转换bug
|1.0.2| 2017/9/11| Suzy|指令中的类型根据实际连上的设备类型设置
|1.0.3| 2017/11/16| Suzy|代码优化
|1.0.4| 2018/7/12| Suzy| 兼容广播秤
|1.0.5| 2018/1/15| Suzy| 兼容新协议
|1.0.6| 2018/2/25| Suzy| 功能优化
|1.0.7| 2018/2/28| Suzy| 封装小数点位数类
|1.0.8| 2018/3/14| Suzy| 修复身体年龄错误的bug
|1.0.9| 2018/4/9| Suzy| 兼容BM09协议
|1.1.1| 2018/5/10| Suzy| 兼容kg/lb分度协议
|1.1.2| 2018/5/11| Suzy| 解决st单位数据跟秤端显示不一致的bug
|1.1.3| 2018/6/22| Suzy| 解决小数点位数有时获取不到的bug
|1.1.4| 2018/7/7| Suzy| 兼容BM15协议
|1.1.5| 2018/7/20| Suzy| 兼容算法ID协议
|1.1.7| 2019/04/30| Stan| 添加BM15体脂数据计算算法
|1.1.8| 2019/06/6| Stan| 修改原始数据转lb ,st计算错误问题
|1.1.9| 2019/12/19| Xing| 增加历史记录
|1.2.0| 2019/1/17| Xing| 更新优化蓝牙库
|1.2.1| 2020/3/19| Xing| 增加体脂数据计算方法和去脂体重算法等
|1.2.2| 2020/3/23| Xing| 修改SDK为gradle形式依赖
|1.2.3| 2020/4/2| Xing| 增加key校验,修改依赖环境为androidx
|1.2.4| 2020/4/10| Xing| 修复已知bug

## FAQ

- 如何判断区分当前扫描到的BroadData(设备)是广播秤还是连接秤?
1.根据BroadData的deviceType属性值区分:
deviceType==AicareBleConfig.TYPE_WEI_BROAD是不带温度的广播秤
deviceType==AicareBleConfig.TYPE_WEI_TEMP_BROAD是有温度的广播秤
deviceType==AicareBleConfig.TYPE_WEI是不带温度的连接秤
deviceType==AicareBleConfig.TYPE_WEI_TEMP是有温度的连接秤

- 蓝牙协议支持哪些单位?
1.单位最多只支持4种(kg,lb,st,斤),具体支持什么单位请参照秤的出厂设置。

- 扫描不到蓝牙设备?
1.查看App权限是否正常,6.0及以上系统必须要定位权限,且需要手动获取权限
2.查看手机的定位服务是否开启,部分手机可能需要打开GPS
3.拔掉电池重启秤
4.是否被其他手机连接(秤未被连接时,秤盘上蓝牙图标会不断闪烁)

- 支持哪些设备?
1.支持BM系列的连接秤、BM15广播秤

- 连接秤如何判定测量结束?
1.onGetFatData()方法回调就代表测量完成

- 广播秤如何判定测量结束?
1.广播秤所有的数据都是从getAicareDevice返回并解析得到WeightData对象,WeightData中的getCmdType()==3表示测量完成,详细请参考demo

- 秤显示的数据和app收到的数据不一致
1.SDK会默认请求获取小数的,可使用WBYBinder中的getDecimalInfo()主动获取小数位
2.app计算重量的时候需要传入DecimalInfo(小数对象)进行计算
```
DecimalInfo{
private int sourceDecimal;//源数据小数位数
private int kgDecimal;//kg小数位数
private int lbDecimal;//lb小数位数
private int stDecimal;//st小数位数
private int kgGraduation;//kg分度
private int lbGraduation;//lb分度
}
```
- 为什么只能测到体重,没有其他体脂数据?
1.必须脱掉鞋和袜子,光脚站在体脂秤的电极片上,才能测出体脂数据。

- 称量时秤总是显示Error,app显示阻抗测量失败,是什么原因?
1.脱掉鞋和袜子,光脚站在体脂秤的电极片上测量,就不会再显示Error。

- 如何高效的向技术支持人员提供反馈?
1.SDK会在控制台打印log,反馈问题时请先将log保存为txt,发给技术人员
2.反馈问题时,尽可能将问题出现时的前后操作描述清楚,最好能录制视频告知问题如何复现。

- 是否有各项体脂数据的判定标准和文案呢?
1.体脂判定标准各厂商标准都可能不一样,目前并没有行业公认的参考标准。如下是我司使用的标准,仅供参考: [《蓝牙体脂秤判定标准及小程序文案20200416》](https://shimo.im/sheets/8dGqCgyhX9P6Xpcw/GX3qk/)

## 联系我们
深圳市易连物联网有限公司

电话:0755-81773367

官网:www.elinkthings.com

邮箱:app@elinkthings.com

Binär
体脂秤SDK使用说明.pdf Visa fil


Laddar…
Avbryt
Spara