使用ScanSettings.SCAN_MODE_OPPORTUNISTIC,"应用程序扫描过于频繁"

Mar*_*ych 41 android bluetooth-lowenergy android-bluetooth samsung-galaxy android-7.0-nougat

我注意到三星S8,Android 7.0上的问题(更新.这也发生在Android 7.0上:三星S7,Nexus 5x),它告诉(经过几次测试)应用程序扫描过于频繁:

08-14 12:44:20.693 25329-25329/com.my.app D/BluetoothAdapter: startLeScan(): null
08-14 12:44:20.695 25329-25329/com.my.app D/BluetoothAdapter: STATE_ON
08-14 12:44:20.696 25329-25329/com.my.app D/BluetoothAdapter: STATE_ON
08-14 12:44:20.698 25329-25329/com.my.app D/BluetoothLeScanner: Start Scan
08-14 12:44:20.699 25329-25329/com.my.app D/BluetoothAdapter: STATE_ON
08-14 12:44:20.700 25329-25329/com.my.app D/BluetoothAdapter: STATE_ON
08-14 12:44:20.700 25329-25329/com.my.app D/BluetoothAdapter: STATE_ON
08-14 12:44:20.701 25329-25329/com.my.app D/BluetoothAdapter: STATE_ON
08-14 12:44:20.703 4079-4093/? D/BtGatt.GattService: registerClient() - UUID=dbaafee1-caf1-4482-9025-b712f000eeab
08-14 12:44:20.807 4079-4204/? D/BtGatt.GattService: onClientRegistered() - UUID=dbaafee1-caf1-4482-9025-b712f000eeab, clientIf=5, status=0
08-14 12:44:20.808 25329-25342/com.my.app D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=5 mClientIf=0
08-14 12:44:20.809 4079-7185/? D/BtGatt.GattService: start scan with filters
08-14 12:44:20.811 4079-7185/? D/BtGatt.GattService: getScanSettings 
08-14 12:44:20.812 4079-7185/? D/BtGatt.GattService: Is it foreground application = true
08-14 12:44:20.812 4079-7185/? D/BtGatt.GattService: not a background application
08-14 12:44:20.817 4079-7185/? E/BtGatt.GattService: App 'com.my.app' is scanning too frequently
Run Code Online (Sandbox Code Playgroud)

问题肯定在于那6个STATE_ON调用结果,它是未记录的BLE行为变化的一部分,在DP4发行说明中首次提到:

我们已经改变了从DP4开始的BLE扫描行为.我们将阻止应用程序在30秒内启动和停止扫描超过5次.对于长时间运行的扫描,我们会将它们转换为机会扫描.

即使我设置了:在不到30秒的时间内我还没有得到6次扫描: ScanSettings.setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC).

代码是:

List<ScanFilter> filters = new ArrayList<>();
ScanSettings scanSettings = new ScanSettings.Builder()
    .setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC)
    .build();
bluetoothAdapter.getBluetoothLeScanner().startScan(filters, scanSettings, recoderScanCallback);
//events from the log happen before this log is printed
Log.i("test", " started!");
return recoderScanCallback.scanResultObservable().map((ScanResult record) -> {
    //never gets here
    Log.i("test", " result!");
});
Run Code Online (Sandbox Code Playgroud)

RecorderScanCallback源于ScanCallback.我们不能使用RxAndroidBle#rxBleClient.scanBleSettings(ScanSettings),因为我们的代码即将冻结,我们使用1.1.0版本的lib.

为什么不ScanSettings.setScanMode改变搜索结果?

Saf*_*dir 8

Android 7 可防止扫描在 30 秒内启动-停止超过 5 次。不好的一面是,它不会返回错误,而只是打印日志。应用程序认为扫描已开始,但实际上并未从 ble 堆栈开始。此外,它还将长时间运行的扫描转换为机会扫描,以防止滥用应用程序。长时间运行扫描的持续时间为 30 分钟。

这些更改没有记录,在这篇文章中提到:https : //blog.classycode.com/undocumented-android-7-ble-behavior-changes-d1a9bd87d983