有没有办法在 BLE 特征中只写一个字节?
Is there a way to write just a byte in BLE characteristic?
我是 android 的新手。我的 BLE 设备只需要一个字节(标志)。我试着在一个字节数组中只写一个字节,但它从来没有用过。在将数组写入另一个特征时,它期望 2 个字节有效。有没有办法解决我的问题,还是我必须要求更改设备代码?
我正在使用 this 项目作为示例
public void writeCustomCharacteristicStart() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
/*check if the service is available on the device*/
BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("00001813-0000-1000-8000-00805f9b34fb"));
if(mCustomService == null){
Log.w(TAG, "Custom BLE Service not found");
return;
}
/*get the read characteristic from the service*/
byte pom= 1;
byte[] data= new byte[1];
data[0]=pom;
BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(UUID.fromString("00002a4e-0000-1000-8000-00805f9b34fb"));
if((mWriteCharacteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE)>0 ) {
Log.w(TAG,"Writing started");
mWriteCharacteristic.setValue(data)
}
if(!mBluetoothGatt.writeCharacteristic(mWriteCharacteristic)){
Log.w(TAG, "Failed to write characteristic");
}
Log.w(TAG,"Writing ending");
}
08-06 11:59:57.700 29279-29279/com.example.devicescanactivity E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.devicescanactivity, PID: 29279
java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View.onClick(View.java:4084)
at android.view.View.performClick(View.java:4858)
at android.view.View$PerformClick.run(View.java:20167)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5931)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:987)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View.onClick(View.java:4079)
at android.view.View.performClick(View.java:4858)
at android.view.View$PerformClick.run(View.java:20167)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5931)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:987)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)
Caused by: java.lang.SecurityException: Need BLUETOOTH_PRIVILEGED permission: Neither user 10097 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
at android.os.Parcel.readException(Parcel.java:1549)
at android.os.Parcel.readException(Parcel.java:1502)
at android.bluetooth.IBluetoothGatt$Stub$Proxy.writeCharacteristic(IBluetoothGatt.java:1003)
at android.bluetooth.BluetoothGatt.writeCharacteristic(BluetoothGatt.java:1029)
at com.example.devicescanactivity.BluetoothLeService.writeCustomCharacteristic(BluetoothLeService.java:377)
at com.example.devicescanactivity.DeviceControlActivity.onClickWrite(DeviceControlActivity.java:332)
这是错误,我没有得到 BLUETOOTH_PRIVILEGED 错误,但是当我写入接受 2 个字节的特征时,我没有得到任何错误。
首先,要在您的应用中使用蓝牙,您需要将以下权限添加到您的应用清单中:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
可以将 1 字节的值写入 BLE 特性,前提是设备需要 1 字节的值。
如果存在长度问题,您应该会在 onCharacteristicWrite() 回调中看到错误:
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.i("TAG", "onCharacteristicWrite() status: " + status + " - UUID: " + characteristic.getUuid());
} else if (status == BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH) {
Log.e("TAG", "onCharacteristicWrite() A write operation failed due to invalid attribute length");
} else {
Log.e("TAG", "onCharacteristicWrite() A write operation failed. Status = " + status);
}
}
此外,我会将 writeCharacteristic() 调用移动到您检查 PROPERTY_WRITE 以确保可以完成写入操作:
if((mWriteCharacteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0 ) {
Log.i(TAG,"Writing started");
mWriteCharacteristic.setValue(data)
if(!mBluetoothGatt.writeCharacteristic(mWriteCharacteristic)){
Log.e(TAG, "Failed to write characteristic");
}
}
问题不在于我在特征中写了什么,而是我使用了什么特征。我使用了 HID Control Point,当它在计算机上测试时,nRF Connect 应用程序在我的设备上运行良好,但由于其预定义状态,它无法在 android 上运行。我们刚刚将特征更改为 Record Access Control Point,现在可以使用了。
我是 android 的新手。我的 BLE 设备只需要一个字节(标志)。我试着在一个字节数组中只写一个字节,但它从来没有用过。在将数组写入另一个特征时,它期望 2 个字节有效。有没有办法解决我的问题,还是我必须要求更改设备代码?
我正在使用 this 项目作为示例
public void writeCustomCharacteristicStart() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
/*check if the service is available on the device*/
BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("00001813-0000-1000-8000-00805f9b34fb"));
if(mCustomService == null){
Log.w(TAG, "Custom BLE Service not found");
return;
}
/*get the read characteristic from the service*/
byte pom= 1;
byte[] data= new byte[1];
data[0]=pom;
BluetoothGattCharacteristic mWriteCharacteristic = mCustomService.getCharacteristic(UUID.fromString("00002a4e-0000-1000-8000-00805f9b34fb"));
if((mWriteCharacteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE)>0 ) {
Log.w(TAG,"Writing started");
mWriteCharacteristic.setValue(data)
}
if(!mBluetoothGatt.writeCharacteristic(mWriteCharacteristic)){
Log.w(TAG, "Failed to write characteristic");
}
Log.w(TAG,"Writing ending");
}
08-06 11:59:57.700 29279-29279/com.example.devicescanactivity E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.devicescanactivity, PID: 29279
java.lang.IllegalStateException: Could not execute method of the activity
at android.view.View.onClick(View.java:4084)
at android.view.View.performClick(View.java:4858)
at android.view.View$PerformClick.run(View.java:20167)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5931)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:987)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at android.view.View.onClick(View.java:4079)
at android.view.View.performClick(View.java:4858)
at android.view.View$PerformClick.run(View.java:20167)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5931)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:987)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:782)
Caused by: java.lang.SecurityException: Need BLUETOOTH_PRIVILEGED permission: Neither user 10097 nor current process has android.permission.BLUETOOTH_PRIVILEGED.
at android.os.Parcel.readException(Parcel.java:1549)
at android.os.Parcel.readException(Parcel.java:1502)
at android.bluetooth.IBluetoothGatt$Stub$Proxy.writeCharacteristic(IBluetoothGatt.java:1003)
at android.bluetooth.BluetoothGatt.writeCharacteristic(BluetoothGatt.java:1029)
at com.example.devicescanactivity.BluetoothLeService.writeCustomCharacteristic(BluetoothLeService.java:377)
at com.example.devicescanactivity.DeviceControlActivity.onClickWrite(DeviceControlActivity.java:332)
这是错误,我没有得到 BLUETOOTH_PRIVILEGED 错误,但是当我写入接受 2 个字节的特征时,我没有得到任何错误。
首先,要在您的应用中使用蓝牙,您需要将以下权限添加到您的应用清单中:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
可以将 1 字节的值写入 BLE 特性,前提是设备需要 1 字节的值。
如果存在长度问题,您应该会在 onCharacteristicWrite() 回调中看到错误:
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.i("TAG", "onCharacteristicWrite() status: " + status + " - UUID: " + characteristic.getUuid());
} else if (status == BluetoothGatt.GATT_INVALID_ATTRIBUTE_LENGTH) {
Log.e("TAG", "onCharacteristicWrite() A write operation failed due to invalid attribute length");
} else {
Log.e("TAG", "onCharacteristicWrite() A write operation failed. Status = " + status);
}
}
此外,我会将 writeCharacteristic() 调用移动到您检查 PROPERTY_WRITE 以确保可以完成写入操作:
if((mWriteCharacteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0 ) {
Log.i(TAG,"Writing started");
mWriteCharacteristic.setValue(data)
if(!mBluetoothGatt.writeCharacteristic(mWriteCharacteristic)){
Log.e(TAG, "Failed to write characteristic");
}
}
问题不在于我在特征中写了什么,而是我使用了什么特征。我使用了 HID Control Point,当它在计算机上测试时,nRF Connect 应用程序在我的设备上运行良好,但由于其预定义状态,它无法在 android 上运行。我们刚刚将特征更改为 Record Access Control Point,现在可以使用了。