问题
I've been trying to create a small Android BLE app that sends some bytes of data to a BLE device (an HM-10 module).
Using existing applications on the Play Store I've been able to test the connection and this seems to be working but I seem to keep running into problems when trying to implement it in my own app.
This is the code I'm using to connect to the BLE device using its MAC-address:
// Initializes Bluetooth adapter.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
BluetoothDevice myDevice = mBluetoothAdapter.getRemoteDevice("00:09:83:20:8D:18");
mBluetoothGatt = myDevice.connectGatt(getApplicationContext(), true, mGattCallback);
and sending data using the writeCharacteristic method:
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status)
{
//Now we can start reading/writing characteristics
String TAG = "";
if (status == BluetoothGatt.GATT_SUCCESS)
{
for (BluetoothGattService gattService : gatt.getServices())
{
Log.i(TAG, "onServicesDiscovered: ---------------------");
Log.i(TAG, "onServicesDiscovered: service=" + gattService.getUuid());
for (BluetoothGattCharacteristic characteristic : gattService.getCharacteristics())
{
Log.i(TAG, "onServicesDiscovered: characteristic=" + characteristic.getUuid());
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0)
{
Log.w(TAG, "onServicesDiscovered: found LED");
//byte[] b = { '$', 0x05, 0x05, 0x10, '$', 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\r', '\n' };
byte[] b = {0x01};
characteristic.setValue(b); // call this BEFORE(!) you 'write' any stuff to the server
boolean myResult = mBluetoothGatt.writeCharacteristic(characteristic);
Log.i(TAG, "onServicesDiscovered: , write bytes?! " + b);
}
}
}
//broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}
I use the following code to receive the callback:
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
if(status != BluetoothGatt.GATT_SUCCESS){
Log.d("onCharacteristicWrite", "Failed write, retrying: " + status);
gatt.writeCharacteristic(characteristic);
}
Log.d("onCharacteristicWrite", ByteArrToHex(characteristic.getValue()));
super.onCharacteristicWrite(gatt, characteristic, status);
}
For some reason the status variable in the callback always contains status 3 (GATT_WRITE_NOT_PERMITTED). I've been trying to look for the specific meaning of this status but I wasn't able to find anything useful.
Does anyone have an idea what I'm missing here?
EDIT: I also noticed that calling getPermissions() on the characteristic in onCharacteristicWrite returns 0.
EDIT: Alright, so thanks to @Emil I was able to change the example to check for the service UUID which resulted into this:
if (gattService.getUuid().equals(UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb")))
{
for (BluetoothGattCharacteristic characteristic : gattService.getCharacteristics())
{
Log.i(TAG, "onServicesDiscovered: characteristic=" + characteristic.getUuid());
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0)
{
Log.w(TAG, "onServicesDiscovered: found LED");
//byte[] b = { '$', 0x05, 0x05, 0x10, '$', 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\r', '\n' };
byte[] b = "$\5\5\16Hello world!\r\n".getBytes();
//byte[] b = {0x01};
characteristic.setValue(b); // call this BEFORE(!) you 'write' any stuff to the server
boolean myResult = mBluetoothGatt.writeCharacteristic(characteristic);
Log.i(TAG, "onServicesDiscovered: , write bytes?! " + b);
}
}
}
The BLE device now receives the data properly!
回答1:
It means that the remote device doesn't permit you to write to that characteristic (although it has set the writable bit in the properties...)
But you shouldn't loop through the services like that and just write to the first writable characteristic you find. Instead find the correct service and characteristic by uuid to make sure you find the correct one.
来源:https://stackoverflow.com/questions/48731701/android-ble-write-oncharacteristicwrite-returns-status-gatt-write-not-permitte