• Stars
    star
    755
  • Rank 60,125 (Top 2 %)
  • Language
    Java
  • License
    BSD 3-Clause "New...
  • Created over 9 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A compat library for Bluetooth Low Energy scanning on Android.

Android BLE Scanner Compat library

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 by the compat library. Also, native filtering, batching and reporting first match or match lost may be disabled if you find them not working on some devices. Advertising Extension (ScanSetting#setLegacy(boolean) or setPhy(int)) is available only on Android Oreo or newer and such calls will be ignored on older 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 or SCAN_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 emulate scanning with PendingIntent on 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 saves a lot of development time if such feature should be implemented anyway. Please read below for more details.

Note, that for unfiltered scans, scanning is stopped on screen off to save power. Scanning is resumed 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 the following 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 have mavenCentral() in your main build.gradle file:

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

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

Permissions

Following this link:

An app must have ACCESS_COARSE_LOCATION permission in order to get results. An App targeting Android Q or later must have ACCESS_FINE_LOCATION permission in order to get results. For apps targeting Build.VERSION_CODES#R or lower, this requires the Manifest.permission#BLUETOOTH_ADMIN permission which can be gained with a simple <uses-permission> manifest tag. For apps targeting Build.VERSION_CODES#S or or higher, this requires the Manifest.permission#BLUETOOTH_SCAN permission which can be gained with Activity.requestPermissions(String[], int). In addition, this requires either the Manifest.permission#ACCESS_FINE_LOCATION permission or a strong assertion that you will never derive the physical location of the device. You can make this assertion by declaring usesPermissionFlags="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 the BluetoothAdapter, acquire the scanner instance using:

BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();

You also need to change the packets for ScanSettings, ScanFilter and ScanCallback classes to:

no.nordicsemi.android.support.v18.scanner

Sample

To start scanning use (example):

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

to stop scanning use:

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

Scanning modes

There are 4 scanning modes available in native ScanSettings. 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 advertise very often (at least once per 100 ms) in order to be found with this mode, otherwise the scanning interval may miss some or even all advertising 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 a good trade-off between scan frequency and power consumption. The scanner will scan for 2 seconds followed by 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 results without 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 time and rests in between. To set scanning and rest intervals use Builder#setPowerSave(long,long).

Opportunistic scanning is not possible to emulate and will fallback to SCAN_MODE_LOW_POWER on Lollipop and power save settings on pre-Lollipop devices. That means that this library actually will initiate scanning on 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 where BluetoothAdapter#isOffloadedFilteringSupported() returns true (when Bluetooth is enabled). If it is not supported, this library will scan without a filter and apply the filter to the results. If you find offloaded filtering unreliable you may force using compat filtering by calling Builder#useHardwareFilteringIfSupported(false). Keep in mind that, newer Android versions may prohibit background 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 call Builder#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, call Builder#useHardwareBatchingIfSupported(false), which will start a normal scan and report results in given interval. Emulated batching uses significantly more battery than offloaded as it wakes CPU with every device found.

Scanning with Pending Intent

Android 8.0 Oreo introduced Background Execution Limits which made background running services short-lived. At the same time, to make background scanning possible, a new method was added to BluetoothLeScanner which allows registering a PendingIntent that will be sent whenever a device matching filter criteria is found. This will also work after your application has been killed (the receiver must be added in AndroidManifest and the PendingIntent 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 calling scanner.startScan(filters, settings, context, pendingIntent, requestCode), which will be scanning in background with given settings and will send the given PendingIntent when a device matching filter is found. To lower battery consumption it is recommended to set ScanSettings.SCAN_MODE_LOW_POWER scanning mode and use filter, but even with those conditions fulfilled the battery consumption will be significantly higher than on Oreo+. To stop scanning call scanner.stopScan(context, pendingIntent, requestCode) with the 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 also emulate batching or apply filtering (when useHardwareBatchingIfSupported or useHardwareFilteringIfSupported were called with parameter false) the library will register its own broadcast receiver 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 by the application. No changes are required to make it work.

To use this feature:

    Intent intent = new Intent(context, MyReceiver.class); // explicit intent
	intent.setAction("com.example.ACTION_FOUND");
	intent.putExtra("some.extra", value); // optional
	PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
	
	BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner();
	ScanSettings settings = new ScanSettings.Builder()
				.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
				.setReportDelay(10000)
				.build();
	List<ScanFilter> filters = new ArrayList<>();
	filters.add(new ScanFilter.Builder().setServiceUuid(mUuid).build());
	scanner.startScan(filters, settings, context, pendingIntent, requestCode);

Add your MyReceiver to AndroidManifest, as the application context might have been released and 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.
    Intent intent = new Intent(context, MyReceiver.class);
	intent.setAction("com.example.ACTION_FOUND");
	PendingIntent pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT);
	
	BluetoothLeScannerCompat scanner = 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 called requestCode 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 equal to 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 with PendingIntent and SCAN_MODE_LOW_POWER or SCAN_MODE_OPPORTUNISTIC should be used, together with report delay set and filters used. useHardwareFilteringIfSupported and useHardwareBatchingIfSupported should be set to true (default).

Background scanning on Android 4.3 and 4.4.x will use a lot of power, as all those properties will have to be emulated. It is recommended to scan in background only on Lollipop or newer, or even 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 is resumed 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.

More Repositories

1

Android-BLE-Library

A library that makes working with Bluetooth LE on Android a pleasure. Seriously.
Java
1,982
star
2

Android-nRF-Connect

Documentation and issue tracker for nRF Connect for Android.
1,299
star
3

Android-nRF-Toolbox

The nRF Toolbox is a container app that stores your Nordic Semiconductor apps for Bluetooth Low Energy in one location.
Kotlin
1,077
star
4

Android-DFU-Library

Device Firmware Update library and Android app
Java
760
star
5

IOS-nRF-Toolbox

The nRF Toolbox is a container app that stores your Nordic Semiconductor apps for Bluetooth Low Energy in one location.
Swift
600
star
6

IOS-DFU-Library

OTA DFU Library for Mac and iOS, compatible with nRF5x SoCs
Swift
517
star
7

nRF-Logger-API

The public library with nRF Logger API. Allows to log custom logs into the nRF Logger database.
Java
413
star
8

Android-nRF-Mesh-Library

The Bluetooth Mesh Provisioner and Configurator library.
Java
404
star
9

pc-nrfutil

nrfutil python library and command line client
Python
383
star
10

bluetooth-numbers-database

An up-to-date listing of all the various Bluetooth Specification-related elements that are defined by our industry (Company IDs, Service UUIDs, Characteristic UUIDs and Descriptor UUIDs), that you can use instead of rolling your own.
JavaScript
323
star
11

IOS-nRF-Mesh-Library

Provision, configure and control Bluetooth mesh devices with nRF Mesh library.
Swift
310
star
12

Kotlin-BLE-Library

Kotlin
300
star
13

pc-ble-driver

Desktop library for Bluetooth low energy development
C
281
star
14

Android-nRF-Blinky

nRF Blinky is an application developed targeting an audience of developers who are new to Bluetooth Low Energy
Kotlin
266
star
15

nrfx

Standalone drivers for peripherals present in Nordic SoCs
C
254
star
16

ble-sdk-arduino

C++
249
star
17

nRF-Sniffer-for-802.15.4

nRF-based 802.15.4 sniffer (firmware and software)
Python
227
star
18

IOS-CoreBluetooth-Mock

Mocking library for CoreBluetooth framework.
Swift
224
star
19

Nordic-Thingy52-FW

Nordic Thingy:52 software development kit. This kit is designed to assist users in developing their own custom firmware for Thingy. Please see http://www.nordicsemi.com/thingy for the latest news and software releases.
C
210
star
20

pc-nrfconnect-launcher

nRF Connect for Desktop application and framework
TypeScript
172
star
21

pc-nrfconnect-ble

Bluetooth low energy app for nRF Connect for Desktop
TypeScript
150
star
22

nRF5-SDK-for-Mesh

This repo is a "Release" clone of the zip files available @
C
145
star
23

IOS-nRF-Connect

Info page
136
star
24

pc-ble-driver-py

Python bindings for the ble-driver library
Python
126
star
25

zcbor

Low footprint C/C++ CBOR library and Python tool providing code generation from CDDL descriptions.
C
114
star
26

Android-Nordic-Thingy

Android SDK and sample application for Nordic Thingy:52
Java
107
star
27

Android-nRF-Beacon

The nRF Beacon application lets you explore the full range of possibilities for beacons using Bluetooth Smart technology. The application has been designed to demonstrate all features of the nRF8122 Bluetoothยฎ Smart Beacon Kit.
Java
106
star
28

pc-nrfconnect-ppk

Power Profiler app for nRF Connect for Desktop
TypeScript
103
star
29

IOS-nRF-Connect-Device-Manager

A mobile management library for devices supporting nRF Connect Device Manager.
Swift
88
star
30

Android-nRF-Connect-Device-Manager

A mobile management library for devices running Apache Mynewt and Zephyr (DFU, logs, stats, config, etc.)
Java
81
star
31

pc-ble-driver-js

Node.js interface to the C/C++ pc-ble-driver library. API docs: https://nordicsemiconductor.github.io/pc-ble-driver-js/
JavaScript
79
star
32

pynrfjprog

Python wrapper around the nrfjprog dynamic link library (DLL)
C
75
star
33

pc-nrfconnect-programmer

Programmer app for nRF Connect for Desktop
TypeScript
66
star
34

IOS-Nordic-Thingy

iOS Library and example application for Thingy:52โ„ข
Swift
65
star
35

IOS-BLE-Library

The Bluetooth LE library for iOS and Mac. 100% Swift.
Swift
62
star
36

Android-BLE-Common-Library

A companion library for the Android BLE Library. Contains parsers for common Bluetooth SIG characteristics.
Java
55
star
37

Android-nRF-Beacon-for-Eddystone

An application with Eddystone GATT Configuration Service & Google Nearby API and Proximity API.
Java
48
star
38

iOS-nRF-Blinky

A starter app for new developers in the BLE world!
Swift
44
star
39

nrf-udev

Linux udev rules for Nordic Semiconductor devices.
Shell
37
star
40

pc-nrfconnect-rssi

RSSI Viewer app for nRF Connect for Desktop
C
37
star
41

Flutter-nRF-Connect-Device-Manager

A Flutter plugin for McuMgr libraries for Android and iOS.
Dart
36
star
42

Android-nRF-Bluetooth-LE-Joiner

nRF BLE Joiner is an application that lets you add new IoT nodes to a network based on Bluetooth Smart.
Java
35
star
43

Linux-ble-6lowpan-joiner

C
35
star
44

pc-nrfjprog-js

Node.js library that exposes the functionality of the nRF Command Line Tools
C++
28
star
45

nrf-intel-hex

Yet another parser for "Intel HEX" files.
JavaScript
27
star
46

pc-nrfconnect-toolchain-manager

Install and manage tools to develop with the nRF Connect SDK (NCS)
TypeScript
24
star
47

pc-nrfconnect-shared

Dependency management for nRF Connect for Desktop packages
TypeScript
21
star
48

asset-tracker-cloud-firmware-aws

nRF Asset Tracker for AWS firmware.
C
18
star
49

pc-nrf-dfu-js

Javascript implementation of Nordic's DFU protocol over serial (or NoBLE).
JavaScript
17
star
50

nrf-device-setup-js

JavaScript
15
star
51

nRF-IEEE-802.15.4-radio-driver

A generic, stack independent and system independent IEEE 802.15.4 radio driver, intended for nRF SoCs with IEEE 802.15.4 radio. It contains a built-in support for multiprotocol, allowing for concurrent operation of IEEE 802.15.4-based stacks (e.g. Thread, ZigBee) with Bluetooth LE
13
star
52

pc-nrfconnect-linkmonitor

LTE Link Monitor app for nRF Connect for Desktop
JavaScript
13
star
53

pc-nrfconnect-gettingstarted

nRF Connect Getting Started Assistant is a tool to guide through the process of setting up the nRF Connect SDK toolchain
SCSS
12
star
54

asset-tracker-cloud-aws-js

A reference implementation of a serverless backend for an IoT product developed using AWS CDK in TypeScript.
TypeScript
12
star
55

asset-tracker-cloud-docs

The nRF Asset Tracker aims to provide a concrete end-to-end example for an IoT product in the asset tracker space.
CSS
10
star
56

pc-nrfconnect-dtm

C
10
star
57

IOS-Memfault-Library

nRF Memfault Library + Example App
Swift
8
star
58

pc-nrfconnect-boilerplate

Starting point for creating apps for nRF Connect for Desktop
TypeScript
8
star
59

Android-nRF-Wi-Fi-Provisioner

An Android library and app for provisioning Nordic Wi-Fi devices to a network.
Kotlin
8
star
60

KMM-BLE-Library

Kotlin
8
star
61

nRF52-Bluetooth-Course

7
star
62

IOS-nRF-Edge-Impulse

Connect to a Thing:53, collect sensor data over Bluetooth Low Energy and create your machine learning applications.
Swift
6
star
63

Android-Memfault-Library

An Android library for sending heap dumps to the Memfault cloud.
Kotlin
6
star
64

pc-nrfconnect-cellularmonitor

TypeScript
5
star
65

modemtalk

[end-of-life] library to interface with the nRF9160 modem
JavaScript
5
star
66

Android-Gradle-Plugins

Kotlin
5
star
67

pc-nrfconnect-docs

Developer documentation for nRF Connect for Desktop. Read them at https://NordicSemiconductor.github.io/pc-nrfconnect-docs/
HTML
5
star
68

IOS-nRF-Wi-Fi-Provisioner

A Swift library and app for provisioning Nordic Wi-Fi devices to a network.
Swift
5
star
69

pc-nrfconnect-serial-terminal

Terminal emulator for serial port connections
TypeScript
5
star
70

asset-tracker-cloud-app-js

The nRF Asset Tracker Web Application is a reference single-page application (SPA) developed using create-react-app in TypeScript.
TypeScript
5
star
71

piccata

Python CoAp Toolkit
Python
4
star
72

npmx-zephyr

npmx integration with Zephyr
C
4
star
73

pc-nrfconnect-tracecollector

Trace collector tool for nRF Connect for Desktop
JavaScript
4
star
74

microbit-v2-pager

C
4
star
75

cell-geolocation-helpers-js

Helper functions for the cell geolocation feature
TypeScript
4
star
76

nrf-device-lister-js

List usb, serialport and jlink devices
JavaScript
4
star
77

svada

SVD Parsing for Python
Python
3
star
78

asset-tracker-cloud-device-ui-js

Provides a user interface via a web application to interact with a simulated device for the nRF Asset Tracker.
TypeScript
3
star
79

cloud-azure-firmware-ci-runner-js

Runs firmware on a real device connected to Azure IoT hub.
TypeScript
3
star
80

at_host-hex

Compiles the AT host sample for 9161DK, 9160DK, and Thingy:91 and publishes it regularly.
3
star
81

cloud-aws-package-layered-lambdas-js

Packages lambda functions and layers for AWS lambda
TypeScript
3
star
82

NAT-TestServer

Receives NAT test messages from the NAT-TestFirmware and logs them and timeout occurances to S3
TypeScript
3
star
83

asset-tracker-cloud-firmware-azure

nRF Asset Tracker for Azure firmware.
C
3
star
84

Android-nRF-Edge-Impulse

Connect to a Thing:53, collect sensor data over Bluetooth Low Energy and create your machine learning applications.
Kotlin
3
star
85

nrfprogrammer-firmware-images

Provides a list of pre-compiled firmware images for nRF Programmer in the GitHub pages website for this repository.
TypeScript
3
star
86

npmx

Standalone drivers for Nordic PMICs
C
3
star
87

NFC-Connect

Kotlin
2
star
88

pmic-npm6001-lib

C
2
star
89

cloud-e2e-bdd-test-runner-js

Implementation of a test-runner for end-to-end tests of cloud-native applications using Gherkin features.
TypeScript
2
star
90

IOS-CoreBluetooth-Mock-Example

Sample app demonstrating migration to CoreBluetoothMock framework.
Swift
2
star
91

pc-nrfconnect-npm

TypeScript
2
star
92

cloud-device-helpers-js

Helper functions for interacting with the nRF9160 used during end-to-end tests
TypeScript
2
star
93

asset-tracker-cloud-code-style-js

Code style definitions for all nRF Asset Tracker projects.
JavaScript
1
star
94

asset-tracker-cloud-app-aws-js

The nRF Asset Tracker Web Application for AWS is a reference single-page application (SPA) developed using TypeScript.
TypeScript
1
star
95

nrfcloud-location-services-tests-js

Verifies the nRF Cloud Location Services REST API.
TypeScript
1
star
96

cloud-azure-firmware-ci-feature-runner-action

Uses @nordicsemiconductor/e2e-bdd-test-runner to run features files of a firmware.
JavaScript
1
star
97

cloud-e2e-bdd-test-runner-example-js

Example use of @nordicsemiconductor/e2e-bdd-test-runner
TypeScript
1
star
98

cloud-aws-firmware-ci-feature-runner-action

Uses @nordicsemiconductor/e2e-bdd-test-runner to run features files of a firmware.
JavaScript
1
star
99

lwm2m-types-js

TypeScript type definitions and JSON schema for the objects defined in the LwM2M Object Registry.
TypeScript
1
star
100

asset-tracker-cloud-memfault-azure-js

Memfault integration for Azure IoT Hub developed in TypeScript.
TypeScript
1
star