geofencingclient geofences geofence added android gps android-maps geofencing android-geofence

android - added - Manejo de transiciones de múltiples geofences con área común.



geofences added android (3)

Si tengo estas dos geofences, luego de registrar estas geofences debería recibir una notificación cuando esté ingresando o saliendo de la circunferencia de estos círculos. Sin embargo, no quiero que mi aplicación envíe una notificación si me estoy moviendo a través del área común, es decir, de un círculo a otro.

¿Es posible? Si es así, entonces ¿cómo?


Esta puede ser una alternativa:

Todas las geofences tienen una identificación; No estoy seguro de que deban ser únicos, pero para esta discusión digamos que deben ser únicos. En sus dos ejemplos de geofence, usemos las identificaciones "fenceHome-1" y "fenceHome-2" para las que se muestran y una tercera llamada "someOther-1" que no se muestra.

Ahora, lo que puede hacer es crear una variable para almacenar la geofence actual en la que se encuentra el usuario. En este ejemplo, será una cadena con el id de geofence. Llamémoslo

String currentGeofence = new String();

Cuando el usuario ingresa un nuevo geofence, ahora puede verificar si los geofenceIds son los mismos.

/** 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 } }

Así es como lo haría. Jugar con todas esas matemáticas es demasiado difícil. Solo establece una convención de nomenclatura inteligente para tus ID de geofence. La clave es el nombramiento de las geofences .

En el mundo real, currentGeofence tendría que ser una colección, ya que un usuario puede estar en múltiples geofences y geofenceExit () tendría que eliminarse de currentGeofence.

Otra cosa que debe recordar del administrador de notificaciones de Android es: si envía la misma notificación dos veces, solo enviará una notificación. Esto podría ser utilizado para su ventaja.


Tendrá que usar una class para controlar su cercado:

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

Debe crear escuchas para cada una de las áreas que desea monitorear, digamos listener1 y listener2. Para optimizar ambas áreas e integrarla, el mejor enfoque es hacer una cuadrícula utilizando MongoDB, que en tal caso incluso le permite integrar más de dos puntos, mientras construye una cuadrícula.

Suponiendo que vas a obtener un polígono en forma de algunos puntos Lat-Lon, entonces puedes generar una grid como la siguiente:

# 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

Este enfoque le permite lograr un geofencing muy eficiente con redes inteligentes para monitorear áreas objetivo:

Más recientemente, MongoDB también agregó soporte para Android , lo que proporciona una manera fácil para la integración de back-end de su aplicación Android. De hecho, se espera que el desarrollo de geofencing con datos distribuidos inteligentes tenga un número creciente de applications .


muy esquemáticamente:

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"); }