How to extract latitude and longitude from location_and_speed characteristic?
Asked Answered
S

1

1

In an Android app in central role - how do you please get a hold of the latitude and longitude stored in the org.bluetooth.characteristic.location_and_speed characteristic in the org.bluetooth.service.location_and_navigation service of a BLE peripheral?

I am trying the following Java-code -

private float mLatitude;
private float mLongitude;

private static final UUID LOCATION_AND_NAVIGATION =
    UUID.fromString("00001819-0000-1000-8000-00805f9b34fb");

private static final UUID LOCATION_AND_SPEED = 
    UUID.fromString("00002a67-0000-1000-8000-00805f9b34fb");

private BluetoothAdapter mBluetoothAdapter;
private BluetoothGatt mBluetoothGatt;
private BluetoothGattService mVehicleInfoService;
private BluetoothGattCharacteristic mLocationAndSpeedChar;

Here is the callback called on device connect:

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, 
        int status, int newState) {

        if (newState == BluetoothProfile.STATE_CONNECTED)
            gatt.discoverServices();
    }

After the services have been discovered I try to create the service and characteristic objects (and verify they are not null in debugger):

    @Override
    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
        mVehicleInfoService = 
            mBluetoothGatt.getService(LOCATION_AND_NAVIGATION);

        mLocationAndSpeedChar = 
            mVehicleInfoService.getCharacteristic(LOCATION_AND_SPEED);

        if (mLocationAndSpeedChar != null)
            mBluetoothGatt.readCharacteristic(mLocationAndSpeedChar);
    }

Here is the callback called on characteristic value read:

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt,
        BluetoothGattCharacteristic ch, int status) {

        if (status == BluetoothGatt.GATT_SUCCESS) {
            mLatitude = ch.getIntValue(
                BluetoothGattCharacteristic.FORMAT_SINT32, 
                WHICH_OFFSET_TO_USE_FOR_LAT);

            mLongitude = ch.getIntValue(
                BluetoothGattCharacteristic.FORMAT_SINT32,
                WHICH_OFFSET_TO_USE_FOR_LNG);
        }
    }
};

Two questions please:

  1. What offset parameters should I pass to the getIntValue method above?
  2. How to convert the integers to doubles needed by Google Maps Location?
Spindell answered 12/8, 2015 at 13:57 Comment(3)
As some fields are optional you need to look at the flags to work out the offset. The bit sizes are in the table the flags are at byte 0. As for getting to double just cast and multiply by the scaling factor in the spec. if in doubt trial and error with the number of zeros required.Cologarithm
What is the factor in the spec, should I divide the signed integers by 10^7 ?Spindell
yes, or multiply by 1/10^7Cologarithm
C
0

Although I think it won't work for a read you need a notify.

            UUID CCCD = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
            mVehicleInfoService = bluetoothGatt.getService(LOCATION_AND_NAVIGATION);
            mLocationAndSpeedChar = mVehicleInfoService.getCharacteristic(LOCATION_AND_SPEED);
            bluetoothGatt.setCharacteristicNotification(mLocationAndSpeedChar,true);
            BluetoothGattDescriptor descriptor = mLocationAndSpeedChar.getDescriptor(CCCD);
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            bluetoothGatt.writeDescriptor(descriptor);
Childs answered 4/2, 2016 at 0:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.