bluetooth-lowenergy - 减少BLE startScan在Android 5.0 Lollipop上检测到的设备

标签 bluetooth-lowenergy android-5.0-lollipop rssi ibeacon-android android-ibeacon

简洁版本:

在Android 5.0 Lollipop的测试中,我注意到 android.bluetooth.le.BluetoothLeScanner 侦测BLE设备的频率低于Android 4.4 KitKat。为什么会这样,还有其他选择吗?

长版:

我正在开发一个专门用于Nexus 7平板电脑的Android应用程序,该应用程序专注于检测低功耗蓝牙(BLE)设备。该应用程序主要对信标的RSSI值感兴趣,以确定它们与平板电脑的接近程度。这意味着我不需要连接到BLE设备,因为在检测到设备时RSSI值将传递到扫描回调。

在Android 4.4 KitKat中,当我调用BluetoothAdapter.startLeScan(LeScanCallback)时,对于每个检测到的BLE设备,我的回调仅被调用一次。 (我见过some discussions声称每个设备的这种行为可能有所不同),但是,我对不断变化的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
        }
    };

}

从本质上讲,这给了我所需的结果,但是此过程非常耗费资源,并最终导致蓝牙适配器无响应。

由于这些原因,我将Nexus 7升级到了Android 5.0 Lollipop,以查看BLE问题是否会得到解决。在Lollipop中,BluetoothAdapter.startLeScan(LeScanCallback)已弃用,并替换为a new 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
        }
    };

}

如您所见,我已经使用ScanSettings类配置了扫描仪,该类允许您设置scanMode。我使用ScanSettings.SCAN_MODE_LOW_LATENCY,该文件具有以下文档:“使用最高占空比进行扫描。建议仅在应用程序在前台运行时才使用此模式。”听起来完全像我想要的,但是不幸的是,我每15到30秒只能检测到一个信标,而KitKat版本在此扫描间隔内每1-2秒钟就会向我显示相同的信标。

您是否知道造成这种差异的原因是什么?我是否缺少某些内容,也许有一些新设置?是否有其他方法可以做到以上几点?

在此先多谢!

亚伯

PS:我想包括更多我所使用资源的链接,但我现在还没有代表点。

最佳答案

使用运行新的Android 5.0扫描API的Nexus 5,我得到了截然不同的结果。使用SCAN_MODE_LOW_LATENCY时,BLE信标每10毫秒以100ms的速度几乎实时地检测到BLE数据包。

您可以在此处阅读完整结果:

http://developer.radiusnetworks.com/2014/10/28/android-5.0-scanning.html

这些测试基于运行开源Android Beacon Library 2.0的实验性android-l-apis分支here的基础。

测试结果有何不同尚不明显,但开始和停止扫描可能会改变结果。

编辑:可能是硬件有所不同。在Nexus 4上查看类似计时的报告:https://github.com/AltBeacon/android-beacon-library/issues/59#issuecomment-64281446

关于bluetooth-lowenergy - 减少BLE startScan在Android 5.0 Lollipop上检测到的设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27111309/

相关文章:

android - 如何在 Android 中获取手机服务信号强度?

android - 在不征求用户许可的情况下开启 Android LE 扫描

android - 动态 BLE 广告 Android

android - 蓝牙 Le Gatt 找不到任何设备

Android ParseQueryAdapter 分页与 RecyclerView.Adapter

bluetooth - 蓝牙 RSSI 中出现的规律振荡是否有解释?

android - 如何找到连接的蓝牙设备的信号强度

android - 如何通过蓝牙获取远程设备的序列号?

android - Lollipop : making my activity stay in the task that launched the share intent

java - Android 应用程序在 Lollipop 上崩溃