扫描信标不适用于 Android N 设备
Scan beacons not working with Android N device
我正在使用 Android N 设备(Moto G 5th gen)测试一个应用程序,它没有找到任何信标(beacons.size() == 0 总是),但是其他API 较低的设备工作正常...仅此设备失败。
我检查了 Google 在 Android N:
中添加的扫描限制
We’ve changed the BLE Scanning behavior starting in DP4. We’ll prevent
applications from starting and stopping scans more than 5 times in 30
seconds. For long running scans, we’ll convert them into opportunistic
scans.
这是代码:
public void startBeaconScan() {
Log.d(TAG, "App started up");
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout(iBeaconLayout));
long timeBetweenScans = 1100;
long timeScanPeriod = 500;
if(Build.VERSION.SDK_INT > 23){ //CHECK IF NOUGAT OR MORE
timeBetweenScans = 5000;
timeScanPeriod = 15000;
}
beaconManager.setForegroundBetweenScanPeriod(timeBetweenScans);
beaconManager.setForegroundScanPeriod(timeScanPeriod);
beaconManager.setBackgroundBetweenScanPeriod(timeBetweenScans);
beaconManager.setBackgroundScanPeriod(timeScanPeriod);
beaconManager.setRegionStatePeristenceEnabled(true);
region = new Region("myMonitoringUniqueId", Identifier.parse("2f234454-cf6d-4a0f-adf2-f4911ba9ffa6"), null, null);
new RegionBootstrap(this, region);
}
此函数是从 BootstrapNotifier 接口的应用程序的 didDetermineStateForRegion() 回调方法调用的。
知道我为什么会遇到这个问题吗?使用 Android N,我只用 Moto G 5th 测试过......但是对于其他设备(Android L,Android M......)代码工作正常。
-----更新-----
Logcat 应用程序启动:
06-01 15:51:05.183 12251-12251/? D/MyApplication: App started up
06-01 15:51:05.187 12251-12251/? D/BeaconParser: Parsing beacon layout: m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25
06-01 15:51:05.189 12251-12251/? D/BeaconParser: Parsing beacon layout: m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25
06-01 15:51:05.200 21464-4646/? I/PBSessionCacheImpl: Deleted sessionId[4000692901285] from persistence.
06-01 15:51:05.202 21464-4534/? V/ConnectivityManager: isActiveNetworkMetered() returns:false
06-01 15:51:05.207 21464-4534/? V/ConnectivityManager: isActiveNetworkMetered() returns:false
06-01 15:51:05.211 21464-21464/? W/SearchService: Abort, client detached.
06-01 15:51:05.216 21464-5529/? E/ContentStoreEUAS: Failed to commit the deferred actions
06-01 15:51:05.351 12251-12267/? D/NetworkSecurityConfig: No Network Security Config specified, using platform default
06-01 15:51:05.366 12251-12251/? W/BluetoothCrashResolver: Can't read macs from BluetoothCrashResolverState.txt
06-01 15:51:05.371 12251-12251/? W/ModelSpecificDistanceCalculator: Cannot find match for this device. Using default
06-01 15:51:05.371 12251-12251/? W/ModelSpecificDistanceCalculator: Cannot find match for this device. Using default
06-01 15:56:17.210 16969-16969/? D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
从 Android 开始,必须在设置中打开 Marshmallow (6.0) 位置才能检测蓝牙 LE 设备。这适用于蓝牙信标以及其他类型的蓝牙 LE 设备。 Google 进行此更改是因为扫描蓝牙 LE 设备可用于推断您的位置。同样的限制不适用于 6.0 之前的设备。
一种可能的解决方案是在 6.0+ 设备上 detect if location is off 并提示用户将其打开。
值得注意的是,如果您的应用以 SDK 23+ 为目标,则还必须获得 android.permission.ACCESS_FINE_LOCATION 或 android.permission.ACCESS_COARSE_LOCATION 的运行时权限。 See here for more info.
我正在使用 Android N 设备(Moto G 5th gen)测试一个应用程序,它没有找到任何信标(beacons.size() == 0 总是),但是其他API 较低的设备工作正常...仅此设备失败。
我检查了 Google 在 Android N:
中添加的扫描限制We’ve changed the BLE Scanning behavior starting in DP4. We’ll prevent applications from starting and stopping scans more than 5 times in 30 seconds. For long running scans, we’ll convert them into opportunistic scans.
这是代码:
public void startBeaconScan() {
Log.d(TAG, "App started up");
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout(iBeaconLayout));
long timeBetweenScans = 1100;
long timeScanPeriod = 500;
if(Build.VERSION.SDK_INT > 23){ //CHECK IF NOUGAT OR MORE
timeBetweenScans = 5000;
timeScanPeriod = 15000;
}
beaconManager.setForegroundBetweenScanPeriod(timeBetweenScans);
beaconManager.setForegroundScanPeriod(timeScanPeriod);
beaconManager.setBackgroundBetweenScanPeriod(timeBetweenScans);
beaconManager.setBackgroundScanPeriod(timeScanPeriod);
beaconManager.setRegionStatePeristenceEnabled(true);
region = new Region("myMonitoringUniqueId", Identifier.parse("2f234454-cf6d-4a0f-adf2-f4911ba9ffa6"), null, null);
new RegionBootstrap(this, region);
}
此函数是从 BootstrapNotifier 接口的应用程序的 didDetermineStateForRegion() 回调方法调用的。
知道我为什么会遇到这个问题吗?使用 Android N,我只用 Moto G 5th 测试过......但是对于其他设备(Android L,Android M......)代码工作正常。
-----更新-----
Logcat 应用程序启动:
06-01 15:51:05.183 12251-12251/? D/MyApplication: App started up
06-01 15:51:05.187 12251-12251/? D/BeaconParser: Parsing beacon layout: m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25
06-01 15:51:05.189 12251-12251/? D/BeaconParser: Parsing beacon layout: m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25
06-01 15:51:05.200 21464-4646/? I/PBSessionCacheImpl: Deleted sessionId[4000692901285] from persistence.
06-01 15:51:05.202 21464-4534/? V/ConnectivityManager: isActiveNetworkMetered() returns:false
06-01 15:51:05.207 21464-4534/? V/ConnectivityManager: isActiveNetworkMetered() returns:false
06-01 15:51:05.211 21464-21464/? W/SearchService: Abort, client detached.
06-01 15:51:05.216 21464-5529/? E/ContentStoreEUAS: Failed to commit the deferred actions
06-01 15:51:05.351 12251-12267/? D/NetworkSecurityConfig: No Network Security Config specified, using platform default
06-01 15:51:05.366 12251-12251/? W/BluetoothCrashResolver: Can't read macs from BluetoothCrashResolverState.txt
06-01 15:51:05.371 12251-12251/? W/ModelSpecificDistanceCalculator: Cannot find match for this device. Using default
06-01 15:51:05.371 12251-12251/? W/ModelSpecificDistanceCalculator: Cannot find match for this device. Using default
06-01 15:56:17.210 16969-16969/? D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
从 Android 开始,必须在设置中打开 Marshmallow (6.0) 位置才能检测蓝牙 LE 设备。这适用于蓝牙信标以及其他类型的蓝牙 LE 设备。 Google 进行此更改是因为扫描蓝牙 LE 设备可用于推断您的位置。同样的限制不适用于 6.0 之前的设备。
一种可能的解决方案是在 6.0+ 设备上 detect if location is off 并提示用户将其打开。
值得注意的是,如果您的应用以 SDK 23+ 为目标,则还必须获得 android.permission.ACCESS_FINE_LOCATION 或 android.permission.ACCESS_COARSE_LOCATION 的运行时权限。 See here for more info.