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();
}
};