我正在研究Android手机中BLE Beacons的距离估算。我已经开发了自己的基于RSSI的距离估计算法。 (我将很快以库的形式推出距离计算算法)。对于计算,电话需要来自信标周围的大量广告包。
到目前为止,我已经使用BLE扫描的常规做法测试了代码。截至目前,我已经编写了目标API级别19的代码。以下是我正在处理的代码的一部分,我开始扫描信标并在10秒后停止它。
private void scanLeDevice(final boolean enable) {
if (enable) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
bluetoothAdapter.stopLeScan(LEScanCallback);
}
}, 10000L);
bluetoothAdapter.startLeScan(LEScanCallback);
}
}
private BluetoothAdapter.LeScanCallback LEScanCallback =
new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice bluetoothDevice, int rssi, byte[] scanRecord){
display(rssi);
//append to an arrayList for further processing
}
};
目前我正在做UI线程上的大部分工作。我必须通过创建更多线程以下列方式实现功能。
我在Grepcode上看到了BluetoothAdapter.LeScanCallback的实现 我有以下问题。
答案 0 :(得分:1)
是的, Android蓝牙扫描回调总是在主线程上进行。 4.x API和5+ API都是如此。如果您正在使用回调中的信息进行重要处理,那么将其传递给您描述的其他线程是明智的。如果你不这样做,应用程序UI将变得迟钝,蓝牙处理甚至可能会备份,你会在日志中看到错误。
我不相信这在任何地方都有正式记录,但多年使用这些回调的经验总是表明这是真的。无法配置扫描,因此回调发生在不同的线程上。最佳做法是简单地调用另一个线程来执行处理并快速退出回调。
这是Android Beacon Library中显示的内容here.注意,回调的主体只使用AsyncTask
并在后台线程上执行此行:
new ScanProcessor(...).executeOnExecutor(mExecutor,
new ScanData(device, rssi, scanRecord));
此外,重要的是要注意虽然没有理由停止在较新的Android设备上扫描,但在某些旧设备上,如果信标广告是可连接的,则每个唯一的信标mac地址只能获得一次回调。在这些设备上解决此问题的唯一方法是停止并重新启动扫描以获得额外的回调。
祝你的距离算法好运 - 如果你有好的结果,并且有兴趣分享Android Beacon Library,我很乐意讨论。