capacitor-community / bluetooth-le

Capacitor plugin for Bluetooth Low Energy
MIT License
285 stars 85 forks source link

Scanning in background in Android should use a Pending Intent #699

Open omercnet opened 1 month ago

omercnet commented 1 month ago

Describe the bug The current implementation does not allow connecting to BLE device after the app is backgrounrded

To Reproduce Steps to reproduce the behavior:

  1. Launch a BLE Scan
  2. Close device screen
  3. Broadcast on BLE device
  4. Wait forever

Expected behavior The app should find the device in the background

Screenshots If applicable, add screenshots to help explain your problem.

Plugin version:

Additional context https://developer.android.com/develop/connectivity/bluetooth/ble/background

In android, to receive scan results in the background, the startScan method should be called with a Pending Intent and not a ScanResult

See https://github.com/android/platform-samples/blob/main/samples/connectivity/bluetooth/ble/src/main/java/com/example/platform/connectivity/bluetooth/ble/BLEScanIntentSample.kt#L114-L120 for an official example

peitschie commented 4 weeks ago

Hi @omercnet

Quick question... when you are launching a scan here... are you filtering by a service UUID? Or running an open scan (i.e., no filters)?

I ask because I noticed this line in the startScan doco when looking at your pending intents patch:

Start Bluetooth LE scan. The scan results will be delivered through callback. For unfiltered scans, scanning is stopped on screen off to save power. Scanning is resumed when screen is turned on again. To avoid this, do filtered scanning by using proper ScanFilter.

Pending intents are only needed when the application process itself may be terminated or paused by the OS and should be relaunched when a device is found. However... this approach doesn't work in general for capacitor applications, as modern Android generally doesn't allow a new Activity like the capacitor browser to be launched from a pending intent like this.

I'll run a few more tests with your patch just to confirm my findings here.

peitschie commented 4 weeks ago

On an Nokia 3.1 Plus with Android 10, I'm seeing that the normal callback scan continues reporting devices in the background once the screen is off.

Here's the code I'm using:

await BleClient.initialize();
await BleClient.requestLEScan({
  services: [numberToUUID(0x180a)],
  allowDuplicates: true
}, d => console.log(Date.now(), "device detected", d))

I've got a simulated peripheral (another phone using nrf Connect ) configured with an advertising packet with the 0x180a service in it.

I'm seeing that when the screen is off, the updates slow down to a burst every 10s or so... but... the scanning continues to function.

Are you able to provide more specifics about the BLE plugin calls you're making here @omercnet , and the operating environment? (Android phone manufacturer... android version... test conditions, etc.)?

peitschie commented 5 days ago

Also relates to #643