Now I know this question has been asked about a billion times.
I've read through most of them(this website hasn't been that helpful for my problem), I've read through the docs and I've read through the examples and tutorials.
What I'm trying to do is:
Send hello world to a BLE device(Connected to an arduino)
What I've done so far:
Paired with the device using the inbuilt settings(no programmed logic in my app)
Connected with the device using the GATT server.
However when I try to write a characteristic, the corresponding status return boolean is always false. This is the most relevant code:
private void setupServer(BluetoothAdapter bAdapter) {
Log.d(TAG, "Started setting up server");
BluetoothLeAdvertiser bAdvertiser = bAdapter.getBluetoothLeAdvertiser();
if (bAdapter != null) {
bGattServer = bManager.openGattServer(getApplicationContext(), new BluetoothGattServerCallback() {
@Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
super.onConnectionStateChange(device, status, newState);
}
});
//Create a service using a random UUID
//Create characteristics with WRITE property and write a value
BluetoothGattService service = new BluetoothGattService(UUID.randomUUID(), BluetoothGattService.SERVICE_TYPE_PRIMARY);
BluetoothGattCharacteristic bluetoothGattCharacteristic = new BluetoothGattCharacteristic(bUUID, BluetoothGattCharacteristic.PROPERTY_WRITE, BluetoothGattCharacteristic.PERMISSION_WRITE);
Log.d(TAG, "Adding characteristic to service " + service.addCharacteristic(bluetoothGattCharacteristic));
bluetoothGattCharacteristic.setValue("hello");
Log.d(TAG, "Trying to write characteristic..., first value: " + bluetoothGattCharacteristic.getValue()[0]);
if (bGatt != null) {
boolean success = bGatt.writeCharacteristic(bluetoothGattCharacteristic);
if (success) {
Log.d(TAG, "Successfuly wrote characteristic to" + bUUID);
} else {
//THIS ALWAYS EXECUTES??
Log.e(TAG, "Failed to write to characteristic");
}
} else {
Log.e(TAG, "BGATT IS NULL");
}
service.addCharacteristic(bluetoothGattCharacteristic);
bGatt.setCharacteristicNotification(bluetoothGattCharacteristic, true);
bGattServer.addService(service);
}
These are my permissions:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-feature android:name="android.hardware.bluetooth_le" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
And this is the rest of the relevant code
private boolean scanBluetooth(final BluetoothAdapter bAdapter, final BluetoothDevice[] bDevice) {
final BluetoothLeScanner bScanner = bAdapter.getBluetoothLeScanner();
final boolean[] stopCallback = {false};
Log.d(TAG,"Started scanning");
bScanner.startScan(new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
bDevice[0] = result.getDevice();
if (bDevice[0] == null || stopCallback[0]) {
Toast.makeText(getApplicationContext(), "Didn't find a device", Toast.LENGTH_LONG);
} else {
stopCallback[0] = true;
System.out.println("DEVICE" + bDevice[0]);
bGatt = bDevice[0].connectGatt(getApplicationContext(), true, new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if(status == BluetoothGatt.GATT_SUCCESS){
Log.d(TAG, "Successful GATT " + newState);
setupServer(bAdapter);
return;
}
if(status == BluetoothGatt.GATT_FAILURE){
Log.e(TAG,"Bigg error boi");
System.exit(1);
}
else{
Log.w(TAG,"Oh no, gatt failed " + status + " retrying");
return;
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
Log.d(TAG, "Characteristic written" + status);
}
}, BluetoothDevice.TRANSPORT_LE);
Log.d(TAG, "Bgatt value:" + bGatt);
}
}
});
if(bGatt==null){
Log.w(TAG, "BGATT IS NULL WHILE SCANNING");
}
Log.d(TAG, "Finished scanning...");
return true;
}
I've gotten bUUID using the app BLEScanner, which showed a UUID for read and write. The goal of my application is to mirror the functionality of that app, but I'm starting to lose my mind. I can't even send a simple hello world yet.
Android Studio output:
018-12-01 23:58:56.214 25024-25136/com.iopt.davidv7.iopt W/DBG: Oh no, gatt failed 22 retrying
2018-12-01 23:58:56.675 25024-25136/com.iopt.davidv7.iopt D/DBG: Successful GATT 2
2018-12-01 23:58:56.675 25024-25136/com.iopt.davidv7.iopt D/DBG: Started setting up server
2018-12-01 23:58:56.692 25024-25136/com.iopt.davidv7.iopt D/DBG: Adding characteristic to service true
2018-12-01 23:58:56.693 25024-25136/com.iopt.davidv7.iopt D/DBG: Trying to write characteristic..., first value: 104
2018-12-01 23:58:56.693 25024-25136/com.iopt.davidv7.iopt E/DBG: Failed to write to characteristic
The client is a simple HM-10 Bluetooth module and I want to mirror what I send in the app on the serial monitor using ARDUINO IDE for now.
I hope I've given you all the context, because I'm losing hope. I'm not manually checking for permissions because I've set them up using the system dialogue, however, there was only "location" to enable? Could this be the root of my issue? Checking with checkSelfPermission for bluetooth, bluetooth admin returns true though, so I dont think that is it:
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_ADMIN)
!= PackageManager.PERMISSION_GRANTED) {
Log.e(TAG,"No permission for bluetooth");
// Permission is not granted
}
else{
Log.d(TAG,"Bluetooth permission granted");
}