当前位置:  开发笔记 > Android > 正文

Android蓝牙低功耗代码兼容API> = 21 AND API <21

如何解决《Android蓝牙低功耗代码兼容API>=21ANDAPI<21》经验,为你挑选了1个好方法。

我正在开发一个必须与BLE设备连接的应用程序,在我的代码中,我想使用从API 21(Android 5)实现的新的Scan和ScanCallback for BLE,但我必须保持与Android 4.3及更高版本的兼容性.

所以我用这种方式编写了代码:

        if (Build.VERSION.SDK_INT >= 21) {
            mLEScanner.startScan(filters, settings, mScanCallback);
        } else {
            btAdapter.startLeScan(leScanCallback);
        }

我已经定义了2个回调,一个用于API 21及更高版本,另一个用于API 18到20:

    //API 21
private ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
              BluetoothDevice btDevice = result.getDevice();
              connectToDevice(btDevice);
         }
         public void connectToDevice(BluetoothDevice device) {
              if (mGatt == null) {
                   mGatt = device.connectGatt(context, false, btleGattCallback);
                   if (Build.VERSION.SDK_INT < 21) {
                        btAdapter.stopLeScan(leScanCallback);
                   } else {
                        mLEScanner.stopScan(mScanCallback);
                   }
               }
         }
    };


//API 18 to 20
        private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) {

        btAdapter.stopLeScan(leScanCallback);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mBluetoothGatt = device.connectGatt(context, false, btleGattCallback);
            }
        });


    }
};

我还添加了注释

@TargetApi(21)

但是当我在Android 4.x上启动应用程序时,它立即崩溃,报告无法找到类ScanCallback的错误(仅用于Android 5及更高版本的那个).

我怎么解决这个问题?

非常感谢你.丹尼尔.



1> Pedro Varela..:

看完几篇文章后,我做了以下几点.以防万一,这是关于BluetoothLe的Android文档

第一

创建两个方法之一scanLeDevice21scanLeDevice18.在scanLeDevice21添加注释时@RequiresApi(21)说:

表示只应在给定API级别或更高级别上调用带注释的元素.这与旧的@TargetApi注释类似,但更清楚地表明这是调用者的要求,而不是用于在方法中"抑制"超过minSdkVersion的警告.

第二

实现每个方法,这是我的代码.

@RequiresApi(21)
private void scanLeDevice21(final boolean enable) {

    ScanCallback mLeScanCallback = new ScanCallback() {

        @Override
        public void onScanResult(int callbackType, ScanResult result) {

            super.onScanResult(callbackType, result);

            BluetoothDevice bluetoothDevice = result.getDevice();

            if (!bluetoothDeviceList.contains(bluetoothDevice)) {
                Log.d("DEVICE", bluetoothDevice.getName() + "[" + bluetoothDevice.getAddress() + "]");
                bluetoothDeviceArrayAdapter.add(bluetoothDevice);
                bluetoothDeviceArrayAdapter.notifyDataSetChanged();
            }
        }

        @Override
        public void onBatchScanResults(List results) {
            super.onBatchScanResults(results);

        }

        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
        }
    };

    final BluetoothLeScanner bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();

    if (enable) {
        // Stops scanning after a pre-defined scan period.
        mHandler.postDelayed(() -> {
            mScanning = false;
            swipeRefreshLayout.setRefreshing(false);
            bluetoothLeScanner.stopScan(mLeScanCallback);
        }, SCAN_PERIOD);

        mScanning = true;
        bluetoothLeScanner.startScan(mLeScanCallback);
    } else {
        mScanning = false;
        bluetoothLeScanner.stopScan(mLeScanCallback);
    }
}


 /**
 * Scan BLE devices on Android API 18 to 20
 *
 * @param enable Enable scan
 */
private void scanLeDevice18(boolean enable) {

    BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {
                @Override
                public void onLeScan(final BluetoothDevice bluetoothDevice, int rssi,
                                     byte[] scanRecord) {
                    getActivity().runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            bluetoothDeviceArrayAdapter.add(bluetoothDevice);
                            bluetoothDeviceArrayAdapter.notifyDataSetChanged();
                        }
                    });
                }
            };
    if (enable) {
        // Stops scanning after a pre-defined scan period.
        mHandler.postDelayed(() -> {
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
        }, SCAN_PERIOD);

        mScanning = true;
        mBluetoothAdapter.startLeScan(mLeScanCallback);
    } else {
        mScanning = false;
        mBluetoothAdapter.stopLeScan(mLeScanCallback);
    }

}

第三

每当您需要扫描设备时,您都会围绕代码询问您的版本.例如,我有一个RefreshLayout显示设备列表.这是结果:

  /**
 * Refresh listener
 */
private void refreshScan() {
    if (!hasFineLocationPermissions()) {
        swipeRefreshLayout.setRefreshing(false);


        //Up to marshmallow you need location permissions to scan bluetooth devices, this method is not here since is up to you to implement it and it is out of scope of this question. 
        requestFineLocationPermission();

    } else {
        swipeRefreshLayout.setRefreshing(true);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            scanLeDevice21(true);
        } else {
            scanLeDevice18(true);
        }
    }
}

就是这样.

忘记扩展,子类化你并不真正需要的类,如ulusoyca的答案.

推荐阅读
家具销售_903
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有