AltBeacon:测距未按预期工作
AltBeacon: ranging not working as expected
我正在构建一个 Android 应用程序,当用户进入或离开 "bluetooth zone" 时,它应该在 后台启动操作 可以定义。就像来自 Google.
的地理围栏
这里看了很多,也改编了代码,我怎么想的,必须的。
"bluetooth zones" 由用户配置,通过扫描蓝牙设备,选择设备并为其添加半径。这按预期工作。
这个 "bluetooth zone" 然后由 BeaconManager 作为自己的 activity:
中的一个区域持久化和排列
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 检测到该设备,但它并没有在应用程序启动时开始测距。然后有时它突然开始。这是一种奇怪的行为。
当它运行时,entering/exiting 会被多次报告,即使设备没有移动,而且 entering/exiting 通常不会(及时?)在后台报告。
我错过了什么吗?
Application
代码中的几个问题:
在使用 RegionBootstrap
时,无需显式实现 BeaconConsumer
或调用 bind
,因为绑定会在 RegionBootstrap
内自动发生。
我会将 setRegionsAtBoot
的呼叫移至 didEnterRegion
。
目前还不完全清楚为什么会出现您描述的症状,但以上可能是原因之一。
您也可以使用 Locate Beacon 等现成的扫描仪来确保您的信标可以可靠地测距。这将有助于消除硬件问题。
最后,先让它在前台工作,然后专注于后台操作。
我正在构建一个 Android 应用程序,当用户进入或离开 "bluetooth zone" 时,它应该在 后台启动操作 可以定义。就像来自 Google.
的地理围栏这里看了很多,也改编了代码,我怎么想的,必须的。
"bluetooth zones" 由用户配置,通过扫描蓝牙设备,选择设备并为其添加半径。这按预期工作。 这个 "bluetooth zone" 然后由 BeaconManager 作为自己的 activity:
中的一个区域持久化和排列 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 检测到该设备,但它并没有在应用程序启动时开始测距。然后有时它突然开始。这是一种奇怪的行为。
当它运行时,entering/exiting 会被多次报告,即使设备没有移动,而且 entering/exiting 通常不会(及时?)在后台报告。 我错过了什么吗?
Application
代码中的几个问题:
在使用
RegionBootstrap
时,无需显式实现BeaconConsumer
或调用bind
,因为绑定会在RegionBootstrap
内自动发生。我会将
setRegionsAtBoot
的呼叫移至didEnterRegion
。
目前还不完全清楚为什么会出现您描述的症状,但以上可能是原因之一。
您也可以使用 Locate Beacon 等现成的扫描仪来确保您的信标可以可靠地测距。这将有助于消除硬件问题。
最后,先让它在前台工作,然后专注于后台操作。