java 使用小米MiBand和BLE测量心率

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36311874/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 01:15:19  来源:igfitidea点击:

Heart Rate measuring using Xiaomi MiBand and BLE

javaandroidbluetooth-lowenergy

提问by Alexander Hryk

I'm trying to implement simple sdk for working with fitness tracker Xiaomi Mi Band. Currently I can track steps, actuate the vibration, handle the sensor touch but I have a problem with heart rate measuring. My sdk based on https://github.com/pangliang/miband-sdk-android. To measure heart rate, I need to write descriptor to appropriate characteristic to enable handling callback when the value of this characteristic was changed and then write appropriate data to heart rate control point characteristic to directly start the heart rate measure process. The problem is that the heart rate measuring process was not started after the data to initiate this process was successfullywritten to the characteristic (when the Mi Band starts to measure heart rate then the bottom sensor blinks green). This can be caused by a new firmware of fitness tracker (firmware version: 4.15.12.10; HeartRate version: 1.3.74.64) or there are some defects in my code:

我正在尝试实现简单的 sdk,以便与健身追踪器小米 Mi Band 配合使用。目前我可以跟踪步数、启动振动、处理传感器触摸,但我在心率测量方面遇到了问题。我的 sdk 基于https://github.com/pangliang/miband-sdk-android。为了测量心率,我需要将描述符写入适当的特征以在该特征的值发生变化时启用处理回调,然后将适当的数据写入心率控制点特征以直接启动心率测量过程。问题是在数据启动这个过程成功后没有启动心率测量过程写入特征(当 Mi Band 开始测量心率时,底部传感器呈绿色闪烁)。这可能是由于健身追踪器的新固件(固件版本:4.15.12.10;HeartRate 版本:1.3.74.64)或我的代码中存在一些缺陷引起的:

/-------- MiBandProfile --------/
public static final UUID UUID_SERVICE_HEARTRATE = UUID.fromString("0000180d-0000-1000-8000-00805f9b34fb");
public static final UUID UUID_NOTIFICATION_HEARTRATE = UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb");
public static final UUID UUID_CHAR_HEARTRATE = UUID.fromString("00002a39-0000-1000-8000-00805f9b34fb");
public static final UUID UUID_DESCRIPTOR_UPDATE_NOTIFICATION = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");

/-------- MiBandProtocol --------/
public static final byte[] START_HEART_RATE_SCAN = {21, 1, 1};

/-------- BleProvider --------/
public class BleProvider extends BluetoothGattCallback {

public interface NotifyListener {
     void onNotify(byte[] data);
}

private HashMap<UUID, NotifyListener> mNotifyListeners = new HashMap<UUID, NotifyListener>();
.
.
.
public void setNotifyListener(UUID serviceUUID, UUID charaUUID, NotifyListener listener) {
        //enable chara notofication
        if (this.mGatt == null || !this.mIsServicesDiscovered) {
            if (DBG) Log.d(Debug.TAG, "Device is not connected or services are not discovered");
            return;
        }

        BluetoothGattCharacteristic chara = this.mGatt.getService(serviceUUID).getCharacteristic(charaUUID);

        if (DBG) Log.d(Debug.TAG, "setCharacteristicNotification: " + this.mGatt.setCharacteristicNotification(chara, true));
        BluetoothGattDescriptor descriptor = chara.getDescriptor(MiBandProfile.UUID_DESCRIPTOR_UPDATE_NOTIFICATION);
        if (DBG) Log.d(Debug.TAG, "setValue: " + descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE));
        if (DBG) Log.d(Debug.TAG, "writeDescriptor: " + this.mGatt.writeDescriptor(descriptor));
        this.mNotifyListeners.put(charaUUID, listener);
}

@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
        //this method must be called when the characteristic value was changed but nothing happened :(
        super.onCharacteristicChanged(gatt, characteristic);

        if (this.mNotifyListeners.containsKey(characteristic.getUuid())) {
            this.mNotifyListeners.get(characteristic.getUuid()).onNotify(characteristic.getValue());
        }
}
} //end BleProvider

.
.
.

setNotifyListener(MiBandProfile.UUID_SERVICE_HEARTRATE, MiBandProfile.UUID_NOTIFICATION_HEARTRATE, new BleProvider.NotifyListener(){...});
//waiting few seconds
writeCharacteristic(MiBandProfile.UUID_SERVICE_HEARTRATE, MiBandProfile.UUID_CHAR_HEARTRATE, MiBandProtocol.START_HEART_RATE_SCAN);

Maybe the protocol is deprecated and there are people who can share me a new protocol. I will be very glad) Thanks.

也许协议已被弃用,有些人可以与我分享新协议。我会很高兴)谢谢。

采纳答案by Alexander Hryk

I solved the problem! Before calling setNotifyListenerto track the change of pulse value you must to write User Information (age, weight) to appropriate characteristic, because without this Mi Band doesn't start the measuring.

我解决了问题!在调用setNotifyListener跟踪脉冲值的变化之前,您必须将用户信息(年龄、体重)写入适当的特征,因为没有这个 Mi Band 不会开始测量。

回答by Daniel ORTIZ

Im working with BLE A&D , to obatin the iformation i use:

我与 BLE A&D 合作,以获取我使用的信息:

To find UUID

查找 UUID

  @SuppressLint("NewApi")
private void displayGattServicesService(List<BluetoothGattService> gattServices) {
    //  salida.append("Buscando servicio");
    if (gattServices == null)
        return;
    for (BluetoothGattService gattService : gattServices) {

        String uuid = gattService.getUuid().toString();

        List<BluetoothGattCharacteristic> gattCharacteristics = gattService
                .getCharacteristics();
        if (uuid.equals("00001810-0000-1000-8000-00805f9b34fb")) {
            //  salida.append("Ecnontro");
            for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                String uuid1 = gattCharacteristic.getUuid().toString();
                if (uuid1.equals("00002a35-0000-1000-8000-00805f9b34fb")) {
                    //     salida.append("Envio caracterisitca");
                    mensaje(getResources().getString(R.string.Espere_res));
                    mBluetoothLeService.setCharacteristicNotification(
                            gattCharacteristic, true);
                }
            }
        }
    }
}

To set UUID

设置 UUID

BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {

            // Show all the supported services and characteristics on the user interface.
            displayGattServicesService(mBluetoothLeService.getSupportedGattServices());

Use BleGatt Example https://github.com/googlesamples/android-BluetoothLeGatt

使用 BleGatt 示例https://github.com/googlesamples/android-BluetoothLeGatt