Cómo crear un AlarmManager persistente

Edit: Clarificó la pregunta basada en la respuesta de CommonsWare

Estamos programando una alarma a través de AlarmManager para activar cada 60 segundos. Cuando nuestra aplicación es matada nuestras alarmas parecen no ejecutar más. ¿Hay una manera de hacer que estas alarmas persisten incluso cuando la aplicación es eliminada manualmente o por el sistema?

Esto es un problema para nosotros porque tenemos una aplicación de widget que muestra la hora. Esto significa que necesitamos actualizar el tiempo cada minuto. Para evitar el límite de actualización de 30 minutos en el método onUpdate de AppWidgetProvider usamos AlarmManager. Por lo general funciona bastante bien, pero algunos usuarios han informado de la hora de salir de la sincronización. Después de hablar con varios de ellos, mi sospecha es que nuestra aplicación está siendo asesinada manualmente a través de una aplicación asesina tarea o Android es en sí mismo está matando a nuestra aplicación.

Cualquier otra solución alternativa para el problema raíz (mantener el tiempo sincronizado en un widget) también es bienvenida.

Aquí está el código que ejecutamos para programar nuestra alarma:

Intent intent = new Intent(UPDATE_TIME); PendingIntent pIntent = PendingIntent.getBroadcast(ctx, 0 /* no requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT ); // get alarm params Date d = new Date(); long timeTilMinuteChange = 60*1000-d.getSeconds()*1000; long startTime = System.currentTimeMillis() + + timeTilMinuteChange; AlarmManager am = (AlarmManager) ctx.getSystemService(Context. am.cancel(pIntent); am.set(AlarmManager.RTC, System.currentTimeMillis(), pIntent); am.setRepeating(AlarmManager.RTC, startTime, 60000, pIntent); 

Cada vez que se cancela nuestra aplicación, el AlarmManager también se extingue.

AlarmManager no se AlarmManager . Su alarma, sin embargo, se cancela. Si la fuerza del usuario -tiene o mata la tarea-, sus alarmas no se programarán. En Android 3.1 o superior, si la fuerza del usuario te detiene, nada de tu código se ejecutará de nuevo hasta que el usuario inicie manualmente una de tus actividades.

Después de hablar con varios de ellos, mi sospecha es que nuestra aplicación está siendo asesinada manualmente a través de una aplicación asesina tarea o Android es en sí mismo está matando a nuestra aplicación.

Idealmente, su aplicación no debe escribirse de tal manera que Android tendría alguna causa para deshacerse de usted. Para algo como lo que usted describe, debe usar un getBroadcast() PendingIntent apuntando a un BroadcastReceiver registrado por el manifiesto, o debería usar un getService() PendingIntent apuntando a un IntentService . En cualquier caso, su código se ejecutará brevemente y, a continuación, su proceso será elegible para la reclamación de Android sin problema si fuera necesario.

Los asesinos de tareas, ya sean manuales o automáticos, parecen un culpable mucho más probable de las alarmas que se cancelan, IMHO.

Acerca del administrador de alarmas en Docs – la explicación es un poco confusa y honestamente todavía no lo entiendo completamente. Tengo este pedacito del código para la pieza del widget que solucionó el problema en mi caso.

 package com.test.mytestwidget; import java.util.Calendar; import android.app.AlarmManager; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; public class MyWidgetProvider extends AppWidgetProvider { private PendingIntent service = null; public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); final Calendar TIME = Calendar.getInstance(); TIME.set(Calendar.MINUTE, 0); TIME.set(Calendar.SECOND, 0); TIME.set(Calendar.MILLISECOND, 0); final Intent i = new Intent(context, UpdateWidgetService.class); if (service == null) { service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT); } m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 30000, service); } @Override public void onDisabled(Context context) { final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); m.cancel(service); super.onDisabled(context); } } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.