Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scan failed: a BLE scan with the same settings is already started by the app #944

Open
davidgyoung opened this issue Jan 28, 2020 · 9 comments

Comments

@davidgyoung
Copy link
Member

Expected behavior

No error in logs about scan already started

Actual behavior

@paulpv: "I am confused by the behavior that I am seeing when I background the app while a scan is active. With a scan active/started, I background the app and almost immediately get this..."

2020-01-28 14:50:21.042 17590-17590/org.altbeacon.beaconreference D/CycledLeScanner: Done with scan cycle
2020-01-28 14:50:21.044 17590-17590/org.altbeacon.beaconreference D/CycledLeScanner: Not stopping scan because this is Android N and we keep scanning for a minimum of 6 seconds at a time. We will stop in 3773 millisconds.
2020-01-28 14:50:21.045 17590-17590/org.altbeacon.beaconreference D/CycledLeScanner: starting a new scan cycle
2020-01-28 14:50:21.045 17590-17590/org.altbeacon.beaconreference D/CycledLeScanner: restarting a bluetooth le scan
2020-01-28 14:50:21.047 17590-17590/org.altbeacon.beaconreference D/CycledLeScannerForLollipop: starting a scan in SCAN_MODE_LOW_LATENCY
2020-01-28 14:50:21.049 17590-17590/org.altbeacon.beaconreference D/CycledLeScannerForLollipop: Using a wildcard scan filter on Samsung because the screen is on.  We will switch to a non-empty filter if the screen goes off

The log says it isn't going to stop the scan, but what it does is start a scan while a scan is already scanning, which results in onScanFailed SCAN_FAILED_ALREADY_STARTED the the following log:

2020-01-28 14:58:50.950 17590-17590/org.altbeacon.beaconreference E/CycledLeScannerForLollipop: Scan failed: a BLE scan with the same settings is already started by the app

I have yet to find a way to get startAndroidOBackgroundScan to be called. :/

Steps to reproduce this behavior

Run the reference app on a Samsung device with the screen on

Mobile device model and OS version

Samsung

Android Beacon Library version

2.16.4

@davidgyoung
Copy link
Member Author

I believe this log line is harmless, but it does create log noise.

There is logic in the CycledLeScanner to not stop a scan at the end of a cycle because Android now restricts the number of times scans can be started and stopped. Instead the scan is left on.

Some path in the code causes a scan to be commanded again with the exact same settings, which leads to this logged error from the operating system. This log line really should be a warning, not an error, as there are no consequences to my knowledge. The bug is simply that the log line gets sent out at all.

If your goal is to get an android O background scan to be called, then you must (a) use BackgroundPowerSaver and put the app to the background or set background mode to true (b) use a backgroundBetweenScanPeriod that is nonzero. (c) Typically this will be triggered when when using Scan Jobs and not a foreground service (this is the default library setting). Only when the library goes into background mode like this will the o scan be triggered.

@paulpv
Copy link
Contributor

paulpv commented Jan 29, 2020

If your goal is to get an android O background scan to be called, then you must (a) use BackgroundPowerSaver and put the app to the background or set background mode to true (b) use a backgroundBetweenScanPeriod that is nonzero. (c) Typically this will be triggered when when using Scan Jobs and not a foreground service (this is the default library setting). Only when the library goes into background mode like this will the o scan be triggered.

Your reference app shows setting setBackgroundBetweenScanPeriod(0) commented out implying to uncomment setting that to 0 to enable background scanning.
https://github.com/AltBeacon/android-beacon-library-reference/blob/master/app/src/main/java/org/altbeacon/beaconreference/BeaconReferenceApplication.java#L79

I set that to 6200 and it does seem to actually work now.
Should the reference app be updated?

My fork of your reference app is at:
https://github.com/paulpv/android-beacon-library-reference/tree/pebblebee

The diff is:
AltBeacon/android-beacon-library-reference@master...paulpv:pebblebee

I have changed very little effective code, only notably:

  1. added a nonbeacon callback to simply log them
  2. uncommented (enabled) the notification creation and call to enableForegroundServiceScanning
  3. only start monitoring if it was previously started
  4. listen for bluetooth adapter disable/enable
  5. update foreground service notification when bluetooth is disabled/enabled
  6. several cosmetic only lines that should have zero change in behavior

@paulpv
Copy link
Contributor

paulpv commented Jan 29, 2020

It works with the app backgrounded, but not with the screen off.
When I background the app I continue to get scans.
When I turn the screen off I do not continue to get scans.
When I turn the screen on, even if locked, I resume getting scanned devices.
NOTE that this is using a Samsung S8 (the purpose of some of your recent scanning changes).

@paulpv
Copy link
Contributor

paulpv commented Jan 29, 2020

And a breakpoint that I set on the first line of startAndroidOBackgroundScan is never hit.
That is the only area in the code where I see PendingIntent scan in use.
startAndroidOBackgroundScan looks like it requires scheduled jobs, since the only place it is called is from ScanJob.startPassiveScanIfNeeded.

Does AltBeacon's enableForegroundServiceScanning not support PendingIntent scans?
If not, then how does this library successfully scan beacon with the app in the background and/or the screen off/locked?

@davidgyoung
Copy link
Member Author

The simplest explanation for why you would not detect beacons with the screen off is because the scan filter required by Samsung does not match your beacon packet. It is common for this to happen with custom beacon formats for one of three reasons:

  1. For manufacturer advertisements, this is often because the manufacturer code has not been set properly in the BeaconParser. Call beaconParser.setHardwareAssistManufacturerCodes([code]) where code is the integer value of the Bluetooth SIG assigned manufacturer of your beacon. This value is seen right after the FF in the manufacturer advertisement. Examples: 0x4c for Apple Inc., 0x0118 for Radius Networks.

  2. The beacon parser layout might have offsets that are outside the BLE PDU (typically offsets must be positive and have a value of 2+)

  3. The hardware device has run out of hardware scan slots so scan filters won't work for your app at all. This is rare in production cases, but can sometimes happen for developers who have lots of BLE scanning apps installed on their phone that have used up all the hardware scan filter slots. In rare cases like this, the only way around this problem is to uninstall all apps that might be doing BLE scanning, then re-install and test your app so that it gets a slot before other apps take them all up.

@paulpv
Copy link
Contributor

paulpv commented Jan 29, 2020

(Sorry if my comments are straying from the point of the issue. Should I open a separate issue on my "issue"? Is there a better way to converse than via issues? A forum? I didn't see one).

I am clearing the beacon parsers at startup:
https://github.com/paulpv/android-beacon-library-reference/blob/pebblebee/app/src/main/java/org/altbeacon/beaconreference/BeaconReferenceApplication.java#L103

        List<BeaconParser> beaconParsers = beaconManager.getBeaconParsers();
        beaconParsers.clear(); // For testing purposes I currently don't care about the default AltBeacon beacons

Perhaps I should not be doing that?
Is it required to have at least one Parser to scan in the background?
If I clear the parsers, it does not look like the library inserts a wildcard filter.

@davidgyoung
Copy link
Member Author

In order to get any callbacks from the library for didRangeBeaconsInRegion, didEnterRegion, you must have at least on BeaconParser active. Otherwise here will be zero beacons detected that can fire these events. The entire design of the library is centered around detecting beacons, which requires at least one BeaconParser active -- without beacon detections, the library cannot serve its purpose.

@paulpv
Copy link
Contributor

paulpv commented Jan 29, 2020

I am using setNonBeaconLeScanCallback and clearing all beacon parsers.
I get scan results for everything except when the screen is off.
I do understand that scanning w/ the screen off is tricking on some phone brands and may need a special non-wildcard filter.

I can and will create a parser for my own BLE device, which isn't always a beacon, but thought I would avoid that for now and just try to prove out if this library meets my requirements.
If it is a requirement of this library to provide a valid beacon parser then I will go ahead and create a custom one.

@davidgyoung
Copy link
Member Author

Yes, a BeaconParser is a requirement for getting background detections with this library. The setNonBeaconLeScanCallback is provided as a convenience method for apps that also need non-beacon BLE detections, so they apps don't have to set up secondary beacon scanning. But this is a secondary function of the library provided only for convenience, and is certainly not a core function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants