To find BLE devices, you use the
startScan()
method. This method takes a
ScanCallback as a parameter.
You must implement this callback, because that is how scan results are returned.
Because scanning is battery-intensive, you should observe the following
guidelines:
- As soon as you find the desired device, stop scanning.
- Never scan on a loop, and always set a time limit on your scan. A device that was previously available may have moved out of range, and continuing to scan drains the battery.
In the following example, the BLE app provides an activity
(DeviceScanActivity) to scan for available Bluetooth LE devices and display
them in a list to the user. The following snippet shows how to start and stop a
scan:
Kotlin
private val bluetoothLeScanner = bluetoothAdapter.bluetoothLeScanner private var scanning = false private val handler = Handler() // Stops scanning after 10 seconds. private val SCAN_PERIOD: Long = 10000 private fun scanLeDevice() { if (!scanning) { // Stops scanning after a pre-defined scan period. handler.postDelayed({ scanning = false bluetoothLeScanner.stopScan(leScanCallback) }, SCAN_PERIOD) scanning = true bluetoothLeScanner.startScan(leScanCallback) } else { scanning = false bluetoothLeScanner.stopScan(leScanCallback) } }
Java
private BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner(); private boolean scanning; private Handler handler = new Handler(); // Stops scanning after 10 seconds. private static final long SCAN_PERIOD = 10000; private void scanLeDevice() { if (!scanning) { // Stops scanning after a predefined scan period. handler.postDelayed(new Runnable() { @Override public void run() { scanning = false; bluetoothLeScanner.stopScan(leScanCallback); } }, SCAN_PERIOD); scanning = true; bluetoothLeScanner.startScan(leScanCallback); } else { scanning = false; bluetoothLeScanner.stopScan(leScanCallback); } }
To scan for only specific types of peripherals, you can instead call
startScan(List<ScanFilter>, ScanSettings, ScanCallback),
providing a list of ScanFilter
objects that restrict the devices that the scan looks for and a
ScanSettings object that
specifies parameters about the scan.
The following code sample is an implementation of
ScanCallback,
which is the interface used to deliver BLE scan results. When results are found,
they are added to a list adapter in the DeviceScanActivity to display to the
user.
Kotlin
private val leDeviceListAdapter = LeDeviceListAdapter() // Device scan callback. private val leScanCallback: ScanCallback = object : ScanCallback() { override fun onScanResult(callbackType: Int, result: ScanResult) { super.onScanResult(callbackType, result) leDeviceListAdapter.addDevice(result.device) leDeviceListAdapter.notifyDataSetChanged() } }
Java
private LeDeviceListAdapter leDeviceListAdapter = new LeDeviceListAdapter(); // Device scan callback. private ScanCallback leScanCallback = new ScanCallback() { @Override public void onScanResult(int callbackType, ScanResult result) { super.onScanResult(callbackType, result); leDeviceListAdapter.addDevice(result.getDevice()); leDeviceListAdapter.notifyDataSetChanged(); } };