I have a problem with my Galaxy S6 with Android 7.0 when I try to use BLE advertising. After a few times that I get onStartSuccess callback I start to get onStartFailure callback with error ADVERTISE_FAILED_ALREADY_STARTED and then it evolves into ADVERTISE_FAILED_TOO_MANY_ADVERTISERS. I had looked through the source code specificly at the startAdvertising method and found this code snippet:
if (mLeAdvertisers.containsKey(callback)) {
postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED);
return;
}
Using reflection I tried to get the mLeAdvertisers in my code just before calling startAdvertising to see if its size is greater than 0. Every time I check its size was always 0. Even when I checked it in my onStartFailure callback.
I didn't find any other place in the source code which could give me ADVERTISE_FAILED_ALREADY_STARTED error. Has anyone seen this error and knows how to deal with it?
This is how I start my advertising:
public void startAdvertise(String serviceUUID) {
if(bluetoothAdapter.isEnabled()) {
Log.e(TAG, "eddie startAdvertise: ");
Config config = Config.getInstance(mContext);
ParcelUuid pUuid = new ParcelUuid(UUID.fromString(serviceUUID));
AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();
dataBuilder.addServiceUuid(pUuid);
dataBuilder.setIncludeDeviceName(false);
dataBuilder.setIncludeTxPowerLevel(true);
int currentTime = (int) (System.currentTimeMillis() / 1000);
byte[] key = CryptoManager.getInstance(mContext).mySelf.generateEphemeralId(currentTime, BLEScannerManager.sGeoHash);
dataBuilder.addServiceData(pUuid, key);
AdvertiseSettings.Builder settingsBuilder = new AdvertiseSettings.Builder();
settingsBuilder.setAdvertiseMode(config.getAdvertiseMode());
settingsBuilder.setTimeout((int) config.getAdvertiseDuration());
settingsBuilder.setTxPowerLevel(config.getAdvertiseTXPowerLevel());
settingsBuilder.setConnectable(false);
try {
Log.e(TAG, "startAdvertise: reflection");
Field f = bluetoothAdapter.getBluetoothLeAdvertiser().getClass().getDeclaredField("mLeAdvertisers");
f.setAccessible(true);
HashMap table = (HashMap) f.get(bluetoothAdapter.getBluetoothLeAdvertiser());
Log.e(TAG, "startAdvertise: size of mLeAdvertises is: " + table.keySet().size());
} catch (Exception e) {
e.printStackTrace();
}
bluetoothAdapter.getBluetoothLeAdvertiser().startAdvertising(settingsBuilder.build(), dataBuilder.build(), advertiseCallback);
}
}
This is how I stop advertising:
public void stopAdvertise() {
if(bluetoothAdapter.isEnabled()){
Log.e(TAG, "eddie stopAdvertise: " );
bluetoothAdapter.getBluetoothLeAdvertiser().stopAdvertising(advertiseCallback);
mEventListenerCallback.onEvent(ADVERTISING_STATUS, false);
}
}