信标库 - bootstrapNotifier:如果已经在一个区域中则没有回调

Beacon library - bootstrapNotifier: no callback if already in a region

我正在 Android

中编写一个简单的信标应用程序

如果在区域外启动它可以工作(这是我的自定义日志):

onCreate - In
onCreate - Out
onBeaconServiceConnect - In
onBeaconServiceConnect - Out
didDetermineStateForRegion (INSIDE)
didEnterRegion - In
dER - startRangingBeaconsInRegion OK
didEnterRegion - Out
didRangeBeaconsInRegion - 1 beacons
...... omitted .....
didRangeBeaconsInRegion - 0 beacons
didDetermineStateForRegion (OUTSIDE)
didExitRegion - In
dXR - stopRangingBeaconsInRegion OK
didExitRegion - Out
didRangeBeaconsInRegion - 0 beacons

如果在区域内启动,则不会调用 bootstrapNotifier(即 monitorNotifier)方法

谁能看出我哪里出错了?

package it.test.test01;

import android.app.Application;
import android.os.RemoteException;
import android.util.Log;

import org.altbeacon.beacon.Beacon;
import org.altbeacon.beacon.BeaconConsumer;
import org.altbeacon.beacon.BeaconManager;
import org.altbeacon.beacon.BeaconParser;
import org.altbeacon.beacon.MonitorNotifier;
import org.altbeacon.beacon.RangeNotifier;
import org.altbeacon.beacon.Region;
import org.altbeacon.beacon.powersave.BackgroundPowerSaver;
import org.altbeacon.beacon.startup.RegionBootstrap;
import org.altbeacon.beacon.startup.BootstrapNotifier;

import java.util.Collection;


public class testApplication extends Application
    implements BootstrapNotifier, BeaconConsumer, RangeNotifier {
    private final String TAG = "Application ";
    protected static final Region beaconRegion = new Region("test01", null, null, null);
    protected BeaconManager beaconManager = null;
    private RegionBootstrap regionBootstrap;
    private BackgroundPowerSaver backgroundPowerSaver;

    protected static String sLog = "";

    @Override
    public void onCreate() {
    super.onCreate();
    logIt(TAG, "onCreate - In");
    beaconManager = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(this);
    beaconManager.getBeaconParsers().clear();
    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 (tutti)
    //--- wake up the app when a beacon is seen
    regionBootstrap = new RegionBootstrap(this, beaconRegion);
    //--- activate power saver
    backgroundPowerSaver = new BackgroundPowerSaver(this);
    beaconManager.bind(this);
    logIt(TAG, "onCreate - Out");
    }

    private void logIt (String TAG, String msg) {
    sLog += TAG + msg + "\n";
    Log.w(TAG, msg);
    }

    //-------------------------//
    //--- BootstrapNotifier ---//
    //-------------------------//
    @Override
    public void didDetermineStateForRegion(int state, Region region) {
    String msg = "didDetermineStateForRegion ";
    switch(state) {
    case MonitorNotifier.INSIDE:
        msg +="(INSIDE)";
        break;
    case MonitorNotifier.OUTSIDE:
        msg +="(OUTSIDE)";
        break;
    default:
        msg +="(state=" +state +")";
        break;
    }
    logIt(TAG, msg);
    }

    @Override
    public void didEnterRegion(Region arg0) {
    logIt(TAG, "didEnterRegion - In");
    try {
        beaconManager.startRangingBeaconsInRegion(beaconRegion);
        logIt(TAG,"dER - startRangingBeaconsInRegion OK");
    } catch (RemoteException e) {
        logIt(TAG, "dER - startRangingBeaconsInRegion Err " +e);
    }
    logIt(TAG, "didEnterRegion - Out");
    }

    @Override
    public void didExitRegion(Region region) {
    logIt(TAG, "didExitRegion - In");
    try {
        beaconManager.stopRangingBeaconsInRegion(beaconRegion);
        logIt(TAG,"dXR - stopRangingBeaconsInRegion OK");
    } catch (RemoteException e) {
        logIt(TAG, "dXR - stopRangingBeaconsInRegion Err " +e);
    }
    logIt(TAG, "didExitRegion - Out");
    }

    //----------------------//
    //--- BeaconConsumer ---//
    //----------------------//
    @Override
    public void onBeaconServiceConnect() {
    logIt(TAG, "onBeaconServiceConnect - In");
    beaconManager.setRangeNotifier(this);
    logIt(TAG, "onBeaconServiceConnect - Out");
    }

    //---------------------//
    //--- RangeNotifier ---//
    //---------------------//

    @Override
    public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
    logIt(TAG, "didRangeBeaconsInRegion - " +beacons.size() +" beacons");
    }
}

如果应用程序启动时您已经在区域内,您将不会收到进入事件。这是设计使然。

编辑:库 2.9 有两个修改,使启动时更容易确定区域状态:

  1. 一旦应用程序开始监控,didDetermineStateForRegion 回调一定会被调用,告诉您区域的状态。 (除非实际发生变化,否则 didEnterRegiondidExitRegion 回调可能不会触发。)

  2. 如果你想禁用区域状态持久性,你可以使用 beaconManager.setRegionStatePeristenceEnabled(false); 这将保证在应用程序启动后第一次看到信标时回调到 didEnterRegion ,即使在应用重启前几秒可见信标。

如果您使用的是 2.9+,请不要按照以下说明操作,因为该解决方案已被弃用,将来可能无法使用。

如果您确实希望在每次应用程序启动时首次检测到一个额外的进入事件,您可以添加这行代码: MonitoringStatus.getInstanceForApplication(this).stopStatusPreservationOnProcessDestruction();

我们正致力于在下一版本中使此行为更易于配置。