web-dev-qa-db-ja.com

ScanSettings.SCAN_MODE_OPPORTUNISTICを使用した「アプリのスキャン頻度が高すぎる」

Samsung S8で問題に気づいた、Android 7.0(pd。これはAndroid 7.0:Samsung 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!");
});
_

RecorderScanCallbackScanCallbackから派生しています。 _RxAndroidBle#rxBleClient.scanBleSettings_(ScanSettings)を使用することはできません。コードがフリーズしようとしており、1.1.0バージョンのlibを使用しているためです。

_ScanSettings.setScanMode_が検索結果を変更しないのはなぜですか?

41

Android 7は、30秒間に5回を超えるスキャンの開始と停止を防ぎます。悪い面は、エラーを返さず、代わりにログを出力するだけです。アプリはスキャンが開始されたと見なしますが、実際にはbleスタックからは開始されていません。また、不正なアプリを防ぐ目的で、長時間実行されているスキャンを日和見スキャンに変換します。長時間のスキャンの場合、所要時間は30分です。

これらの変更は文書化されておらず、この投稿で言及されています: https://blog.classycode.com/undocumented-Android-7-ble-behavior-changes-d1a9bd87d98

3
Safa Kadir