我正在构建一个Android应用程序,当用户进入或离开用户可以定义的"蓝牙区域"时,它应该在后台中启动操作。就像Google的Geofencing一样。
我在这里已经阅读了很多内容并对代码进行了调整,我的想法是,它必须是。
"蓝牙区"用户通过扫描蓝牙设备,选择设备并为其添加半径来配置。这按预期工作。 这个"蓝牙区"然后由BeaconManager持久化并作为自己活动中的区域进行测距:
BeaconManager mBeaconManager = BeaconManager.getInstanceForApplication(this);
Region singleBeaconRegion = new Region(mRegion.getText().toString(), listB);
try {
mBeaconManager.startRangingBeaconsInRegion(singleBeaconRegion);
} catch (RemoteException e) { }
我还有一个应用程序,如下所示:
public class BtZoneApplication extends Application implements BootstrapNotifier, RangeNotifier{
private static final String TAG = "BeaconReferenceAppl";
private BeaconManager mBeaconManager;
private Region mAllBeaconsRegion;
private BackgroundPowerSaver mBackgroundPowerSaver;
private RegionBootstrap mRegionBootstrap;
private Worker worker;
private final static String ALLBEACONSREGION = "##AllBeaconsRegion##";
DbServerHelper datasourceServer;
DbZoneHelper datasource;
@Override
public void onCreate() {
mAllBeaconsRegion = new Region(ALLBEACONSREGION, null, null, null);
mBeaconManager = BeaconManager.getInstanceForApplication(this);
mBackgroundPowerSaver = new BackgroundPowerSaver(this);
mBeaconManager.setBackgroundBetweenScanPeriod(30000L);
mBeaconManager.setBackgroundScanPeriod(2100L);
// wake up the app when a beacon is seen
mRegionBootstrap = new RegionBootstrap(this, mAllBeaconsRegion);
mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
}
@Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
// Start actions
if (region.getUniqueId().equals(ALLBEACONSREGION)){
return;
}
if (beacons.size() > 0) {
for (Beacon beacon: beacons) {
Log.d(TAG, "Beacon "+beacon.toString() + " is about " + beacon.getDistance() + " meters away, with Rssi: " + beacon.getRssi());
//
if (beacon.getDistance() < radius && !status) {
// set status to true
// start action at entering zone
}
// radius * 2 for testing
if (beacon.getDistance() > radius * 2 && status) {
// set status to false
// start action at exiting zone
}
}
}
}
@Override
public void didDetermineStateForRegion(int arg0, Region arg1) {
// do nothing
}
@Override
public void didEnterRegion(Region region) {
Log.d(TAG, "entered region. starting ranging");
setRegionsAtBoot();
mBeaconManager.setRangeNotifier(this);
}
@Override
public void didExitRegion(Region region) {
// do nothing. Ranging should work further
}
// Set regions to monitor at boot/startup
private void setRegionsAtBoot(){
...
for (Iterator<SimpleBeacon> iterator = beacons.iterator(); iterator.hasNext();) {
...
try {
mBeaconManager.startRangingBeaconsInRegion(new Region(simpleBeacon.getId(), listB));
} catch (RemoteException e) {
}
}
}
我的问题是,它不会在应用程序启动时开始,尽管BluetoothLeScanner会看到该设备。然后有时突然开始。这是一种奇怪的行为。
当它运行时,会多次报告进入/退出,即使设备没有移动,通常也不会在后台报告进入/退出(时间?)。 我想念一下吗?
答案 0 :(得分:1)
Application
代码中的几个问题:
使用BeaconConsumer
时无需实施bind
或明确调用RegionBootstrap
,因为绑定会在RegionBootstrap
内自动生成。
我会将通话移至setRegionsAtBoot
至didEnterRegion
。
为什么你所描述的症状会发生并不完全清楚,但上述可能是贡献者。
您也可以使用Locate Beacon等现成的扫描仪来确保您的信标可以可靠地进行测距。这有助于消除硬件问题。
最后,首先让它在前台工作,然后专注于后台操作。