gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 11:05:17 26 4
gpt4 key购买 nike

我正在开发一个必须与 BLE 设备连接的应用程序,在我的代码中,我想使用从 API 21 (Android 5) 实现的 BLE 的新 Scan 和 ScanCallback,但我必须保持与 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 及更高版本)。

我该如何解决这个问题?

非常感谢。丹妮尔。

最佳答案

阅读几篇文章后,我做了以下事情。为了以防万一,这里有关于 BluetoothLe 的 Android 文档。

首先

创建两个方法 scanLeDevice21scanLeDevice18。在 scanLeDevice21 上添加注释 @RequiresApi(21) 说:

Denotes that the annotated element should only be called on the given API level or higher. This is similar in purpose to the older @TargetApi annotation, but more clearly expresses that this is a requirement on the caller, rather than being used to "suppress" warnings within the method that exceed the 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<ScanResult> 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 答案那样扩展、子类化您并不真正需要的类。

关于与 API>=21 AND API<21 兼容的 Android 低功耗蓝牙代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34447183/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com