循环中的 BootstrapNotifier 回调
BootstrapNotifier callbacks in loop
我的信标检测有问题。
有时,应用程序会循环通过 BootstrapNotifier 回调 (didDetermineStateForRegion(int arg0, Region arg1)、didEnterRegion(Region arg0) 和 didExitRegion(Region arg0))。
有时在我启动应用程序时发生,其他时候是在应用程序处于后台时...我没有找到任何模式,因此我不知道问题出在哪里。
循环是这样的(只有一段日志):
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didEnterRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didExitRegion call: null
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didEnterRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didExitRegion call: null
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didEnterRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didExitRegion call: null
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didEnterRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didExitRegion call: null
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didEnterRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didExitRegion call: null
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didEnterRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
为什么会发生?该应用程序检测到该区域,但不会立即启动信标扫描。
此循环或多或少一分钟后,扫描通常开始(但并非总是如此)。
为了测试应用程序,我使用这个信标软件模拟器作为发射器 (https://github.com/WebBluetoothCG/ble-test-peripheral-android)
----------------更新------------
我的代码:
public class BeaconApplication extends Application implements BootstrapNotifier, BeaconConsumer {
private String TAG = "MyApplication";
private BeaconManager beaconManager;
private Region region;
@Override
public void onCreate() {
super.onCreate();
startBeaconScan();
}
public void startBeaconScan() {
Log.d(TAG, "App started up");
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25")); //iBeacon layout
beaconManager.setRegionStatePeristenceEnabled(false);
beaconManager.bind(this);
region = new Region("myMonitoringUniqueId", Identifier.parse("2f234454-cf6d-4a0f-adf2-f4911ba9ffa6"), null, null);
new RegionBootstrap(this, region);
}
@Override
public void didDetermineStateForRegion(int arg0, Region arg1) {
beaconManager.addRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
//CODE FOR BEACON DETECTION
}
});
try {
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
Log.d(TAG, "Got a didDetermineStateForRegion call: " + arg1.getId1());
}
@Override
public void didEnterRegion(Region arg0) {
Log.d(TAG, "Got a didEnterRegion call: " + arg0.getId1());
}
@Override
public void didExitRegion(Region arg0) {
Log.d(TAG, "Got a didExitRegion call: " + arg0.getBluetoothAddress());
}
@Override
public void onBeaconServiceConnect() {
try {
beaconManager.setBackgroundBetweenScanPeriod(500);
beaconManager.setBackgroundScanPeriod(500);
beaconManager.setForegroundBetweenScanPeriod(500);
beaconManager.setForegroundScanPeriod(500);
beaconManager.updateScanPeriods();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
我已经尝试在 "onBeaconServiceConnect()" 回调中使用 "beaconManager.startRangingBeaconsInRegion(region);",但似乎没有任何区别。
有两件事可能导致此问题:
设置如此短的扫描周期可能会有问题,除非您确定要测试的信标以 10Hz 或更高的频率传输。这是因为 500 毫秒不足以检测数据包,并且当您在扫描开启和关闭之间循环时,无线电会关闭一段时间。我会延长扫描周期(至少 1100 毫秒)以查看问题是否消失。
库版本 2.10 中引入了一个错误,该错误可能会导致区域在后台退出。我怀疑它能否解决如此短的扫描周期的问题。尝试定位库版本 2.9,或者您可以使用 instructions to try 2.11-beta1.
一些其他提示:
没有理由在使用RegionBootstrap时调用bind(),否则会导致后台模式切换出现问题。您可以将自定义扫描周期代码放在您设置 BeaconParser 的位置旁边,然后只需取出对 updateScanPeriods()
的调用,因为只有在扫描开始后更改扫描周期时才需要它。
除非您激活 BackgroundPowerSaver
class 或以编程方式更改 beaconManager 的后台模式,否则不会使用后台扫描周期。除非您执行其中一项操作,否则将始终使用前台扫描周期。
我的信标检测有问题。
有时,应用程序会循环通过 BootstrapNotifier 回调 (didDetermineStateForRegion(int arg0, Region arg1)、didEnterRegion(Region arg0) 和 didExitRegion(Region arg0))。
有时在我启动应用程序时发生,其他时候是在应用程序处于后台时...我没有找到任何模式,因此我不知道问题出在哪里。
循环是这样的(只有一段日志):
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didEnterRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didExitRegion call: null
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didEnterRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didExitRegion call: null
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didEnterRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didExitRegion call: null
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didEnterRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didExitRegion call: null
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didEnterRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didExitRegion call: null
D/MyApplication: Got a didDetermineStateForRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
D/MyApplication: Got a didEnterRegion call: 2f234454-cf6d-4a0f-adf2-f4911ba9ffa6
为什么会发生?该应用程序检测到该区域,但不会立即启动信标扫描。 此循环或多或少一分钟后,扫描通常开始(但并非总是如此)。
为了测试应用程序,我使用这个信标软件模拟器作为发射器 (https://github.com/WebBluetoothCG/ble-test-peripheral-android)
----------------更新------------
我的代码:
public class BeaconApplication extends Application implements BootstrapNotifier, BeaconConsumer {
private String TAG = "MyApplication";
private BeaconManager beaconManager;
private Region region;
@Override
public void onCreate() {
super.onCreate();
startBeaconScan();
}
public void startBeaconScan() {
Log.d(TAG, "App started up");
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25")); //iBeacon layout
beaconManager.setRegionStatePeristenceEnabled(false);
beaconManager.bind(this);
region = new Region("myMonitoringUniqueId", Identifier.parse("2f234454-cf6d-4a0f-adf2-f4911ba9ffa6"), null, null);
new RegionBootstrap(this, region);
}
@Override
public void didDetermineStateForRegion(int arg0, Region arg1) {
beaconManager.addRangeNotifier(new RangeNotifier() {
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
//CODE FOR BEACON DETECTION
}
});
try {
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
Log.d(TAG, "Got a didDetermineStateForRegion call: " + arg1.getId1());
}
@Override
public void didEnterRegion(Region arg0) {
Log.d(TAG, "Got a didEnterRegion call: " + arg0.getId1());
}
@Override
public void didExitRegion(Region arg0) {
Log.d(TAG, "Got a didExitRegion call: " + arg0.getBluetoothAddress());
}
@Override
public void onBeaconServiceConnect() {
try {
beaconManager.setBackgroundBetweenScanPeriod(500);
beaconManager.setBackgroundScanPeriod(500);
beaconManager.setForegroundBetweenScanPeriod(500);
beaconManager.setForegroundScanPeriod(500);
beaconManager.updateScanPeriods();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
我已经尝试在 "onBeaconServiceConnect()" 回调中使用 "beaconManager.startRangingBeaconsInRegion(region);",但似乎没有任何区别。
有两件事可能导致此问题:
设置如此短的扫描周期可能会有问题,除非您确定要测试的信标以 10Hz 或更高的频率传输。这是因为 500 毫秒不足以检测数据包,并且当您在扫描开启和关闭之间循环时,无线电会关闭一段时间。我会延长扫描周期(至少 1100 毫秒)以查看问题是否消失。
库版本 2.10 中引入了一个错误,该错误可能会导致区域在后台退出。我怀疑它能否解决如此短的扫描周期的问题。尝试定位库版本 2.9,或者您可以使用 instructions to try 2.11-beta1.
一些其他提示:
没有理由在使用RegionBootstrap时调用bind(),否则会导致后台模式切换出现问题。您可以将自定义扫描周期代码放在您设置 BeaconParser 的位置旁边,然后只需取出对
updateScanPeriods()
的调用,因为只有在扫描开始后更改扫描周期时才需要它。除非您激活
BackgroundPowerSaver
class 或以编程方式更改 beaconManager 的后台模式,否则不会使用后台扫描周期。除非您执行其中一项操作,否则将始终使用前台扫描周期。