我的巨剑能轻松搅动潮汐 2023-07-13 16:50 采纳率: 28.6%
浏览 104
已结题

unity安卓使用 BluetoothLEHardwareInterface插件开发小米手环5报错"failed to write characteristic descriptor"

手机:vivo y30
开发目标:小米手环5
unity版本:2021.3.21LTS
目的:开发一个unity 安卓app,通过蓝牙通信读取到小米手环正在运动时测量到的心率值。
//
1.问题
unity安卓使用 BluetoothLEHardwareInterface插件开发小米手环5报错"failed to write characteristic descriptor",从而无法读取小米手环5的心率值功能

img

img


(读取到的uuid是对的)
////
2.报错内容
①报错:无法读取到正在测量的心率值。
BluetoothLEHardwareInterface.SubscribeCharacteristic方法,报错为:failed to write characteristic descriptor(无法写入特征描述符)。
②更改了读取数据的方法
BluetoothLEHardwareInterface.ReadCharacteristic出现了报错:failed to read a characteristic(无法读取特征)。
但我觉得应该不能用ReadCharacteristic方法因为

img


因为是notify属性。可能就不能用读方法了
3.已知信息

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools" android:installLocation="preferExternal">
    <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
    <application android:theme="@style/UnityThemeSelector" android:icon="@drawable/app_icon" android:label="@string/app_name" android:isGame="true">
        <activity android:label="@string/app_name" android:screenOrientation="fullSensor" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:hardwareAccelerated="false" android:name="com.unity3d.player.UnityPlayerActivity">

            <intent-filter>
                <!--<action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <category android:name="android.intent.category.LEANBACK_LAUNCHER" />-->
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>
    </application>
    <!--
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
  <uses-permission android:name="android.permission.BLUETOOTH"/>
  <uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
    -->
    <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.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <uses-permission-sdk-23 android:name="android.permission.BLUETOOTH" />
    <uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <!--
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    -->
</manifest>

①蓝牙服务的UUID↓

img

②获取到该字段即可获得环5正在测量的心率值

img

https://zhuanlan.zhihu.com/p/591331326

4.代码片段

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class BLContect01 : MonoBehaviour
{
    #region
    public class UUIDS
    {
        public static readonly string miband1 = "0000fee0-0000-1000-8000-00805f9b34fb";
        public static readonly string miband2 = "0000fee1-0000-1000-8000-00805f9b34fb";
        public static readonly string alert = "00001802-0000-1000-8000-00805f9b34fb";
        public static readonly string devinfo = "0000180a-0000-1000-8000-00805f9b34fb";
        public static readonly string heartrate = "0000180d-0000-1000-8000-00805f9b34fb";
        public static readonly string notifications = "00001811-0000-1000-8000-00805f9b34fb";
    }
    public class CHAR_UUIDS
    {
        public static readonly string devicename = "00002a00-0000-1000-8000-00805f9b34fb";

        public static readonly string hz = "00000002-0000-3512-2118-0009af100700";
        public static readonly string sensor = "00000001-0000-3512-2118-0009af100700";
        public static readonly string auth = "00000009-0000-3512-2118-0009af100700";

        public static readonly string alert = "00002a06-0000-1000-8000-00805f9b34fb";
        public static readonly string current_time = "00002a2b-0000-1000-8000-00805f9b34fb";
        // unknown=         "00002a23-0000-1000-8000-00805f9b34fb";
        public static readonly string serial = "00002a25-0000-1000-8000-00805f9b34fb";
        public static readonly string hrdw_revision = "00002a27-0000-1000-8000-00805f9b34fb";
        public static readonly string revision = "00002a28-0000-1000-8000-00805f9b34fb";
        public static readonly string heartrate_measure = "00002a37-0000-1000-8000-00805f9b34fb";
        public static readonly string heartrate_control = "00002a39-0000-1000-8000-00805f9b34fb";
        public static readonly string notifications = "00002a46-0000-1000-8000-00805f9b34fb";
        // unknown=         "00002a50-0000-1000-8000-00805f9b34fb";
        public static readonly string age = "00002a80-0000-1000-8000-00805f9b34fb";
        public static readonly string le_params = "0000ff09-0000-1000-8000-00805f9b34fb";

        public static readonly string configuration = "00000003-0000-3512-2118-0009af100700";
        public static readonly string fetch = "00000004-0000-3512-2118-0009af100700";
        public static readonly string activity_data = "00000005-0000-3512-2118-0009af100700";
        public static readonly string battery = "00000006-0000-3512-2118-0009af100700";
        public static readonly string steps = "00000007-0000-3512-2118-0009af100700";
        public static readonly string user_settings = "00000008-0000-3512-2118-0009af100700";
        public static readonly string music_notification = "00000010-0000-3512-2118-0009af100700";
        public static readonly string deviceevent = "00000010-0000-3512-2118-0009af100700";
        public static readonly string chunked_transfer = "00000020-0000-3512-2118-0009af100700";
    }
    public class NOTIFICATION_TYPES
    {
        public static readonly byte[] auth = { 0x02, 0x00 };
        public static readonly byte[] msg = { 0x01, 0x01 };
        public static readonly byte[] call = { 0x03, 0x01 };
        public static readonly byte[] missed = { 0x04, 0x01 };
        public static readonly byte[] sms = { 0x05, 0x01 };
    }
    public class AUTH_TYPES
    {
        public static readonly byte[] received = { 0x10, 0x01, 0x01 };
        public static readonly byte[] requestcode = { 0x10, 0x02, 0x01 };
        public static readonly byte[] authed = { 0x10, 0x03, 0x01 };
        public static readonly byte[] authfail = { 0x10, 0x03, 0x08 };
    }
    public class HEARTRATECONTROL_TYPES
    {
        public static readonly byte[] stop_heartrate_manual = { 0x15, 0x01, 0x00 };
        public static readonly byte[] stop_heartrate_auto = { 0x15, 0x02, 0x00 };
        public static readonly byte[] start_heartrate_manual = { 0x15, 0x01, 0x01 };
        public static readonly byte[] start_heartrate_auto = { 0x15, 0x02, 0x01 };
        public static readonly byte[] ping = { 0x16 };
    }
    #endregion
    const string TargetBLEDeviceAddress="C1:02:07:05:62:14";
    const string TargetBLEDeviceName = "Mi Smart Band 5";
    const int BLEDevice_arrLength = 5;
    public Text text_warn;
    public Text text_TempValue;

    public Text[] Text_AddressArr = new Text[BLEDevice_arrLength];

    public bool lock_connectPrint = false;//true 可打印
    bool ok = false;
    //test
    int num = 0;
    class BLEDeviceData
    {
        public BLEDeviceData(string _address, string _name, string _rssi, string _advertisingInfo)
        {
            this._address = _address;
            this._rssi = _rssi;
            this._name = _name;
            this._advertisingInfo = _advertisingInfo;
        }
        public BLEDeviceData()
        {
            this._address = "00:00";//
            this._name = "no name";//
            this._rssi = "0";//
            this._advertisingInfo = "0";//
        }
        public string _address = "00:00";//设备地址
        public string _name = "no name";//设备名
        public string _rssi = "0";//信号强度重新赋值
        public string _advertisingInfo = "0";//蓝牙设备的广播信息
        public string Print_BLEDeviceData()
        {
            //设备
            string x = string.Format("Device: {0} RSSI: {1} Address: {2}\nData Length: {3}  Bytes: {4} ", this._name, this._rssi, this._address, this._advertisingInfo.Length, this._advertisingInfo);
            return x;
        }
    }
    BLEDeviceData[] BLEDevice_Arr = new BLEDeviceData[BLEDevice_arrLength];
    string[] Test = new string[BLEDevice_arrLength];
    int BLEDevice_arr_Index = 0;


    void Start()
    {
        BluetoothLEHardwareInterface.Initialize(true, false,
            () =>
            {
                show("蓝牙初始化成功");
                Invoke("scanBLE", 1f);
            },
            (string errorInfo) =>
            {
                show("蓝牙初始化报错\n" + errorInfo.ToString());
            });

        for (int i = 0; i < BLEDevice_arrLength; i++)
        {
            BLEDevice_Arr[i] = new BLEDeviceData();
        }
        #region
        //BluetoothDeviceScript.
        /*BluetoothLEHardwareInterface.Initialize(true, false, delegate
        {
            Invoke("scanBLE", 0.1f);
            text_warn.text = "初始化中";
        },delegate(string errorInfo) {
            text_warn.text = "初始化报错"+ errorInfo.ToString();
        });
        */
        #endregion
        //F5();
    }

    public void scanBLE()//扫描蓝牙
    {
        BluetoothLEHardwareInterface.ScanForPeripheralsWithServices(null, (address, name) =>
        { }, (address, name, rssi, advertisingInfo) =>
        {
            //蓝牙搜索
            #region
            /*if (BLEaddress_find(address, name, rssi.ToString(), advertisingInfo.ToString()))//找到相同,不操作
            {

            }
            else
            {

            }*/
            #endregion
            //找到对应的蓝牙名称
            if (name == TargetBLEDeviceName)
            {
                show("找到了米环5");
                //连接蓝牙、接收数据
                BLEConnect(address, name, rssi.ToString(), advertisingInfo.ToString());

            }
        });
    }
    public void BLEConnect(string getaddress, string getname, string getrssi, string getadvertisingInfo)
    {
        show("停止搜索");
        BluetoothLEHardwareInterface.StopScan();
        show("开始连接" + getaddress);
        lock_connectPrint = true;
        BluetoothLEHardwareInterface.ConnectToPeripheral(getaddress, (getaddress)=> {
        

        }, null, (getaddress, serviceUUID, characteristicUUID) =>//要更改
        {
            if (lock_connectPrint)
            {
                //加个锁,平均每次连接打印54次
                show("成功连接到" + string.Format("getaddress:{0} serviceUUID:{1} characteristicUUID:{2}", getaddress, serviceUUID, characteristicUUID));
            }
            lock_connectPrint = false;

            //BLEReviceData(getaddress,serviceUUID);
            StartCoroutine(BLEDataAnalyse());
        });
    }
    public void BLEReviceData(string getaddress,string serviceUUID)
    {
        //接收数据
        //BluetoothLEHardwareInterface.SubscribeCharacteristicWithDeviceAddress(getaddress, serviceUUID, characteristicUUID, null, BLEDataAnalyse);//要更改
        //show("收数据");
        /*BluetoothLEHardwareInterface.SubscribeCharacteristicWithDeviceAddress(getaddress, UUIDS.heartrate, CHAR_UUIDS.heartrate_measure, null, (string arg1, string arg2, byte[] arg3)=>
        {

        });*/
        
    }
    string hearttemp="";
    IEnumerator BLEDataAnalyse()
    {
       /* yield return new WaitForSeconds(1);
        BluetoothLEHardwareInterface.WriteCharacteristic(TargetBLEDeviceAddress, UUIDS.heartrate, CHAR_UUIDS.heartrate_control,
          HEARTRATECONTROL_TYPES.stop_heartrate_auto, HEARTRATECONTROL_TYPES.stop_heartrate_auto.Length, false, (charUUID) =>
          {
          });
        yield return new WaitForSeconds(1);
        BluetoothLEHardwareInterface.WriteCharacteristic(TargetBLEDeviceAddress, UUIDS.heartrate, CHAR_UUIDS.heartrate_control,
          HEARTRATECONTROL_TYPES.stop_heartrate_manual, HEARTRATECONTROL_TYPES.stop_heartrate_manual.Length, false, (charUUID) =>
          {
          });*/

        yield return new WaitForSeconds(1);
        BluetoothLEHardwareInterface.SubscribeCharacteristicWithDeviceAddress(TargetBLEDeviceAddress, UUIDS.heartrate, CHAR_UUIDS.heartrate_measure, null, (address, characteristicUUID, bytes) =>
        {
            show("数据Sub");
            hearttemp = "";//重置读取到的数据
            for (int i = 0; i < bytes.Length; i++)
            {
                hearttemp += bytes[i];
            }
            show(hearttemp);
            hearttemp = "";
        });
        /**/
    }
    public void show(string str)
    {
        text_TempValue.text += "\n"+str;
    }
    bool BLEaddress_find(string getaddress, string getname, string getrssi, string getadvertisingInfo)
    {
        for (int i = 0; i <= BLEDevice_arr_Index; i++)
        {
            if (BLEDevice_Arr[i]._address.Contains(getaddress))//找到相同地址
            {
                //更换信号
                //BLEDevice_Arr[i] = new BLEDeviceData(getaddress, getname, getrssi, getadvertisingInfo);
                BLEDevice_Arr[i]._rssi = getrssi;
                //text_TempValue.text = BLEDevice_Arr[i]._address+"和"+getaddress + "相同,替换信号强度RSSI";
                return true;
            }
        }
        //text_TempValue.text = BLEDevice_Arr[BLEDevice_arr_Index]._address + "和" + getaddress + "不同,添加替换";
        BLEDevice_arr_Index = (BLEDevice_arr_Index + 1) % BLEDevice_arrLength;
        BLEDevice_Arr[BLEDevice_arr_Index] = new BLEDeviceData(getaddress, getname, getrssi, getadvertisingInfo);

        return false;
    }

    /// <summary>unity蓝牙获取到其他设备信息添加
    /// 
    /// </summary>
    /// 蓝牙获取到的数组的添加
    /// <param name="addressInstance">地址</param>
    /// <param name="name">设备名</param>
    /// <param name="rssi">信号强弱</param>
    /// <param name="advertisingInfo">蓝牙设备的广播信息</param>
    /// <returns></returns>

    //屏幕显示
    #region
    //屏幕刷新携程
    /*IEnumerator ShowUI()
    {
        while (true)
        {
            yield return new WaitForSeconds(1f);
            F5();
        }
    }

    //屏幕刷新方法
    void F5()
    {
        for (int i = 0; i <= BLEDevice_arr_Index; i++)
        {
            Text_AddressArr[i].text = BLEDevice_Arr[i].Print_BLEDeviceData();
        }

        
    }*/
    #endregion

}


/////////////////////////////

  • 写回答

1条回答 默认 最新

  • qllaoda 2023-07-13 18:43
    关注

    这个应该只用读取就行了,为什么要write呢

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 7月15日
  • 赞助了问题酬金20元 7月13日
  • 修改了问题 7月13日
  • 修改了问题 7月13日
  • 展开全部

悬赏问题

  • ¥15 stc15f2k60s2单片机关于流水灯,时钟,定时器,矩阵键盘等方面的综合问题
  • ¥15 YOLOv8已有一个初步的检测模型,想利用这个模型对新的图片进行自动标注,生成labellmg可以识别的数据,再手动修改。如何操作?
  • ¥30 NIRfast软件使用指导
  • ¥20 matlab仿真问题,求功率谱密度
  • ¥15 求micropython modbus-RTU 从机的代码或库?
  • ¥15 django5安装失败
  • ¥15 Java与Hbase相关问题
  • ¥15 后缀 crn 游戏文件提取资源
  • ¥20 bash代码推送不上去 git fetch origin master #失败了
  • ¥15 LOL外服加入了反作弊系统,现在游戏录像rofl文件离线都无法打开