我正在开发一个使用蓝牙低功耗的Android应用程序。我使用了类BluetoothAdapter
但现在在API-21中,类是BluetoothLeScanner
我的旧代码实现了接口BluetoothAdapter.LeScanCallback我现在必须实现什么接口?或者我可以做另一种解决方案吗?
我们不推荐使用stopLeScan
和startLeScan
这两种方法,这就是为什么我要使用类BluetoothLeScanner
,而是让方法启动和停止。
这是我班级的代码:
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);
}
}
}
答案 0 :(得分:3)
在5.0上有可用的apis,在较低版本上缺少。我建议使用目标sdk 22(最新版)构建应用程序。 i)使用不同的apis在不同版本中获得相同的结果。就像手机运行低于Android 5.0一样,使用startScan,否则使用startLEScan。 ii)Android 5.0和5.1也有差异,因此请相应地使用这些方法。像startScan这样的apis已被弃用,但我知道,他们仍然在工作,因为他们已经将它们与新api绑在一起了。所以在他们删除旧的api之前,他们将在所有平台上工作。这正是弃用意味着:)
因此,您可以根据SDK版本调用相应的api。您可以通过android.os.Build.VERSION.SDK_INT在运行时获得SDK版本,所以尝试这样做:
if(android.os.Build.VERSION.SDK_INT<21)
bluetoothAdapter.startLeScan(this);
else{
bluetoothLeScanner.startScan(callBack);
}
答案 1 :(得分:2)
Android documenation描述了使用新的BluetoothAdapter
startScan()
方法:
public void startScan (List<ScanFilter> filters, ScanSettings settings, ScanCallback callback)
您可以为API级别21及更高版本创建BleDevicesScannerV21
课程,该课程使用ScanCallback
代替BluetoothAdapter.LeScanCallback
。