0

his is just my code. Saw this example somewhere. But it didn't work.

private static final UUID Battery_Service_UUID = UUID.fromString("0000180F-0000-1000-8000-00805f9b34fb");
private static final UUID Battery_Level_UUID = UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb");
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private BluetoothGattService mBluetoothGatt;

...

public void readCustomCharacteristic() {

    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.w("Beacons", "BluetoothAdapter not initialized");
        return;
    }
    /*check if the service is available on the device*/
    BluetoothGattService mBatteryService = mBluetoothGatt;
    if(mBatteryService == null){
        Log.w("Beacons", "Battery BLE Service not found");
        return;
    }
    /*get the read characteristic from the service*/
    BluetoothGattCharacteristic mReadCharacteristic = mBatteryService.getCharacteristic(Battery_Level_UUID);


    if(mReadCharacteristic.getStringValue(0) == null){
        Log.w("Beacons", "Failed to read characteristic");
    } else {
        Log.i("Beacons", "Battery Level: " + mReadCharacteristic.getValue());
    }
}

To concrete, I get a NullPointerException:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.bluetooth.BluetoothGattCharacteristic.getStringValue(int)' on a null object reference

Maybe I have to implement a complete server, service and broadcastreceiver? Thank you for your help!

Youssif Saeed
  • 11,789
  • 4
  • 44
  • 72
Sunny
  • 25
  • 1
  • 1
  • 6
  • You get the exception because the mBluetoothGatt does not have a characteristic of Battery_Level_UUID. Can you show the code of how mBluetoothGatt is initialized? – davidgyoung Nov 07 '17 at 12:35
  • oh, forgot that. it's in the onCreate(Bundle ...) function like this: mBluetoothGatt = new BluetoothGattService(Battery_Service_UUID, 0); – Sunny Nov 07 '17 at 12:48
  • You should open the app in some BLE explorer app, like nRF connect to see the GATT DB structure. That way you know which characteristics and services it has. – Emil Nov 07 '17 at 13:55

1 Answers1

0

It won't work to simply construct a BluetoothGattService using a constructor new BluetoothGattService(Battery_Service_UUID, 0);. That code usage is intended for hosting a GattService inside your Android app, so the error you are getting is expected.

In order to read a GATT Bluetooth characteristic from an external bluetooth device on Android, you must go through a number of steps first using asynchronous APIs:

  1. Scan for and discover the bluetooth device. (There may be more than one visible, so you somehow have to choose the right one.)

    mBluetoothAdapter.startLeScan(mLeScanCallback);
    // the above will bring a callback to onLeScan(final BluetoothDevice device, int rssi,
        byte[] scanRecord)
    
  2. Connect to the device

    device.connectGatt(mContext, false, mGattCallback);
    // the above will cause a callback to onConnectionStateChange(BluetoothGatt gatt, int status, int newState)
    
  3. Discover the device's services

    gatt.discoverServices();
    // the above will bring a callback to onServicesDiscovered(BluetoothGatt gatt, int status) 
    
  4. Read the characteristic from the service

    gatt.getCharacteristic(Battery_Level_UUID);
    

The line of code in the final step is what the code in the question is trying to do and is resulting in null. The first three steps need to be performed for this to work.

See here for more info: https://developer.android.com/guide/topics/connectivity/bluetooth-le.html

davidgyoung
  • 63,876
  • 14
  • 121
  • 204