BluetoothLeScannerImplOreo startScan PendingIntent causes leak that eventually fails all future scans
See original GitHub issueThis problem might manifest itself with can't Register GATT client, MAX client reached: 32 output in an unfiltered log.
Please also refer to my StackOverflow question and self-answer: https://stackoverflow.com/q/57104535/252308
Basically, BluetoothLeScannerImplOreo startScanInternal has the following code (I added the log line in my fork):
final PendingIntent pendingIntent = createStartingPendingIntent(nonNullFilters,
nonNullSettings, context, callbackIntent);
Log.v(TAG, "#GATT startScanInternal: pendingIntent=" + pendingIntent);
return scanner.startScan(nativeFilters, nativeSettings, pendingIntent);
stopScanInternal has the following code (log line added in my fork):
final PendingIntent pendingIntent = createStoppingPendingIntent(context, callbackIntent);
Log.v(TAG, "#GATT stopScanInternal: pendingIntent=" + pendingIntent);
scanner.stopScan(pendingIntent);
Here is a log of my app starting and stopping a few scans:
2019-07-19 21:14:51.230 16905-16905/com.testapp V/BleScannerManager: scan: #GATT +bleScanner.startScan(...)
2019-07-19 21:14:58.424 16905-16905/com.testapp V/BleScannerImplOreo: #GATT startScanInternal: pendingIntent=PendingIntent{1dfc67: android.os.BinderProxy@e560a14}
2019-07-19 21:14:58.468 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(948)] GATT_Register 3c2e1fd9-d3fd-6897-a113-863aa50df781
2019-07-19 21:14:58.468 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(968)] allocated gatt_if=7
2019-07-19 21:14:58.478 16905-16905/com.testapp V/BleScannerManager: scan: #GATT bleScanner.startScan(...); result=SUCCESS(0)
2019-07-19 21:14:58.479 16905-16905/com.testapp V/BleScannerManager: scan: #GATT -bleScanner.startScan(...)
2019-07-19 21:14:58.481 16905-16905/com.testapp E/BleScannerManager: #GATT bleScannerStartScanCount=1, elapsedMillisSinceBleScannerStartScanFirstTime=0
2019-07-19 21:15:03.521 1447-1447/? D/BtGatt.ScanManager: awakened up at time 614650173
2019-07-19 21:15:08.250 16905-16905/com.testapp V/BleScannerManager: scan: #GATT +bleScanner.stopScan(...)
2019-07-19 21:15:08.255 16905-16905/com.testapp V/BleScannerImplOreo: #GATT stopScanInternal: pendingIntent=PendingIntent{dc4115f: android.os.BinderProxy@84087ac}
2019-07-19 21:15:08.259 1447-1982/? E/BtGatt.ContextMap: Context not found for info com.android.bluetooth.gatt.GattService$PendingIntentInfo@77d2d25
2019-07-19 21:15:08.260 16905-16905/com.testapp V/BleScannerManager: scan: #GATT -bleScanner.stopScan(...)
2019-07-19 21:15:08.556 1447-1447/? D/BtGatt.ScanManager: awakened up at time 614655208
2019-07-19 21:15:08.570 1447-1554/? E/BtGatt.GattService: Exception: android.app.PendingIntent$CanceledException
2019-07-19 21:15:20.556 16905-16905/com.testapp V/BleScannerManager: scan: #GATT +bleScanner.startScan(...)
2019-07-19 21:15:20.570 16905-16905/com.testapp V/BleScannerImplOreo: #GATT startScanInternal: pendingIntent=PendingIntent{2ce86d6: android.os.BinderProxy@84087ac}
2019-07-19 21:15:20.575 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(948)] GATT_Register 6b444e39-d61a-1d92-52d6-afd6e901b56b
2019-07-19 21:15:20.575 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(968)] allocated gatt_if=8
2019-07-19 21:15:20.576 16905-16905/com.testapp V/BleScannerManager: scan: #GATT bleScanner.startScan(...); result=SUCCESS(0)
2019-07-19 21:15:20.576 16905-16905/com.testapp V/BleScannerManager: scan: #GATT -bleScanner.startScan(...)
2019-07-19 21:15:20.576 16905-16905/com.testapp E/BleScannerManager: #GATT bleScannerStartScanCount=2, elapsedMillisSinceBleScannerStartScanFirstTime=22097
2019-07-19 21:15:23.264 16905-16905/com.testapp V/BleScannerManager: scan: #GATT +bleScanner.stopScan(...)
2019-07-19 21:15:23.269 16905-16905/com.testapp V/BleScannerImplOreo: #GATT stopScanInternal: pendingIntent=PendingIntent{ebafcb0: android.os.BinderProxy@ebb6729}
2019-07-19 21:15:23.272 1447-1982/? E/BtGatt.ContextMap: Context not found for info com.android.bluetooth.gatt.GattService$PendingIntentInfo@3abaefa
2019-07-19 21:15:23.272 16905-16905/com.testapp V/BleScannerManager: scan: #GATT -bleScanner.stopScan(...)
2019-07-19 21:15:24.968 16905-16905/com.testapp V/BleScannerManager: scan: #GATT +bleScanner.startScan(...)
2019-07-19 21:15:24.980 16905-16905/com.testapp V/BleScannerImplOreo: #GATT startScanInternal: pendingIntent=PendingIntent{8b1626b: android.os.BinderProxy@ebb6729}
2019-07-19 21:15:24.990 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(948)] GATT_Register 0bbb0b8f-2c63-dfc2-268d-fbfe39360ddf
2019-07-19 21:15:24.990 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(968)] allocated gatt_if=9
2019-07-19 21:15:24.990 16905-16905/com.testapp V/BleScannerManager: scan: #GATT bleScanner.startScan(...); result=SUCCESS(0)
2019-07-19 21:15:24.990 16905-16905/com.testapp V/BleScannerManager: scan: #GATT -bleScanner.startScan(...)
2019-07-19 21:15:24.991 16905-16905/com.testapp E/BleScannerManager: #GATT bleScannerStartScanCount=3, elapsedMillisSinceBleScannerStartScanFirstTime=26511
2019-07-19 21:15:25.019 1447-1554/? E/BtGatt.GattService: Exception: android.app.PendingIntent$CanceledException
2019-07-19 21:15:25.795 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(948)] GATT_Register 32a50296-06f2-ed4d-f83c-25da059a4a19
2019-07-19 21:15:25.795 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(968)] allocated gatt_if=10
2019-07-19 21:15:26.046 1447-1447/? D/BtGatt.ScanManager: awakened up at time 614672699
2019-07-19 21:15:27.000 16905-16905/com.testapp V/BleScannerManager: scan: #GATT +bleScanner.stopScan(...)
2019-07-19 21:15:27.005 16905-16905/com.testapp V/BleScannerImplOreo: #GATT stopScanInternal: pendingIntent=PendingIntent{40e339d: android.os.BinderProxy@6340012}
2019-07-19 21:15:27.008 1447-1982/? E/BtGatt.ContextMap: Context not found for info com.android.bluetooth.gatt.GattService$PendingIntentInfo@96b43b4
2019-07-19 21:15:27.009 16905-16905/com.testapp V/BleScannerManager: scan: #GATT -bleScanner.stopScan(...)
2019-07-19 21:15:28.679 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(948)] GATT_Register f119757a-00ff-29b4-72e0-952c5e0db695
2019-07-19 21:15:28.679 1447-1941/? I/bt_stack: [INFO:gatt_api.cc(968)] allocated gatt_if=10
2019-07-19 21:15:28.810 1447-1447/? D/BtGatt.ScanManager: awakened up at time 614675462
2019-07-19 21:15:28.822 1447-1554/? E/BtGatt.GattService: Exception: android.app.PendingIntent$CanceledException
Notice that the pendingIntent= logged during a startScan and stopScan do not match.
This means that the code never actually stops any PendingIntent started scans.
The pendingIndent passed to stopScan must be the exact same one that was passed to startScan.
You can usually only start about 28, max of 32, scans before the OS blocks all future scans. This repros on every API >= 26 phone I have tried.
I can look in to a fix and send a PR, but I wanted to open this issue to see if there is anything else to discuss.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:14 (10 by maintainers)

Top Related StackOverflow Question
The problem is not resolved, with 1.4.1! The “listent” PendingIntent is not broadcasted anymore, that’s true, but the Bluetooth internal scanning is still not stopped, here is the proof :" BtGatt.ScanManager: awakened up at time". Test device : Pixel2 with Android 10
Problem found : BluetoothLeScannerImplOreo -> createStartingPendingIntent(…) and createStoppingPendingIntent(…) in both methods this line of code breaks the normal flow :
In this way the started pendingIntent hashCode() will be different than the stop pendingIntent hashCode()!! this is bad! it’s a bug, cause the doc clarifies that the two intents must be the same, and in this library case are totally different.
Solution : Add “requestCode” as an extra argument to
createStartingPendingIntent(..., @NonNull final int requestCode)andcreateStoppingPendingIntent(..., @NonNull final int requestCode)methods, and use that for id.And yes, the requestCode must be the same for start and stop.
The time has come, I started looking into this issue now. Just after releasing 1.4.4… 😦