abe*_*fox 20 rssi bluetooth-lowenergy ibeacon-android android-ibeacon android-5.0-lollipop
精简版:
在我使用Android 5.0 Lollipop的测试中,我注意到android.bluetooth.le.BluetoothLeScanner检测BLE设备的频率低于Android 4.4 KitKat.为什么这样,还有其他选择吗?
长版:
我正在开发一款Android应用程序,专门用于Nexus 7平板电脑,专注于检测蓝牙低功耗(BLE)设备.该应用程序主要感兴趣的是信标的RSSI值,以确定它们与平板电脑的接近程度.这意味着我不需要连接到BLE设备,因为在检测到设备时RSSI值会传递给扫描回调.
在Android 4.4 KitKat中,当我调用时BluetoothAdapter.startLeScan(LeScanCallback),对于每个检测到的BLE设备,我的回调仅被调用ONCE.(我已经看到一些讨论声称每个设备的行为可能不同)但是,我对不断变化的RSSI值感兴趣,所以目前推荐的方法是以设定的间隔(在我的情况下为250ms)连续执行startLeScan和stopLeScan:
public class TheOldWay {
private static final int SCAN_INTERVAL_MS = 250;
private Handler scanHandler = new Handler();
private boolean isScanning = false;
public void beginScanning() {
scanHandler.post(scanRunnable);
}
private Runnable scanRunnable = new Runnable() {
@Override
public void run() {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (isScanning) {
adapter.stopLeScan(leScanCallback);
} else if (!adapter.startLeScan(leScanCallback)) {
// an error occurred during startLeScan
}
isScanning = !isScanning;
scanHandler.postDelayed(this, SCAN_INTERVAL_MS);
}
};
private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
// use the RSSI value
}
};
}
Run Code Online (Sandbox Code Playgroud)
基本上这给了我所需的结果,但这个过程是非常耗费资源的,最终会导致无响应的蓝牙适配器.
出于这些原因,我将Nexus 7升级到Android 5.0 Lollipop,看看我的BLE问题是否会得到解决.在棒棒糖BluetoothAdapter.startLeScan(LeScanCallback)已过时,与更换一个新的API,允许用于在扫描过程中的一些更多的控制.从我的第一次测试开始,当RSSI值发生变化时,似乎startScan没有连续调用我的回调(在我的Nexus 7上),所以我仍然需要使用startScan/stopScan实现:
@TargetApi(21)
public class TheNewWay {
private static final int SCAN_INTERVAL_MS = 250;
private Handler scanHandler = new Handler();
private List<ScanFilter> scanFilters = new ArrayList<ScanFilter>();
private ScanSettings scanSettings;
private boolean isScanning = false;
public void beginScanning() {
ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder();
scanSettingsBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
scanSettings = scanSettingsBuilder.build();
scanHandler.post(scanRunnable);
}
private Runnable scanRunnable = new Runnable() {
@Override
public void run() {
BluetoothLeScanner scanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();
if (isScanning) {
scanner.stopScan(scanCallback);
} else {
scanner.startScan(scanFilters, scanSettings, scanCallback);
}
isScanning = !isScanning;
scanHandler.postDelayed(this, SCAN_INTERVAL_MS);
}
};
private ScanCallback scanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
int rssi = result.getRssi();
// do something with RSSI value
}
@Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
// a scan error occurred
}
};
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我已使用ScanSettings类配置扫描程序,该类允许您设置scanMode.我使用ScanSettings.SCAN_MODE_LOW_LATENCY,它有以下文档:"使用最高占空比扫描.建议仅在应用程序在前台运行时使用此模式." 听起来完全像我想要的,但不幸的是我只得到一个信标探测每隔15 - 30秒,其中奇巧版本显示我的每1相同的信标-第2秒,这个扫描间隔.
你知道这种差异的原因是什么?我错过了什么,也许是一些新的设置?有其他方法可以做到吗?
非常感谢提前!
阿贝尔
PS:我想要包含更多我已经使用的资源的链接,但我还没有它的重复点.
使用运行新的Android 5.0扫描API的Nexus 5,我得到了非常不同的结果.当使用SCAN_MODE_LOW_LATENCY时,BLE数据包的检测几乎实时进入,每100ms用于以10Hz发送的BLE信标.
您可以在此处阅读完整结果:
http://developer.radiusnetworks.com/2014/10/28/android-5.0-scanning.html
这些测试都基于运行开源的Android灯塔图书馆2.0的实验机器人-1- API的分支在这里.
测试结果的差异并不明显,但启动和停止扫描可能会改变结果.
编辑:可能硬件是不同的.在Nexus 4上查看类似时间的报告:https://github.com/AltBeacon/android-beacon-library/issues/59#issuecomment-64281446
我还没有50条评论的声誉,所以请耐心等待,这条评论将以答案的形式出现.在你的代码中,不应该这部分:
if (isScanning) {
scanner.startScan(...)
相反:
if (!isScanning) {
scanner.startScan(...)
Run Code Online (Sandbox Code Playgroud)
因为遵循您的代码,您在开始扫描之前调用stopScan().如果stopScan()方法是幂等/安全的,它可能不会对结果产生直接影响.但是你知道,为了代码的可懂度,你应该编辑这个问题.并对你的代码做同样的事情,有时拜占庭式的东西正在发挥作用;)
您是否为SCAN_INTERVAL_MS尝试了更大的值?如果是的话,有多大?
| 归档时间: |
|
| 查看次数: |
19913 次 |
| 最近记录: |