Search code examples
androidflutterdartbluetooth-lowenergyobd-ii

Unable to read data from characteristic on Android but able to read on iOS Flutter Blue


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"/>

Solution

  • 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);
      }
    }