Android STARTESCAN在API21中被分解

Android STARTESCAN在API21中被分解,android,bluetooth-lowenergy,android-bluetooth,Android,Bluetooth Lowenergy,Android Bluetooth,我正在开发一个android应用程序,使用蓝牙低能耗。我使用了类BluetoothAdapter,但现在在API-21中,类是BluetoothLeScanner我的旧代码正在实现接口BluetoothAdapter.lescallback我现在必须实现什么接口?或者我能做的还有其他解决方案吗? 这两种方法stopLeScan和startedscan已被弃用,这就是为什么我想使用类BluetoothLeScanner它具有方法start和stop 这是我的班级代码: public class B

我正在开发一个android应用程序,使用蓝牙低能耗。我使用了类
BluetoothAdapter
,但现在在API-21中,类是
BluetoothLeScanner
我的旧代码正在实现接口BluetoothAdapter.lescallback我现在必须实现什么接口?或者我能做的还有其他解决方案吗? 这两种方法
stopLeScan
startedscan
已被弃用,这就是为什么我想使用类
BluetoothLeScanner
它具有方法start和stop

这是我的班级代码:

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);
        }
    }
}
公共类BleDeviceScanner实现可运行的BluetoothAdapter.LeScanCallback{
私有静态最终字符串标记=bleDeviceScanner.class.getSimpleName();
专用静态最终长默认扫描周期=500L;
公共静态最终长周期扫描一次=-1;
专用最终蓝牙适配器蓝牙适配器;
私有最终处理程序mainThreadHandler=新处理程序(Looper.getMainLooper());
私人决赛莱斯坎斯特莱斯坎斯特;
专用长扫描周期=默认扫描周期;
私有线程扫描线程;
私有易失性布尔isScanning=false;
公共BleeDeviceScanner(BluetoothAdapter、BluetoothAdapter.LeScanCallback回调){
if(适配器==null)
抛出新的IllegalArgumentException(“适配器不应为null”);
蓝牙适配器=适配器;
leScansPoster=新的leScansPoster(回调);
}
公共同步无效设置扫描周期(长扫描周期){
this.scanproid=scanproid<0?PERIOD\u SCAN\u一次:scanproid;
}
公共布尔isScanning(){
返回scanThread!=null&&scanThread.isAlive();
}
公共同步的void start(){
if(IsScaning())
返回;
如果(扫描线程!=null){
scanThread.interrupt();
}
扫描线程=新线程(此);
scanThread.setName(标记);
scanThread.start();
}
公共同步无效停止(){
isScanning=false;
如果(扫描线程!=null){
scanThread.interrupt();
scanThread=null;
}
bluetoothAdapter.stopLeScan(此);
}
@凌驾
公开募捐{
试一试{
IsScaning=真;
做{
已同步(此){
bluetoothAdapter.startescan(这个);
}
如果(扫描周期>0)
睡眠(扫描周期);
已同步(此){
bluetoothAdapter.stopLeScan(此);
}
}while(扫描和扫描周期>0);
}捕获(中断异常忽略){
}最后{
已同步(此){
bluetoothAdapter.stopLeScan(此);
}
}
}
@凌驾
public void onLeScan(蓝牙设备,int-rssi,字节[]扫描记录){
已同步(leScansPoster){
leScansPoster.set(设备、rssi、扫描记录);
mainThreadHandler.post(leScansPoster);
}
}
私有静态类LeScansPoster实现Runnable{
私有最终BluetoothAdapter.LeScanCallback LeScanCallback;
私人蓝牙设备;
私有内部rssi;
专用字节[]扫描记录;
私人LeScansPoster(BluetoothAdapter.LeScanCallback LeScanCallback){
this.leScanCallback=leScanCallback;
}
公共无效集(蓝牙设备,int-rssi,字节[]扫描记录){
这个装置=装置;
这是rssi=rssi;
this.scanRecord=scanRecord;
}
@凌驾
公开募捐{
仅扫描(设备、rssi、扫描记录);
}
}
}
描述了如何使用新的
BluetoothAdapter
startScan()
方法:

public void startScan (List<ScanFilter> filters, ScanSettings settings, ScanCallback callback)
public void startScan(列表过滤器、扫描设置、扫描回调)

您可以为API级别21及更高级别创建一个
BleDeviceScannerv21
类,该类使用
ScanCallback
而不是
BluetoothAdapter。LeScanCallback

我从
ScanCallback
扩展而来,但我如何使用它呢??我不能实例化它,因为它是一个抽象类,而且方法
startScan
startedscan
没有相同的签名