1

This question might be answered already but we would like to have a explicit confirmation.

Currently we are using Proprietary beacons working as iBeacons in our business and we have reach the same problem most people is facing with background scanning we turn to our provider and they told us they were aware of the issue but have not been able to fix it to work on background scanning.

We found David Young blog post decide it to give a try how ever we found two blockers

  1. We are not able to get the beacon id from the data we got from the ScanRecord that we get from the scans results in our broadcast receiver (See the code below)

  2. We still not able to scan continuously in the background and periodic scans does not fit well on our use case.

    ArrayList scanResults = intent.getParcelableArrayListExtra(BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT); ScanRecord record = scanResults.get(0).getScanRecord();

We have a found a workaround for this issue by triggering the background scanning using Google Awareness Fence API and starting the service in charge of scanning as a foreground service using startForegroundService to start the service and then call startInForeground() in the service instance to show a persisting notification indicating the action we are doing in the "background" this approach has worked well for our use case how ever it does it with the cost of showing that notification which does not create a good user experience.

we would like to know if anybody has found a better solution for this issue because from google documentation it looks background scanning is something that definitely we will no be able to do anymore

ragar90
  • 78
  • 9

1 Answers1

3

Your summary of the three options for long-term bluetooth scanning with Android 8+ is essentially correct. You cannot do constant background scanning without a persistent notification. You can:

  1. Do periodic scans using a JobScheduler. You can do a scan of up to 10 minutes every 15 minutes.
  2. Run a foreground service that can keep a constant scan going forever, but at the cost of a persistent notification indicating to the user that your app is active and using battery.
  3. Use an Intent based scan to always be looking for a byte pattern in a bluetooth advertisement. This only works on Android 8+, but if done properly, you can certainly parse beacon identifiers out of the packet.

The open-source Android Beacon Library by default uses both options (1) and (2) on Android 8+. It uses option of an Intent-based scan when the periodic scan is not active, which essentially allows you to detect new beacons at all times.

It's unclear why you were not able to parse the identifier out of packets received through intent-based scans, as the aforementioned library has done this successfully with several Android 8 devices. Perhaps the filter was set to broadly so it matched packets that did not contain the identifiers you expected?

You can see code that works from the library here:

 ArrayList<ScanResult> scanResults = intent.getParcelableArrayListExtra(BluetoothLeScanner.EXTRA_LIST_SCAN_RESULT);

The code above is the same you use. The decoding happens here.

As you can see from the second link, the background detection not only parses the records from the Intent, it also causes the library to use the JobScheduler to schedule a constant scan (briefly). So even if for some reason you have a device that is not passing the scan results successfully from the Intent-based scan, the technique of kicking off a temporary scan with the JobScheduler after the Intent is receive would capture and decode a subsequent advertisement if the beacon appeared in the vicinity and is regularly transmitting.

davidgyoung
  • 63,876
  • 14
  • 121
  • 204