10
votes

I'm developing an Android app. At the start this app show to the user a list of bluetooth devices and when he chooses one of they opens an other activity.

My goal is : after some day when the user will reopen the app the app will have to remember the ble device and it have to try to reconnect to it.

For now I have obtained my goal in this way :

  • I memorize in preference the mac address of the chosen device
  • When the user reopen the app the app do a hidden scan and try to reconnect to a device with a same MAC address.
  • for retrieve the mac address I use the function getAddress() (when I try to connect to the android peripheral this function gives me some problem, because the the device changes his MAC address at each starts :/)

There is a best way to obtain the same thing ?

Off topic : The function onScanResult in the ScanResult some time return to me null device, is it normal ? I have uses startLeScan(UUID[] serviceUuids, BluetoothAdapter.LeScanCallback callback) and after lollipop I use the new version of the startLeScan with Scanfilter. Can it be the problem ?

1

1 Answers

4
votes

For privacy reasongs the mac address keeps on changing-refer below snippet from the ble specs:

5.4.5 Privacy Feature

Bluetooth LE supports a feature that reduces the ability to track a LE device over a period of time by changing the Bluetooth device address on a frequent basis. The privacy feature is not used in the GAP discovery mode and procedures but it is used, when supported, during connection mode and connection procedures. In order for a device using the privacy feature to reconnect to known devices, the device address, referred to as the private address, must be resolvable by the other device.

The private address is generated using the device’s resolving identity key (IRK) exchanged during the bonding procedure.

So the ideal way is to use the IRK to gerate the actual address of the device.However I didnt find any API to do it.

Currently,the work around- which I am using in mny app- to re-connect to the device,

  1. loop through all the available device.
  2. get the serial no-if the serial no matches the already stored number then keep the connection else disconnect.
  3. Repeat step 2 for all the devices.

    This work around will only work if the device exposes serial number through some service.

You can also try setting the autoconnect flag to true when you call connectGatt (Context context, boolean autoConnect, BluetoothGattCallback callback)

From the docs:

public BluetoothGatt connectGatt (Context context, boolean autoConnect, BluetoothGattCallback callback) Added in API level 18

Connect to GATT Server hosted by this device. Caller acts as GATT client. The callback is used to deliver results to Caller, such as connection status as well as any further GATT client operations. The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct GATT client operations. Parameters

autoConnect Whether to directly connect to the remote device (false) or to automatically connect as soon as the remote device becomes available (true).

callback GATT callback handler that will receive asynchronous callbacks. Throws IllegalArgumentException if callback is null