【问题标题】:How to get Heart Rate from Mi Band using Bluetooth Le如何使用蓝牙 Le 从 Mi Band 获取心率
【发布时间】:2019-04-18 12:40:13
【问题描述】:

我想从我的 Mi Band 2 中通过 BluetoothLe 获取心率。我尝试按照 Getting Started with Bluetooth Low Energy 中的示例进行操作,但我没有成功从心率中写入值。我想我错过了什么,但我无法意识到是什么。这是我第一次使用蓝牙和智能手环。我希望你能帮助我。我不知道是否应该使用{0x01} byte 来启动心率传感器。

因此,按照示例,我下载了 BluetoothLeDemo 应用程序,并从那里获得了 BleWrapper BleDefinedUUIDsBleNamesResolver。我有 2 个按钮扫描和停止。我创建了一个名为 mBleWrapper 的 BleWrapper 来使用它来开始扫描和停止扫描。

mBleWrapper = new BleWrapper(this, new BleWrapperUiCallbacks.Null(){


            @Override
            public void uiDeviceConnected(BluetoothGatt gatt, BluetoothDevice device) {
                super.uiDeviceConnected(gatt, device);
            }

            @Override
            public void uiDeviceDisconnected(BluetoothGatt gatt, BluetoothDevice device) {
                super.uiDeviceDisconnected(gatt, device);
            }

            @Override
            public void uiAvailableServices(BluetoothGatt gatt, BluetoothDevice device, List<BluetoothGattService> services) {
                super.uiAvailableServices(gatt, device, services);

                BluetoothGattCharacteristic c=null;

                for(BluetoothGattService service : services) {
                    String serviceName = BleNamesResolver.resolveUuid(service.getUuid().toString());
                    Log.i("SERVIDE", serviceName);
                    }
                }
c=gatt.getService(BleDefinedUUIDs.Service.HEART_RATE).getCharacteristic(BleDefinedUUIDs.Characteristic.HEART_RATE_MEASUREMENT);
                mBleWrapper.writeDataToCharacteristic(c, new byte[]{0x01});
                mState = mSensorState.ACC_ENABLE;

            }

            @Override
            public void uiCharacteristicForService(BluetoothGatt gatt, BluetoothDevice device, BluetoothGattService service, List<BluetoothGattCharacteristic> chars) {
                super.uiCharacteristicForService(gatt, device, service, chars);

            }

            @Override
            public void uiCharacteristicsDetails(BluetoothGatt gatt, BluetoothDevice device, BluetoothGattService service, BluetoothGattCharacteristic characteristic) {
                super.uiCharacteristicsDetails(gatt, device, service, characteristic);
            }

            @Override
            public void uiNewValueForCharacteristic(BluetoothGatt gatt, BluetoothDevice device, BluetoothGattService service, BluetoothGattCharacteristic ch, String strValue, int intValue, byte[] rawValue, String timestamp) {
                super.uiNewValueForCharacteristic(gatt, device, service, ch, strValue, intValue, rawValue, timestamp);
                switch (mState) {
                    case ACC_READ:
                        Log.i("READ", "heart rate dta");
                }

                    Log.i("Value", "Val" + intValue);

            }

            @Override
            public void uiGotNotification(BluetoothGatt gatt, BluetoothDevice device, BluetoothGattService service, BluetoothGattCharacteristic characteristic) {
                super.uiGotNotification(gatt, device, service, characteristic);
                String ch = BleNamesResolver.resolveCharacteristicName(characteristic.getUuid().toString());

                Log.d("AAA",  "uiGotNotification: " + ch);
            }

            @Override
            public void uiSuccessfulWrite(BluetoothGatt gatt, BluetoothDevice device, BluetoothGattService service, BluetoothGattCharacteristic ch, String description) {
                super.uiSuccessfulWrite(gatt, device, service, ch, description);
                BluetoothGattCharacteristic c;
                switch (mState) {
                    case ACC_ENABLE:
                        Log.i("ENABLED", "Heart Rate enabled");
                        c = gatt.getService(BleDefinedUUIDs.Service.HEART_RATE).getCharacteristic(BleDefinedUUIDs.Characteristic.HEART_RATE_MEASUREMENT);
                        mBleWrapper.requestCharacteristicValue(c);
                        mState = mSensorState.ACC_READ;
                        break;
                    case ACC_READ:
                        Log.i("WRITE", "SUCCESSfule write");
                        break;
                }
            }

            @Override
            public void uiFailedWrite(BluetoothGatt gatt, BluetoothDevice device, BluetoothGattService service, BluetoothGattCharacteristic ch, String description) {
                super.uiFailedWrite(gatt, device, service, ch, description);
                switch (mState) {
                    case ACC_ENABLE:
                        Log.i("FAILED", "Feailed to enbale Heart Rate");
                }
            }

            @Override
            public void uiNewRssiAvailable(BluetoothGatt gatt, BluetoothDevice device, int rssi) {
                super.uiNewRssiAvailable(gatt, device, rssi);
            }

            @Override
            public void uiDeviceFound(BluetoothDevice device, int rssi, byte[] record) {
                super.uiDeviceFound(device, rssi, record);
                String msg = "uiDeviceFound: "+device.getAddress()+","+device.getName();
                if(devicesList.contains(device)==false) {
                    Log.i("Devicce", "deviceFound: " + msg);
                    devicesList.add(device);
                    genericListAdapter.notifyDataSetChanged();
                }

            }
        });

我用ListViewonClick 显示找到的所有设备我想连接到该项目并在日志中写入心率。

 deviceListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
             BluetoothGatt gatt;
             BluetoothGattCharacteristic c;
             connectDevice((BluetoothDevice) parent.getItemAtPosition(position));

             Log.i("Read", "Get Heart Rate");
             if(mBleWrapper.isConnected()==false){
                Log.i("not connected", "NOT CONNECTE");
                 return;
             }

             gatt = mBleWrapper.getGatt();
             c = gatt.getService(BleDefinedUUIDs.Service.HEART_RATE).getCharacteristic(BleDefinedUUIDs.Characteristic.HEART_RATE_MEASUREMENT);
             mBleWrapper.requestCharacteristicValue(c);
             mState=mSensorState.ACC_READ;


            }
        });

我还在 BleWrapper 课上添加了onDescpritorWriter

 @Override
        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
            super.onDescriptorWrite(gatt, descriptor, status);

            String deviceName = gatt.getDevice().getName();
            String serviceName = BleNamesResolver.resolveServiceName(descriptor.getCharacteristic().getService().getUuid().toString().toLowerCase(Locale.getDefault()));
            String charName = BleNamesResolver.resolveCharacteristicName(descriptor.getCharacteristic().getUuid().toString().toLowerCase(Locale.getDefault()));
            String description = "Device: " + deviceName + " Service: " + serviceName + " Characteristic: " + charName;

            if(status == BluetoothGatt.GATT_SUCCESS) {
                mUiCallback.uiSuccessfulWrite(mBluetoothGatt, mBluetoothDevice, mBluetoothSelectedService, descriptor.getCharacteristic(), description);
            }
            else {
                mUiCallback.uiFailedWrite(mBluetoothGatt, mBluetoothDevice, mBluetoothSelectedService, descriptor.getCharacteristic(), description + " STATUS = " + status);
            }

        }

对于我使用的 UUIDS 服务

UUID HEART_RATE = UUID.fromString("0000180d-0000-1000-8000-00805f9b34fb");

对于特性

UUID HEART_RATE_MEASUREMENT   = UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb");

在其他示例中,我看到他们也使用 UUIDS 作为描述符,但我没有。我知道这是一个很长的帖子和问题,但我真的需要一些帮助。

【问题讨论】:

标签: android bluetooth-lowenergy android-bluetooth heartrate


【解决方案1】:

有些东西你可以检查一下。

显然,您已成功发现周围的设备。根据this(蓝牙官方文档)心率服务(UUID:180d)需要先设置notify为TRUE。比如:

  1. 使用 UUID:00002902-0000-1000-8000-00805f9b34fb 获取特征的描述符。
 BluetoothGattDescriptor descriptor = gattCharacteristic.getDescriptor(Client_Characteristic_Configuration);
  1. 将描述符的特性(通知)设置为 TRUE:
 descriptor.setValue((BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE));
  1. 将值写入 BLE 设备(使用回调函数中的 Gatt 对象)
gatt.writeDescriptor(descriptor);

在上面之后,您可以在覆盖函数中获取数据:

public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status)

这样:

BluetoothGattCharacteristic Char = gatt.getService(FORA_SERVICE_UUID).getCharacteristic(The uuid you want to connect);

byte[] data = Char.getValue();

也许您可以显示示例链接。可以更清楚你用了什么。

【讨论】:

  • 您好,示例在“蓝牙 LE 入门”一书中。我试过了,但它不起作用
  • 嗨。上次我要从设备中获得价值。但是设备没有“发布”我需要的服务(因为制造商自定义了他们自己的服务并将所有数据打包在其中)这个想法让我想到也许你可以使用 gatt.discoverService() 来确认 Mi 乐队是否有您需要的服务。
  • 嗨,谢谢它有心率服务,我的意思是它发现了它
  • 嘿@Mary 我最近也在做同样的事情。我知道心率服务可用,但我不知道如何访问它。你有什么解决办法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-12
相关资源
最近更新 更多