1

I am unable to read data from characteristic on Android but have been able to read the data on iOS device. Can anyone tell me what I'm missing so that data can be read on Android too.

Connecting the device:-

try {
      await device.connect();
    } catch (error) {
      if (error.code != 'already_connected') {
        throw error;
      }
    } finally {
      List<BluetoothService> deviceServices = await device.discoverServices();
       _examineDeviceServicesForTestConnection(deviceServices, device);
    }

Examining the service with characteristic read and notify:-

_examineDeviceServicesForTestConnection(
      List<BluetoothService> services, BluetoothDevice device) async {
    BluetoothCharacteristic testReadCharacteristic;
    BluetoothCharacteristic testWriteCharacteristic;
    serviceLoop:
    for (BluetoothService service in services) {
      if (service.characteristics.isNotEmpty) {
        characteristicLoop:
        for (BluetoothCharacteristic characteristic
            in service.characteristics) {
          if (characteristic.properties.notify) {
            testReadCharacteristic = characteristic;
          }
          if (characteristic.properties.write) {
            testWriteCharacteristic = characteristic;
          }
        }
        if (testReadCharacteristic != null && testWriteCharacteristic != null) {
          final testCommand = "TEST_COMMAND";
          final convertedTestCommand = utf8.encode(testCommand);

          //reading data from characteristics
          _readDataFromCharacteristics(
              testReadCharacteristic, testWriteCharacteristic, device);

          //write command to device
          await testWriteCharacteristic.write(convertedTestCommand);
        }
      }
    }
  }

Reading the data from characteristic:-

_readDataFromCharacteristics(BluetoothCharacteristic readerCharx,
      BluetoothCharacteristic writerCharx, BluetoothDevice device) async {
    await readerCharx.setNotifyValue(true);
    readerCharx.value.listen((response) {
      var decodedResponse = utf8.decode(response);
      print(decodedResponse);
    });
  }

Necessary permissions for bluetooth and location taken

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
vibu
  • 77
  • 1
  • 8
  • What do you mean with 'unable to read'. Do you get the wrong data, no data, an error message? – Michael Kotzjan Feb 19 '21 at 05:21
  • I don't receive any data when using android. – vibu Feb 19 '21 at 08:03
  • 1
    Does your app have the required permissions for android? You will need permissions BLUETOOTH and ACCESS_FINE_LOCATION https://developer.android.com/guide/topics/connectivity/bluetooth-le#permissions You also need to request ACCESS_FINE_LOCATION at runtime for BLE to work – Michael Kotzjan Feb 19 '21 at 08:32
  • I have requested necessary conditions for bluetooth and location. Updated my query with the permissions I am requesting currently. I was requesting the ACCESS_COARSE_LOCATION as mentioned in the Flutter_Blue package. But even after changing the permission, no data was received. – vibu Feb 19 '21 at 09:23
  • 1
    You are not actively reading from the characteristic. You are enabling notifications. Could you try adding ```await Future.delayed(Duration(seconds: 1));``` before ```await testWriteCharacteristic.write(convertedTestCommand);```? I had a similar problem once on Android where I was not waiting long enough for the notifications to be set. – Michael Kotzjan Feb 19 '21 at 11:51
  • 1
    Adding the delayed command made it work. Thanks a lot @M.Kotzjan. – vibu Feb 19 '21 at 13:13

1 Answers1

1

Before setting notify event delay the listening by at least 1 second will allow operating system to prepare for Listening Bluetooth events(Android). Below example works with flutter-blue package for both platforms.

List<BluetoothService> services = await device.discoverServices();
 for (var service in services) {
   for (var characteristic in service.characteristics) {
    await Future.delayed(const Duration(seconds: 1));
    notifyEvent(characteristic);
  }
}