2014-04-07 25 views
17

Se si dispone di questi due geofences, dopo aver registrato questi geofences dovrei ricevere una notifica quando sto entrando o uscendo dalla circonferenza di queste circonferenze. Tuttavia, non voglio che la mia app invii una notifica se mi sto spostando attraverso l'area comune, vale a dire da una cerchia all'altra.Gestione della transizione di più aree geografiche con area comune

È possibile? Se è così, allora come?

Image of map with two circles intersecting

+0

Sì, questo è molto possibile, ora devi applicare l'Unione qui per ottenere i luoghi comuni ei luoghi noti sotto la circonferenza e il sottoinsieme per ottenere i luoghi comuni di due circonferenze. Ora puoi utilizzare la distanza dal punto centrale e applicare la formula della distanza. –

+0

puoi elaborare la tua risposta un po 'di più.thanx @jitainsharma – Pankaj

risposta

13

si dovrà utilizzare un class per il monitoraggio scherma:

public class GeofenceReceiver extends BroadcastReceiver { 
    Context context; 

    Intent broadcastIntent = new Intent(); 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     this.context = context; 

     broadcastIntent.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES); 

     if (LocationClient.hasError(intent)) { 
      handleError(intent); 
     } else { 
      handleEnterExit(intent); 
     } 
    } 

    private void handleError(Intent intent){ 
     // Get the error code 
     int errorCode = LocationClient.getErrorCode(intent); 

     // Get the error message 
     String errorMessage = LocationServiceErrorMessages.getErrorString(
       context, errorCode); 

     // Log the error 
     Log.e(GeofenceUtils.APPTAG, 
       context.getString(R.string.geofence_transition_error_detail, 
         errorMessage)); 

     // Set the action and error message for the broadcast intent 
     broadcastIntent 
       .setAction(GeofenceUtils.ACTION_GEOFENCE_ERROR) 
       .putExtra(GeofenceUtils.EXTRA_GEOFENCE_STATUS, errorMessage); 

     // Broadcast the error *locally* to other components in this app 
     LocalBroadcastManager.getInstance(context).sendBroadcast(
       broadcastIntent); 
    } 


    private void handleEnterExit(Intent intent) { 
     // Get the type of transition (entry or exit) 
     int transition = LocationClient.getGeofenceTransition(intent); 

     // Test that a valid transition was reported 
     if ((transition == Geofence.GEOFENCE_TRANSITION_ENTER) 
       || (transition == Geofence.GEOFENCE_TRANSITION_EXIT)) { 

      // Post a notification 
      List<Geofence> geofences = LocationClient 
        .getTriggeringGeofences(intent); 
      String[] geofenceIds = new String[geofences.size()]; 
      String ids = TextUtils.join(GeofenceUtils.GEOFENCE_ID_DELIMITER, 
        geofenceIds); 
      String transitionType = GeofenceUtils 
        .getTransitionString(transition); 

      for (int index = 0; index < geofences.size(); index++) { 
       Geofence geofence = geofences.get(index); 
       ...do something with the geofence entry or exit. I'm saving them to a local sqlite db 

      } 
      // Create an Intent to broadcast to the app 
      broadcastIntent 
        .setAction(GeofenceUtils.ACTION_GEOFENCE_TRANSITION) 
        .addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES) 
        .putExtra(GeofenceUtils.EXTRA_GEOFENCE_ID, geofenceIds) 
        .putExtra(GeofenceUtils.EXTRA_GEOFENCE_TRANSITION_TYPE, 
          transitionType); 

      LocalBroadcastManager.getInstance(MyApplication.getContext()) 
        .sendBroadcast(broadcastIntent); 

      // Log the transition type and a message 
      Log.d(GeofenceUtils.APPTAG, transitionType + ": " + ids); 
      Log.d(GeofenceUtils.APPTAG, 
        context.getString(R.string.geofence_transition_notification_text)); 

      // In debug mode, log the result 
      Log.d(GeofenceUtils.APPTAG, "transition"); 

      // An invalid transition was reported 
     } else { 
      // Always log as an error 
      Log.e(GeofenceUtils.APPTAG, 
        context.getString(R.string.geofence_transition_invalid_type, 
          transition)); 
     } 
    } 

    //Posts a notification in the notification bar when a transition 
    private void sendNotification(String transitionType, String locationName) { 

     // Create an explicit content Intent that starts the main Activity 
     Intent notificationIntent = new Intent(context, MainActivity.class); 

     // Construct a task stack 
     TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); 

     // Adds the main Activity to the task stack as the parent 
     stackBuilder.addParentStack(MainActivity.class); 

     // Push the content Intent onto the stack 
     stackBuilder.addNextIntent(notificationIntent); 

     // Get a PendingIntent containing the entire back stack 
     PendingIntent notificationPendingIntent = stackBuilder 
       .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); 

     // Get a notification builder that's compatible with platform versions 
     // >= 4 
     NotificationCompat.Builder builder = new NotificationCompat.Builder(
       context); 

     // Set the notification contents 
     builder.setSmallIcon(R.drawable.ic_notification) 
       .setContentTitle(transitionType + ": " + locationName) 
       .setContentText(
         context.getString(R.string.geofence_transition_notification_text)) 
       .setContentIntent(notificationPendingIntent); 

     // Get an instance of the Notification manager 
     NotificationManager mNotificationManager = (NotificationManager) context 
       .getSystemService(Context.NOTIFICATION_SERVICE); 

     // Issue the notification 
     mNotificationManager.notify(0, builder.build()); 
    } 

è necessario creare gli ascoltatori per ognuna delle aree che si desidera per monitorare, diciamo listener1 e listener2. Per ottimizzare entrambe le aree e integrarlo, l'approccio migliore consiste nel creare una griglia utilizzando MongoDB, che in tal caso consente anche di integrare più di due punti mentre si costruisce una griglia.

enter image description here

Supponendo che si sta andando ad uscire un poligono in forma di alcuni punti di Lat-Lon, allora si può generare un grid come la seguente:

# Method to get the min and max values for the polygon 
def get_bounding_box(coords) 
# get max and min coords 
max = coords.inject({lat:0, lon:0}) do |max, c| 
max[:lon] = c[0] if c[0] > max[:lon] 
max[:lat] = c[1] if c[1] > max[:lat] 
max 
end 
min = coords.inject({lat:MAX_LAT, lon:MAX_LON}) do |min, c| 
min[:lon] = c[0] if c[0] < min[:lon] 
min[:lat] = c[1] if c[1] < min[:lat] 
min 
end 
# add a little padding to the max and min 
max.each {|k, v| max[k] += 1 } 
min.each {|k, v| min[k] -= 1 } 

{min: min, max: max} 
end 

def generate_grid(bounds) 
lon_range = bounds[:min][:lon]...bounds[:max][:lon] 
lat_range = bounds[:min][:lat]...bounds[:max][:lat] 

grid = [] 
lon_range.each do |lon| 
lat_range.each do |lat| 
grid << [lon + 0.25, lat + 0.25] 
grid << [lon + 0.25, lat + 0.75] 
grid << [lon + 0.75, lat + 0.25] 
grid << [lon + 0.75, lat + 0.75] 
end 
end 

grid 
end 

Tale approccio consente a realizzare very efficient geofencing con reti intelligenti per il monitoraggio di aree di destinazione:

enter image description here

Più recentemente MongoDB ha anche aggiunto il supporto per Android, fornendo così un modo semplice per l'integrazione del back-end dell'app Android. Si prevede che lo sviluppo di geofencing con dati distribuiti intelligenti abbia un numero crescente di applications.

0

molto schematicamente:

boolean isTransition1, isTransition2, isTransition, insideCircle1, insideCircle2, insideUnion, insideUnionPrev; 

if (isTransition1 | isTransition2) { 
    insideCircle1 = (dist(currPosition, centerCircle1) < radius1); 
    insideCircle2 = (dist(currPosition, centerCircle2) < radius2); 
    insideUnionPrev = insideUnion; 
    insideUnion = insideCircle1 | insideCircle; 
    isTransition = (insideUnion != insideUnionPrev); 
    if (isTransition & insideUnion) println("Moved into region"); 
    if (isTransition & !insideUnion) println("Moved out of region"); 
} 
+0

Penso che non funzionerà per Android Geofence, grazie per l'aiuto – Pankaj

+0

Perché non pensi che funzionerà? È una logica semplice, basta usare il callback per impostare isTransition1,2 bool ... – user1939887

1

Questo può essere un'alternativa:

Tutti geofences hanno un id; Non sono sicuro che debbano essere unici, ma per questa discussione diciamo che devono essere unici. Nel tuo esempio di due geofence utilizziamo id "fenceHome-1" e "fenceHome-2" per quelli mostrati e un terzo chiamato "someOther-1" che non è mostrato.

Ora ciò che puoi fare è creare una variabile per memorizzare il geofence corrente in cui si trova l'utente. In questo esempio sarà una stringa con l'ID geofence. Chiamiamolo

String currentGeofence = new String(); 

Quando l'utente entra in una nuova geofence ora è possibile controllare se le geofenceIds sono gli stessi.

 /** 
     geofenceEntered get from the Intent. Should be "fenceHome-1" or "fenceHome-2" or "someOther=1" 
     */  
    public void enteredGeoFence(String geofenceEntered) { 

     // strip off the "-1" or "-2" 
     geofenceEntered = geofenceEntered.stripOff(); 

     if (currentGoofence.equals(geofenceEntered) == false} { 
      // user entered a new geofence Ex: "SomeOther-1" to "fenceHome-1" 
      sendNotification(geofenceEntered, .....); 
      currentGeofence = geofencecEntered; 
     } else { 
      // user entered a geofence with in the same 'area'. Ex: "fenceHome-1" to "fenceHome-2" 
      // do nothing 
     } 

    } 

Ecco come lo farei. Giocherellare con tutta quella matematica è troppo difficile. Basta impostare una convenzione di denominazione intelligente per gli ID geofence. La chiave è la denominazione delle aree geografiche.

Nel mondo reale, correnteGeofence dovrebbe essere una raccolta poiché un utente può trovarsi in più geofence e il geofenceExit() dovrebbe rimuovere da currentGeofence.

Un'altra cosa da ricordare del gestore delle notifiche di Android è: se si invia la stessa notifica due volte, verrà inviata una sola notifica. Questo potrebbe essere usato a tuo vantaggio.

+0

puoi condividere il tuo codice ...? –