2017-07-31 5 views
0

J'utilise Android Beacon Library (AltBeacon SDK) dans un de mes projets. Si l'utilisateur entre dans la plage de la balise et la notification de la sortie Si la sortie de la plage de balise, mais le problème auquel je suis confronté, je reçois toujours les notifications, par exemple, didRangeBeaconsInRegion (Balises de collection, Région) appelées plusieurs fois . Y at-il un moyen que cette fonction devrait appeler une seule fois lorsque l'application est dans la gamme de balise?Pourquoi didRangeBeaconsInRegion appelé plusieurs fois?

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(); 

} 

}

Répondre

0

Le didRangeBeaconsInRegion est conçu pour tirer régulièrement à la fin de chaque cycle de balayage (par défaut tous les ~ 1 seconde) pour vous dire que les balises ont été observées au cours de cette période.

Si vous voulez seulement qu'un événement se déclenche une fois que chaque balise a été détectée, vous pouvez créer une variable de classe pour contenir un drapeau indiquant si vous avez déjà traité chaque balise.

Comme ceci:

// 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)); 
     } 
    } 
} 
+0

Merci @ David, j'ai mis en œuvre la même logique, je pensais qu'il pourrait y avoir en fonction intégrée dans l'API. – Gkapoor

+0

Un autre problème que j'ai trouvé que didExitRegion est également appelé alors que l'appareil est dans la gamme balise. – Gkapoor

+0

Comment afficher une notification sur la plage de sortie des balises? – Gkapoor