Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A compat library for Bluetooth Low Energy scanning on Android.

License

NotificationsYou must be signed in to change notification settings

NordicSemiconductor/Android-Scanner-Compat-Library

Repository files navigation

Download

The Scanner Compat library solves the problem with scanning for Bluetooth Low Energy devices on Android.The scanner API, initially created in Android 4.3, has changed in Android 5.0 and has been extended in 6.0 and 8.0.This library allows to use modern API even on older phones, emulating not supported features. If a feature(for example offloaded filtering or batching) is not available natively, it will be emulated bythe compat library. Also, native filtering, batching and reporting first match or match lost maybe disabled if you find them not working on some devices. Advertising Extension (ScanSetting#setLegacy(boolean)orsetPhy(int)) is available only on Android Oreo or newer and such calls will be ignored onolder platforms where only legacy advertising packets on PHY LE 1M will be reported,due to the Bluetooth chipset capabilities.

Background scanning

SCAN_MODE_LOW_POWER orSCAN_MODE_OPPORTUNISTIC should be used when scanning in background.Note, that newer Android versions will enforce using low power mode in background, even if another one has been set.This library allows to emulatescanning with PendingIntenton pre-Oreo devices by starting a background service that will scan with requested scan mode.This is much less battery friendly than when the original method is used, but works and savesa lot of development time if such feature should be implemented anyway. Please read belowfor more details.

Note, that for unfiltered scans, scanning is stopped on screen off to save power. Scanning isresumed when screen is turned on again. To avoid this, use scanning with desired ScanFilter.

Usage

The compat library may be found on Maven Central repository. Add it to your project by adding thefollowing dependency:

implementation'no.nordicsemi.android.support.v18:scanner:1.6.0'

Project not targeting API 31 (Android 12) or newer should use version 1.5.1.

Projects not migrated to Android Jetpack should use version 1.3.1, which is feature-equal to 1.4.0.

As JCenter has shut down, starting from version 1.4.4 the library is available only on Maven Central.Make sure you havemavenCentral() in your mainbuild.gradle file:

buildscript {    repositories {        mavenCentral()    }}allprojects {    repositories {        mavenCentral()    }}

Since version 1.5 you will need toenable desugaring of Java 8 language featuresif you have not already done so.(And if you are releasing an Android library, then anyone who usesthat library will also have to enable desugaring.) We expect for nearly all Android projects to havealready enabled desugaring. But if this causes problems for you, please use version 1.4.5.

Permissions

Followingthis link:

An app must haveACCESS_COARSE_LOCATIONpermission in order to get results. An App targeting Android Q or later must haveACCESS_FINE_LOCATIONpermission in order to get results.For apps targetingBuild.VERSION_CODES#Ror lower, this requires theManifest.permission#BLUETOOTH_ADMINpermission which can be gained with a simple<uses-permission> manifest tag.For apps targetingBuild.VERSION_CODES#Sor or higher, this requires theManifest.permission#BLUETOOTH_SCANpermission which can be gained withActivity.requestPermissions(String[], int).In addition, this requires either theManifest.permission#ACCESS_FINE_LOCATIONpermission or a strong assertion that you will never derive the physical location of the device.You can make this assertion by declaringusesPermissionFlags="neverForLocation" on the relevant<uses-permission> manifest tag, but it may restrict the types of Bluetooth devices you can interact with.

API

The Scanner Compat API is very similar to the original one, known from Android Oreo.

Instead of getting it from theBluetoothAdapter, acquire the scanner instance using:

BluetoothLeScannerCompatscanner =BluetoothLeScannerCompat.getScanner();

You also need to change the packets forScanSettings,ScanFilter andScanCallbackclasses to:

no.nordicsemi.android.support.v18.scanner

Sample

To start scanning use (example):

BluetoothLeScannerCompatscanner =BluetoothLeScannerCompat.getScanner();ScanSettingssettings =newScanSettings.Builder().setLegacy(false).setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).setReportDelay(5000).setUseHardwareBatchingIfSupported(true).build();List<ScanFilter>filters =newArrayList<>();filters.add(newScanFilter.Builder().setServiceUuid(mUuid).build());scanner.startScan(filters,settings,scanCallback);

to stop scanning use:

BluetoothLeScannerCompatscanner =BluetoothLeScannerCompat.getScanner();scanner.stopScan(scanCallback);

Scanning modes

There are 4 scanning modes available in nativeScanSettings.3 of them are available since Android Lollipop while the opportunistic scan mode has been added in Marshmallow.This library tries to emulate them on platforms where they are not supported natively.

  1. SCAN_MODE_LOW_POWER -Perform Bluetooth LE scan in low power mode. This is the default scan mode as it consumes the least power.The scanner will scan for 0.5 second and rest for 4.5 seconds. A Bluetooth LE device should advertisevery often (at least once per 100 ms) in order to be found with this mode, otherwise the scanning interval may miss some or even alladvertising events. This mode may be enforced if the scanning application is not in foreground.
  2. SCAN_MODE_BALANCED -Perform Bluetooth LE scan in balanced power mode. Scan results are returned at a rate that provides agood trade-off between scan frequency and power consumption. The scanner will scan for 2 seconds followedby 3 seconds of idle.
  3. SCAN_MODE_LOW_LATENCY -Scan using highest duty cycle. It's recommended to only use this mode when the application is running in the foreground.
  4. SCAN_MODE_OPPORTUNISTIC -A special Bluetooth LE scan mode. Applications using this scan mode will passively listen for other scan resultswithout starting BLE scans themselves.

3 first modes are emulated on Android 4.3 and 4.4.x by starting a handler task that scans for a period of timeand rests in between. To set scanning and rest intervals useBuilder#setPowerSave(long,long).

Opportunistic scanning is not possible to emulate and will fallback toSCAN_MODE_LOW_POWER on Lollipop andpower save settings on pre-Lollipop devices. That means that this library actually will initiate scanningon its own. This may have impact on battery consumption and should be used with care.

Scan filters and batching

Offloaded filtering is available on Lollipop or newer devices whereBluetoothAdapter#isOffloadedFilteringSupported()returnstrue (when Bluetooth is enabled). If it is not supported, this library will scan without a filter andapply the filter to the results. If you find offloaded filtering unreliable you may force using compat filtering by callingBuilder#useHardwareFilteringIfSupported(false). Keep in mind that, newer Android versions may prohibitbackground scanning without native filters to save battery, so this method should be used with care.

Android Scanner Compat Library may also emulate batching. To enable scan batching callBuilder#setScanDelay(interval)with an interval greater than 0. For intervals less 5 seconds the actual interval may vary.If you want to get results in lower intervals, callBuilder#useHardwareBatchingIfSupported(false), which willstart a normal scan and report results in given interval. Emulated batching uses significantly more batterythan offloaded as it wakes CPU with every device found.

Scanning with Pending Intent

Android 8.0 Oreo introducedBackground Execution Limitswhich made background running services short-lived. At the same time, to make background scanning possible, a newmethodwas added toBluetoothLeScannerwhich allows registering aPendingIntentthat will be sent whenever a device matching filter criteria is found. This will also work afteryour application has been killed (the receiver must be added inAndroidManifest and thePendingIntent must be created with an explicit Intent).

Starting from version 1.3.0, this library may emulate such feature on older Android versions.In order to do that, a background service will be started after callingscanner.startScan(filters, settings, context, pendingIntent, requestCode), which will be scanning inbackground with given settings and will send the givenPendingIntent when a devicematching filter is found. To lower battery consumption it is recommended to setScanSettings.SCAN_MODE_LOW_POWER scanning mode and use filter, but even with those conditions fulfilledthe battery consumption will be significantly higher than on Oreo+. To stop scanning callscanner.stopScan(context, pendingIntent, requestCode) withthe same intent in parameter.The service will be stopped when the last scan was stopped.

On Android Oreo or newer this library will use the native scanning mechanism. However, as it may alsoemulate batching or apply filtering (whenuseHardwareBatchingIfSupported oruseHardwareFilteringIfSupportedwere called with parameterfalse) the library will register its own broadcastreceiver that will translate results from native to compat classes.

The receiver and service will be added automatically to the manifest even if they are not used bythe application. No changes are required to make it work.

To use this feature:

Intentintent =newIntent(context,MyReceiver.class);// explicit intentintent.setAction("com.example.ACTION_FOUND");intent.putExtra("some.extra",value);// optionalPendingIntentpendingIntent =PendingIntent.getBroadcast(context,requestCode,intent,PendingIntent.FLAG_UPDATE_CURRENT);BluetoothLeScannerCompatscanner =BluetoothLeScannerCompat.getScanner();ScanSettingssettings =newScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_POWER).setReportDelay(10000).build();List<ScanFilter>filters =newArrayList<>();filters.add(newScanFilter.Builder().setServiceUuid(mUuid).build());scanner.startScan(filters,settings,context,pendingIntent,requestCode);

Add yourMyReceiver toAndroidManifest, as the application context might have been releasedand all broadcast receivers registered to it together with it.

To stop scanning call:

// To stop scanning use the same PendingIntent and request code as one used to start scanning.Intentintent =newIntent(context,MyReceiver.class);intent.setAction("com.example.ACTION_FOUND");PendingIntentpendingIntent =PendingIntent.getBroadcast(context,requestCode,intent,PendingIntent.FLAG_CANCEL_CURRENT);BluetoothLeScannerCompatscanner =BluetoothLeScannerCompat.getScanner();scanner.stopScan(context,pendingIntent,requestCode);

Note: Android versions 6 and 7 will not report any advertising packets when in Doze mode.Read more about it here:https://developer.android.com/training/monitoring-device-state/doze-standby

Note 2: An additional parameter calledrequestCode was added in version 1.4.5 to the above API.It is to ensure that the scanning would be correctly stopped. If not provided, a request code equalto 0 will be used preventing from having multiple scanning tasks.

Background scanning guidelines

To save power it is recommended to use as low power settings as possible and and use filters.However, the more battery friendly settings are used, the longest time to finding a device.In general, scanning withPendingIntent andSCAN_MODE_LOW_POWER orSCAN_MODE_OPPORTUNISTICshould be used, together with report delay set and filters used.useHardwareFilteringIfSupported anduseHardwareBatchingIfSupported should be set totrue (default).

Background scanning on Android 4.3 and 4.4.x will use a lot of power, as all those propertieswill have to be emulated. It is recommended to scan in background only on Lollipop or newer, oreven Oreo or newer devices and giving the user an option to disable this feature.

Note, that for unfiltered scans, scanning is stopped on screen off to save power. Scanning isresumed when screen is turned on again. To avoid this, use scanning with desired ScanFilter.

License

The Scanner Compat library is available under BSD 3-Clause license. See the LICENSE file for more info.

About

A compat library for Bluetooth Low Energy scanning on Android.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors10


[8]ページ先頭

©2009-2026 Movatter.jp