sirve removed que para hacer geofences geofence espaƱol como app added android-geofence

android-geofence - removed - geofencing app



Android Geofence finalmente deja de obtener intenciones de transiciĆ³n (2)

Tengo una aplicación que comenzó con el código de muestra geofencing de Google. Funciona muy bien durante unos días, y tengo todos los intentos de transición como lo anticipo. Sin embargo, después de un tiempo, algo así como 3 días, la aplicación deja de obtener estos intentos, y no sé por qué.

Cuando creo mis vallas, estoy estableciendo la duración de vencimiento en Geofence.NEVER_EXPIRE

Aquí está mi IntentService, donde obtengo las intenciones de transición antes de que dejen de funcionar:

public class ReceiveTransitionsIntentService extends IntentService { @Override protected void onHandleIntent(Intent intent) { Intent broadcastIntent = new Intent(); broadcastIntent.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES); // First check for errors if (LocationClient.hasError(intent)) { ...handle errors } else { // 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 NEVER GETS HERE } else { ...log error } } } }

Aquí está la parte pertinente del manifiesto:

<service android:name="com.aol.android.geofence.ReceiveTransitionsIntentService" android:exported="false" > </service>

En mi clase GeofenceRequester, es casi idéntico al código de muestra. Aquí están las partes pertinentes:

// Get a PendingIntent that Location Services issues when a geofence transition occurs mGeofencePendingIntent = createRequestPendingIntent(); // Send a request to add the current geofences mLocationClient.addGeofences(mCurrentGeofences, mGeofencePendingIntent, this); private PendingIntent createRequestPendingIntent() { // Create an Intent pointing to the IntentService Intent intent = new Intent(context, ReceiveTransitionsIntentService.class); return PendingIntent.getService( context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); } }

¿Alguien puede ver por qué esto dejaría de funcionar?


A continuación puede encontrar las razones por las que la Aplicación no obtiene Intents Pendientes de acuerdo con la documentación oficial de Google:
1.El dispositivo se reinicia.
2. La aplicación se desinstala y se vuelve a instalar.
3. Los datos de la aplicación se borran.
4. Los datos de los servicios de Google Play se borran.
5. La aplicación ha recibido una alerta GEOFENCE_NOT_AVAILABLE. (Cuando el proveedor de ubicación Android se apaga)

Debe volver a registrar la geovacía después de estos eventos.

En mi caso, el proveedor de localización se desconecta y también se reinicia el dispositivo, por eso no obtuve los intentos pendientes.


Entonces, después de jugar un poco con esto, parece que ReceiveTransitionsIntentService, tal como se define en el código de ejemplo, dejará de recibir las notificaciones cuando la aplicación no se encuentre. Creo que este es un gran problema con el código de ejemplo ... Parece que eso hará tropezar a gente como yo.

Así que utilicé un receptor de transmisión en su lugar, y hasta ahora parece estar funcionando a partir de mis pruebas.

Agregue esto al manifiesto:

<receiver android:name="com.aol.android.geofence.GeofenceReceiver" android:exported="false"> <intent-filter > <action android:name="com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE"/> </intent-filter> </receiver>

Luego, en la clase GeofenceRequester necesitas cambiar el método createRequestPendingIntent para que vaya a tu BroadcastReceiver en lugar de a ReceiveTransitionsIntentService

private PendingIntent createRequestPendingIntent() { // If the PendingIntent already exists if (null != mGeofencePendingIntent) { // Return the existing intent return mGeofencePendingIntent; // If no PendingIntent exists } else { // Create an Intent pointing to the IntentService Intent intent = new Intent("com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE"); // Intent intent = new Intent(context, ReceiveTransitionsIntentService.class); /* * Return a PendingIntent to start the IntentService. * Always create a PendingIntent sent to Location Services * with FLAG_UPDATE_CURRENT, so that sending the PendingIntent * again updates the original. Otherwise, Location Services * can''t match the PendingIntent to requests made with it. */ return PendingIntent.getBroadcast( context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); } }

Luego agregué la clase GeofenceReceiver que se ve así:

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 is * detected. If the user clicks the notification, control goes to the main * Activity. * * @param transitionType * The type of transition that occurred. * */ 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()); } }

Espero que eso ayude a alguien más.