【问题标题】:'App is scanning too frequently' with ScanSettings.SCAN_MODE_OPPORTUNISTIC使用 ScanSettings.SCAN_MODE_OPPORTUNISTIC '应用程序扫描太频繁'
【发布时间】:2018-01-22 17:12:14
【问题描述】:

我注意到三星 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

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

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

即使我设置了:ScanSettings.setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC),我也没有在 30 秒内完成 6 次扫描。

代码是:

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!");
});

RecorderScanCallback 派生自 ScanCallback。 我们不能使用RxAndroidBle#rxBleClient.scanBleSettings(ScanSettings),因为我们的代码即将冻结,我们使用的是 1.1.0 版本的库。

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

【问题讨论】:

  • 似乎每 30 秒最多 6 次扫描的限制也适用于机会性扫描,至少通过检查android.googlesource.com/platform/packages/apps/Bluetooth/+/… 的源代码。
  • 是的,我认为你是对的,但据我了解,在使用机会扫描时,我们只会被动地监听系统更改,而不像文档中所说的那样开始自己扫描 (developer.android.com/reference/android/bluetooth/le/…)。为什么开始扫描?
  • 你多久调用一次 bluetoothAdapter.getBluetoothLeScanner().startScan(filters, scanSettings, recoderScanCallback); ?
  • @DigitalNinja 在测试期间没有运行其他扫描应用程序。唯一的其他应用程序可能是系统,但我仍然不同意这种行为就是这种情况。测试条件为:一部手机,一部BT设备。房间内没有其他开启bt的手机,房间内没有其他开启bt的设备。在几次正确的连接(少于 5 个,通常是 2-3 个)之后,就会发生这种行为。
  • @DigitalNinja,您将如何“依赖其他应用程序开始扫描”而不在您的应用程序中调用 startScan?同样,在文档中(强调我的):一种特殊的蓝牙 LE 扫描模式。使用此扫描模式的应用程序将被动地侦听其他扫描结果本身不会启动 BLE 扫描。

标签: android bluetooth-lowenergy android-bluetooth android-7.0-nougat samsung-galaxy


【解决方案1】:

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

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

【讨论】:

  • 是否有可能在应用程序中捕获此事件(第 6 次扫描开始或停止)?我只能想出手动计算扫描开始/停止的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多