为什么RangeBeaconsInRegion多次调用?

时间:2017-07-31 07:11:28

标签: ibeacon-android altbeacon

我在我的一个项目中使用Android Beacon Library(AltBeacon SDK)。我的要求是显示一些签到通知如果用户进入信标范围和结账通知如果退出信标范围但我面临的问题是我一直收到通知,即多次调用的didRangeBeaconsInRegion(收集信标,区域区域) 。当应用程序进入信标范围时,该功能是否应该只调用一次?

public class BeaconMonitoringService extends Service implements BootstrapNotifier, BeaconConsumer, RangeNotifier {



private static final String TAG = "BeaconMonitoringService";



private BeaconManager beaconManager;



@SuppressWarnings("unused")

private RegionBootstrap regionBootstrap;

@SuppressWarnings("unused")

private BackgroundPowerSaver backgroundPowerSaver;

private Region region;



@Override

public void onCreate() {

    super.onCreate();

    beaconSession = new BeaconSession(this);

    beaconManager = 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"));

    region = new Region("MyBeacon", Identifier.parse("0800200C9A66"), null, null);

    regionBootstrap = new RegionBootstrap(this, region);

    beaconManager.setBackgroundMode(true);

    backgroundPowerSaver = new BackgroundPowerSaver(this);

    beaconManager.bind(this);

}



@Override

public void didEnterRegion(Region region) {

    try {

        Log.d(TAG, "Did Enter Region.");

        beaconManager.startRangingBeaconsInRegion(region);

    } catch (RemoteException e) {

        if (BuildConfig.DEBUG) Log.d(TAG, "Can't start ranging");

    }

}



@Override

public void didExitRegion(Region region) {

    try {

        Log.d(TAG, "Did Exit Region");

    } catch (RemoteException e) {

        if (BuildConfig.DEBUG) Log.d(TAG, "Can't start ranging");

    }

}



@Override

public void didDetermineStateForRegion(int state, Region region) {

    switch (state) {

        case MonitorNotifier.INSIDE:

            Log.d(TAG, "INSIDE");

            didEnterInRegion = true;

            break;

        case MonitorNotifier.OUTSIDE:

            Log.d(TAG, "OUTSIDE");

            didEnterInRegion = false;

            break;

        default:

            didEnterInRegion = false;

            Log.d(TAG, "state" + state);

            break;

    }



}



@Override

public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {

    if (beacons.size() > 0) {

            for (Beacon beacon : beacons) {



             if (beacon.getId1().equals(Identifier.parse("0800200C9A66")) && beacon.getDistance() < 1.0) {

                         sendNotification(beacon);

                    }

            }

    }

}



@Override

public void onBeaconServiceConnect() {

    beaconManager.addRangeNotifier(this);

    try {

        beaconManager.startRangingBeaconsInRegion(region);

    } catch (RemoteException e) {

    }

}



@Override

public IBinder onBind(Intent intent) {

    return null;

}



@Override

public void onDestroy() {

    beaconManager.unbind(this);

    super.onDestroy();

}

}

1 个答案:

答案 0 :(得分:0)

didRangeBeaconsInRegion设计用于在每个扫描周期结束时定期发射(默认情况下每1秒钟),以告诉您在此期间看到了哪些信标。

如果您只想在检测到每个信标之前触发一个事件,您可以创建一个类变量来保存一个标志,指示您是否已经处理了每个信标。

像这样:

// Put this at your class level
Set<String> mBeaconsProcessed = new HashSet<>();

...

// Put this code inside your didRangeBeaconsInRegion method

// Only process this beacon if we have not done so before
if (!mBeaconsProcessed.contains(beacon.toString)) {
    if (beacon.getId1().equals(Identifier.parse("0800200C9A66")) && beacon.getDistance() < 1.0) {
         sendNotification(beacon);
         // Mark this beacon as having already been processed.
         mBeaconsProcessed.put(beacon.toString));
         }
    }
}