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 等现成的扫描仪来确保您的信标可以可靠地测距。这将有助于消除硬件问题。

最后,先让它在前台工作,然后专注于后台操作。