Comments (11)
The correct checking for this "no more than 5 start/stop in 30 seconds"
The source code for this start/stop blocking is here: https://android-review.googlesource.com/c/platform/packages/apps/Bluetooth/+/215844/15/src/com/android/bluetooth/gatt/AppScanStats.java#144
This behavior was documented on developer.android.com when Nougat was in developer preview 4, but since has been removed and didn't make to the official documentation (https://developer.android.com/about/versions/nougat/)
For now there's still a copy of that page on the web archive: https://web.archive.org/web/20160820074825/https://developer.android.com/preview/support.html#dp4
We’ve changed the BLE Scanning behavior starting in DP4. We’ll prevent applications from starting and stopping scans more than 5 times in 30 seconds. For long running scans, we’ll convert them into opportunistic scans.
To fix this on our app, our scanner is a singleton and we wrapped in a NougatScanner
that delayed the stop of the scan, and if the app starts again within those seconds, there's no need for calling start
.
I wonder if that is something that Nordic would be interest in implementing on their library, or they rather leave it as a "thin" compat layer.
I hope it helps.
from android-scanner-compat-library.
I'll close the issue here, but marked it with a label and will mentioned it in the Readme. Thanks @budius for all the information.
from android-scanner-compat-library.
Hmm.. I think you'd have to count it in your app. As you wrote, the callback isn't called and as I can imagine, it depends on the Android version and phone manufacturer, because why not.
from android-scanner-compat-library.
@budius Nice find. Too bad this is just emitted as an error code when trying to start a scan.
I'll leave this issue open for Nordic to decide what they want to do with it. If this is something you want to add to the CompatScanner library or not.
from android-scanner-compat-library.
My implementation to handle this is below
`
private const val NUM_SCAN_DURATIONS_KEPT = 5
private const val EXCESSIVE_SCANNING_PERIOD_MS = 30 * 1000L
private const val SCHEDULE_START_SCAN_WHEN_STARTED_TOO_FREQUENTLY = true
private class SafeScanner {
private val scanner = BluetoothLeScannerCompat.getScanner()
private val handler = Handler(Looper.myLooper()!!)
private val startTimes = LinkedList<Long>()
fun start(filters: List<ScanFilter>, settings: ScanSettings, callback: ScanCallback) {
val now = System.currentTimeMillis()
startTimes.removeIf { now - it > EXCESSIVE_SCANNING_PERIOD_MS }
if (startTimes.size >= NUM_SCAN_DURATIONS_KEPT) {
Log.e("BLE", "startScan: too frequent, $startTimes")
callback.onScanFailed(ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY)
if (SCHEDULE_START_SCAN_WHEN_STARTED_TOO_FREQUENTLY) {
val delay = startTimes.first + EXCESSIVE_SCANNING_PERIOD_MS - now + 2_000
Log.e("BLE", "startScan: schedule start after $delay ms")
handler.postDelayed({
start(filters, settings, callback)
}, delay)
}
} else {
startTimes.addLast(now)
scanner.startScan(filters, settings, callback)
Log.e("BLE", "startScan: $startTimes")
}
}
fun stop(callback: ScanCallback) {
handler.removeCallbacksAndMessages(null)
scanner.stopScan(callback)
}
}
`
from android-scanner-compat-library.
@philips77 Sure, I could check if i performed a scan within the last 2 seconds and if that is the case then back off and wait for 2 seconds to go by. But how will i know that is enough? Maybe some manufacturer requires 30 seconds?
from android-scanner-compat-library.
True. So the best idea is to assume that users aren't stupid and aren't changing screens over and over to kill the scanner, or design the app so it's now possible. I don't think anything else could be done, actually. You may also check if you aren't getting any records for some time and write preform some action based on this.
As you said, I'm able to reproduce this issue in nRF Connect, where I'm using the standard API.
from android-scanner-compat-library.
Hey @philips77 , I just stumbled about this issue. It seems onScanFailed() is not called, only the following is printed.
onScannerRegistered() - status=6 scannerId=-1 mScannerId=0
Shouldn't the onScanFailed() callback be triggered in this case?
from android-scanner-compat-library.
Well... the lib calls it when the native API is called. But in fact the native onScanFailed()
is not being called.
from android-scanner-compat-library.
Thanks for this discussion. This issue was driving me nuts until i found the logcat entry "onScannerRegistered() status=6 ...".
Just want to say, sme issue here. Why the heck onScanFailed() isn't called from android system... but that's another story.
from android-scanner-compat-library.
@philips77 I have checked the readme file and seems you have forgotten to add information been discussed here
from android-scanner-compat-library.
Related Issues (20)
- Lisense HOT 1
- Is there a non AndroidX version? HOT 1
- If the app is repeatedly killed, the device cannot be scanned
- Filter does not update in run time (using Pending intent) HOT 1
- Cannot stop scan when using PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_MUTABLE HOT 1
- NoClassDefFoundError: Failed resolution HOT 4
- Scan occassionally returns no results until restarted HOT 3
- Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference HOT 1
- Android 12 cannot scan out beacon devices HOT 2
- (Long Range (Bluetooth 5.2)) LE Coded PHY HOT 3
- setUseHardwareBatchingIfSupported HOT 4
- No scan results - Pixel 6a Android 13 HOT 3
- 广播名没有修改
- Failed to resolve BluetoothLeScannerCompat when used through a library
- Hit
- Leaked scan callback when app be killed by task manager
- Could not find no.nordicsemi.android:thingylib:2.0.0. HOT 2
- Hello, I may need your help
- Not discovering "Limited Discoverable" devices in Android
- BLE Scanner not working in Android 14
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from android-scanner-compat-library.