我们正在开发一个通过设备名称输出数据的BLE设备。该设备的功能正常,可以使用像nRF Connect这样的应用程序正确更改名称。然而,在我们自己的Android应用程序中进行相同操作很困难。我们可以正常检测到这些设备,但它们几乎无法超越它们最初获得的名称。
我开始使用的代码在onResume()中启动了一个循环,使用BluetoothLeScanner和startScan()函数进行扫描。
然而,即使更新了名称,mLeScanCallback仍然只会返回原始名称。在这里进行一些搜索后,我发现要使用fetchUuidsWithSdp()函数以及像ACTION_FOUND、ACTION_UUID、ACTION_DISCOVERY_FINISHED和ACTION_NAME_CHANGED这样的意图才能正确地查看名称更改。因此,我将fetchUuidsWithSdp()添加到了mLeScanCallback中。然而,尽管这会触发Intents,但名称仍然没有更新。我尝试在实际意图中调用fetchUuidsWithSdp(),但这也没有帮助。奇怪的是,如果我关闭手机屏幕或足够远离BLE设备,ACTION_NAME_CHANGED偶尔会触发。但是,onPause()所做的只是调用
然而,尽管我的意图筛选器中包含它们,但是之前Intents已经被触发了,而现在却没有触发。在进行更多搜索后,我发现有些人说startDiscovery()不能用于Le设备。因此,我搜索了应该使用的替代方法...这让我回到了使用BluetoothLeScanner的startScan。那时,我意识到自己已经陷入了一个死循环,需要帮助。
我检查了整个过程,因为在某个地方我可能错过了什么。 我不知道我应该使用startScan()吗?我没有正确使用startDiscovery()吗?还是应该完全使用其他东西?ACTION_NAME_CHANGED偶尔被触发的事实让我想回到它,但是如何在设备处于唤醒状态时始终使其起作用呢?
我开始使用的代码在onResume()中启动了一个循环,使用BluetoothLeScanner和startScan()函数进行扫描。
public void BLEScan(final boolean enable){
final int SCAN_PERIOD = 12000;
final BluetoothLeScanner bluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
if (enable) {
Log.d(TAG, "Starting Scan");
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
BLEScan(false);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
bluetoothLeScanner.flushPendingScanResults(mLeScanCallback);
bluetoothLeScanner.startScan(mLeScanCallback);
} else {
Log.d(TAG, "Stopping Scan");
bluetoothLeScanner.flushPendingScanResults(mLeScanCallback);
bluetoothLeScanner.stopScan(mLeScanCallback);
mHandler.removeCallbacksAndMessages(null);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
BLEScan(true);
}
}, SCAN_PERIOD);
}
}
在mLeScanCallback中检测基于设备的过滤器。基本上,如果以前没有发现该设备,则将其添加到信标列表中。但是,如果以前有见过它,则使用信标的seen()函数更新值,并将信标名称视为已见过的位置,因为信息将从那里获取。在这两种情况下,它都会更新其适配器以填充新信息。
private ScanCallback mLeScanCallback =
new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
final ScanResult res2 = result;
runOnUiThread(new Runnable() {
@Override
public void run() {
BluetoothDevice device = res2.getDevice();
String address = device.getAddress();
if (device.getName() != null){
if (device.getName().contains("ABT:")){
if (!mLeBeacons.containsKey(address)){
BleBeacon beacon = new BleBeacon(device.getName(), address);
bleList.add(beacon);
adapter.notifyDataSetChanged();
mLeBeacons.put(device.getAddress(), beacon);
} else {
for (int x = 0; x < bleList.size(); x++){
if (device.getAddress().equals(bleList.get(x).getMAC())){
bleList.get(x).seen(device.getName());
adapter.notifyDataSetChanged();
}
}
}
}
}
}
});
}
};
然而,即使更新了名称,mLeScanCallback仍然只会返回原始名称。在这里进行一些搜索后,我发现要使用fetchUuidsWithSdp()函数以及像ACTION_FOUND、ACTION_UUID、ACTION_DISCOVERY_FINISHED和ACTION_NAME_CHANGED这样的意图才能正确地查看名称更改。因此,我将fetchUuidsWithSdp()添加到了mLeScanCallback中。然而,尽管这会触发Intents,但名称仍然没有更新。我尝试在实际意图中调用fetchUuidsWithSdp(),但这也没有帮助。奇怪的是,如果我关闭手机屏幕或足够远离BLE设备,ACTION_NAME_CHANGED偶尔会触发。但是,onPause()所做的只是调用
super.onPause()
和BLEScan(false)
。而且,由于这些都是我已经在循环中完成的事情,我不确定如何在代码处于唤醒状态时将其引入到我的代码中。经过更多搜索,我发现要使用fetchUuidsWithSdq()函数,您需要使用BluetoothAdapter的startDiscovery()函数。因此,我将BLEScan更改为使用它,并完全删除了mLeScanCallback。public void BLEScan(final boolean enable){
final int SCAN_PERIOD = 12000;
if (enable) {
Log.d(TAG, "Starting Scan");
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
BLEScan(false);
invalidateOptionsMenu();
}
}, SCAN_PERIOD);
if (mBluetoothAdapter.isDiscovering()){
mBluetoothAdapter.cancelDiscovery();
}
mBluetoothAdapter.startDiscovery();
} else {
Log.d(TAG, "Stopping Scan");
mBluetoothAdapter.cancelDiscovery();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
BLEScan(true);
}
}, SCAN_PERIOD);
}
}
然而,尽管我的意图筛选器中包含它们,但是之前Intents已经被触发了,而现在却没有触发。在进行更多搜索后,我发现有些人说startDiscovery()不能用于Le设备。因此,我搜索了应该使用的替代方法...这让我回到了使用BluetoothLeScanner的startScan。那时,我意识到自己已经陷入了一个死循环,需要帮助。
我检查了整个过程,因为在某个地方我可能错过了什么。 我不知道我应该使用startScan()吗?我没有正确使用startDiscovery()吗?还是应该完全使用其他东西?ACTION_NAME_CHANGED偶尔被触发的事实让我想回到它,但是如何在设备处于唤醒状态时始终使其起作用呢?