StartLeScan is deactivated in API21
I am developing an android application using low energy bluetooth. i used the class BluetoothAdapter
, but now in API 21 class BluetoothLeScanner
my old code has implemented the bluetoothAdapter.LeScanCallback interface, which interface do i need to implement now? or is there another solution i can make? two methods stopLeScan
and startLeScan
deprecated, so I want to use a class BluetoothLeScanner
, it starts and stops methods instead.
this is my class code:
public class BleDevicesScanner implements Runnable, BluetoothAdapter.LeScanCallback {
private static final String TAG = BleDevicesScanner.class.getSimpleName();
private static final long DEFAULT_SCAN_PERIOD = 500L;
public static final long PERIOD_SCAN_ONCE = -1;
private final BluetoothAdapter bluetoothAdapter;
private final Handler mainThreadHandler = new Handler(Looper.getMainLooper());
private final LeScansPoster leScansPoster;
private long scanPeriod = DEFAULT_SCAN_PERIOD;
private Thread scanThread;
private volatile boolean isScanning = false;
public BleDevicesScanner(BluetoothAdapter adapter, BluetoothAdapter.LeScanCallback callback) {
if (adapter == null)
throw new IllegalArgumentException("Adapter should not be null");
bluetoothAdapter = adapter;
leScansPoster = new LeScansPoster(callback);
}
public synchronized void setScanPeriod(long scanPeriod) {
this.scanPeriod = scanPeriod < 0 ? PERIOD_SCAN_ONCE : scanPeriod;
}
public boolean isScanning() {
return scanThread != null && scanThread.isAlive();
}
public synchronized void start() {
if (isScanning())
return;
if (scanThread != null) {
scanThread.interrupt();
}
scanThread = new Thread(this);
scanThread.setName(TAG);
scanThread.start();
}
public synchronized void stop() {
isScanning = false;
if (scanThread != null) {
scanThread.interrupt();
scanThread = null;
}
bluetoothAdapter.stopLeScan(this);
}
@Override
public void run() {
try {
isScanning = true;
do {
synchronized (this) {
bluetoothAdapter.startLeScan(this);
}
if (scanPeriod > 0)
Thread.sleep(scanPeriod);
synchronized (this) {
bluetoothAdapter.stopLeScan(this);
}
} while (isScanning && scanPeriod > 0);
} catch (InterruptedException ignore) {
} finally {
synchronized (this) {
bluetoothAdapter.stopLeScan(this);
}
}
}
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
synchronized (leScansPoster) {
leScansPoster.set(device, rssi, scanRecord);
mainThreadHandler.post(leScansPoster);
}
}
private static class LeScansPoster implements Runnable {
private final BluetoothAdapter.LeScanCallback leScanCallback;
private BluetoothDevice device;
private int rssi;
private byte[] scanRecord;
private LeScansPoster(BluetoothAdapter.LeScanCallback leScanCallback) {
this.leScanCallback = leScanCallback;
}
public void set(BluetoothDevice device, int rssi, byte[] scanRecord) {
this.device = device;
this.rssi = rssi;
this.scanRecord = scanRecord;
}
@Override
public void run() {
leScanCallback.onLeScan(device, rssi, scanRecord);
}
}
}
source to share
there are apis available as of 5.0 that were missing in lower versions. I suggest building an app using target sdk 22 (latest). i) Use different apis to achieve the same results in different versions. For example, if the phone is running below Android 5.0 use startScan, otherwise startLEScan. ii) There are also differences in Android 5.0 and 5.1, so use these methods accordingly. Some apis like startScan are deprecated but I know they still work as they linked them to the new apis. so until they remove the old apis they will work on all platforms. This is what it means:
This way you can call the appropriate apis based on the SDK version. You can get the SDK version at runtime via android.os.Build.VERSION.SDK_INT, so try this:
if(android.os.Build.VERSION.SDK_INT<21)
bluetoothAdapter.startLeScan(this);
else{
bluetoothLeScanner.startScan(callBack);
}
source to share
The Android documenation describes a new method BluetoothAdapter
startScan()
:
public void startScan (List<ScanFilter> filters, ScanSettings settings, ScanCallback callback)
You can create a class BleDevicesScannerV21
for API level 21 and up that uses ScanCallback
instead BluetoothAdapter.LeScanCallback
.
source to share