Confiabilidad del Administrador de alarmas

He estado luchando con este problema durante días. También he revisado la documentación y varios temas, pero no encontré ninguna solución / explicación.
Estoy probando mi aplicación en LG p500, pero hice algunas pruebas en Droid también y obtener el mismo resultado.

Mi aplicación utiliza AlarmHandler para programar la alarma. La aplicación funciona correctamente en el emulador y también en el dispositivo hasta que el dispositivo tenga suficiente memoria libre. Cuando comienzo varias otras aplicaciones en el dispositivo y la memoria es baja la alarma no se disparará más. Tan pronto como detener la "otra" aplicación de la alarma funciona bien de nuevo.

Permítanme informar la prueba y el resultado.

  1. Puse una alarma en mi aplicación 10 minutos más tarde.
  2. Empecé varias aplicaciones (navegador, google map, gmail, K9Mail, ….)
  3. Inicie el catlog para ver el registro de mi aplicación
  4. Espere 15 minutos sin trabajar en el teléfono
  5. Después de 10 minutos la alarma debe ser disparada pero no pasa nada hasta que despierte mi teléfono presionando un botón
  6. Cuando despierto mi teléfono la alarma inmediatamente se enciende y toda la notificación sucede.
  7. Detengo la "otra" aplicación que previamente inicié (navegador, mapa de google, …)
  8. Establecer de nuevo una alarma 10 minutos más tarde
  9. Inicie el catlog para ver el registro de mi aplicación
  10. Esperar sin trabajar en el teléfono
  11. 10 minutos más tarde la alarma dispara y me notifican.

Hice esta prueba varias veces y obtengo el mismo resultado.
Entonces intenté fijar una alarma usando la aplicación de la "captura" que descargue previamente del mercado y consigo el mismo comportamiento así que parece que esto no es un problema de mi uso.

Mirando el registro de mi aplicación no veo ningún error / excepción, pero parece que cuando el sistema tiene poca memoria sucede algo y el receptor de emisión no se inicia hasta que el teléfono se despierta a través del teclado. Tan pronto como despierto el teléfono, el receptor comienza y toda la notificación ocurre.

Aquí el código que usé:

El receptor:

public class NotificationReceiver extends BroadcastReceiver { public static final String LOG_TAG = "YAAS - Notification Receiver"; @Override public void onReceive(Context context, Intent intent) { ScheduleActivityService.acquireStaticLock(context); Log.i(LOG_TAG, "Received alarm - id: " + intent.getIntExtra("id", -1)); Intent intent2 = new Intent(context, ScheduleActivityService.class); intent2.putExtra("id", intent.getIntExtra("id", -1)); context.startService(intent2); } } 

El servicio

 public class ScheduleActivityService extends Service { public static final String LOCK_NAME_STATIC="it.hp.yaas.AppService.Static"; public static final String LOG_TAG = "YAAS - ActivityService"; private static PowerManager.WakeLock lockStatic = null; private final IBinder mBinder = new LocalBinder(); public class LocalBinder extends Binder { public ScheduleActivityService getService() { return ScheduleActivityService.this; } } @Override public IBinder onBind(Intent intent) { return mBinder; } public static void acquireStaticLock(Context context) { getLock(context).acquire(); } synchronized private static PowerManager.WakeLock getLock(Context context) { if (lockStatic == null) { PowerManager mgr = (PowerManager)context.getSystemService(Context.POWER_SERVICE); lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOCK_NAME_STATIC); lockStatic.setReferenceCounted(true); } return(lockStatic); } /** * This method is called when an alarm fires that is its alarm time is reached. * The system assume that the alarm fired match the alarm time of the first * activity. * @param intent intent fired * @param flag * @param startId */ @Override public int onStartCommand(Intent intent, int flag, int startId) { super.onStartCommand(intent, flag, startId); try { Log.i(LOG_TAG, "Alarm fired: " + startId + " - id: " + intent.getIntExtra("id", -1)); AlarmHandler.getInstance().onAlarmFired(intent.getIntExtra("id", -1)); } finally { getLock(this).release(); } return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); Log.i(LOG_TAG, "Destroy"); } } 

Un pedazo de código de AlarmHandler, la rutina llamada para programar la alarma:

  public synchronized void onAlarmFired(int alarmId) { scheduledAlarmId = -1; Alarm alarmFired = pop(); if (alarmFired == null) return; Log.i(LOG_TAG, "onAlarmFired (Alarm: " + alarmFired + ") at (time: " + Utilities.convertDate(new Date(), "HH:mm:ss") + ")"); notifyAlarmListener(alarmFired); if (alarmFired.reschedule(null) != null) add(alarmFired); Alarm alarm = peek(); if (alarm != null && scheduledAlarmId != alarm.getId()) scheduleEvent(alarm); } /** * Schedule an alarm through AlarmManager that trigger next activity notification * @param alarm alarm to be scheduled */ private void scheduleEvent(Alarm alarm) { Log.i(LOG_TAG, "scheduleEvent - (Alarm: " + alarm + ")"); Intent intent = new Intent(context, NotificationReceiver.class); intent.putExtra("id", alarm.getId()); // In reality, you would want to have a static variable for the request code instead of 192837 PendingIntent sender = PendingIntent.getBroadcast(context, 192837, intent, PendingIntent.FLAG_UPDATE_CURRENT); // Get the AlarmManager service AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); am.set(AlarmManager.RTC_WAKEUP, alarm.getTime().getTime(), sender); scheduledAlarmId = alarm.getId(); } 

Y finalmente este es un pedazo de archivo de manifiesto:

  <activity android:name=".ListActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".EditActivity"/> <activity android:name=".SettingsActivity"/> <service android:name="ScheduleActivityService" android:label="YAAS Service"/> <receiver android:name="NotificationReceiver" /> 

2 Solutions collect form web for “Confiabilidad del Administrador de alarmas”

¿Está seguro de que su proceso no se mata cuando inicia todas esas aplicaciones? Si lo hace, las alarmas que usted fija morirán con él. No está exactamente claro quién y cuándo programa la alarma en su código, pero si es el servicio, ya que es pegajoso, eventualmente se reiniciará, y obtendrá una alarma en algún momento (al despertar el dispositivo).

Una manera fácil de comprobar qué alarmas están registradas en diferentes puntos de su prueba:

 # adb shell dumpsys alarm 

Mi código es muy similar al tuyo en una aplicación de alarma que escribí y uso regularmente. No he sido capaz de reproducir el problema que usted describe. No puedo conseguir que mi teléfono llegue a un estado de memoria extremadamente baja. He abierto todas las aplicaciones que he instalado y todavía tengo 260M libre en mi HTC Rezound.

Como una salvaguardia en mi aplicación he utilizado alarmmanager.setRepeating () en lugar de .set (). Puse el intervalo de repetición a 20 segundos. Pasé la identificación de la alarma como un intento extra como usted tiene. Cuando mi servicio comienza inmediatamente cancela la intención pendiente usando el ID de alarma. Mi lógica aquí es que si por alguna razón mi alarma falla continuará intentando cada 20 segundos hasta que tenga éxito.

  • Ejemplo del Administrador de alarmas
  • Android AlarmManager no se dispara después de la actualización de Google Play
  • AlarmManager no funciona
  • SetRepeating () de AlarmManager se repite después de 1 minuto sin importar la hora (5 segundos en este caso, API 18+)
  • Cómo programar una tarea mediante el Administrador de alarmas
  • Cómo configurar la alarma en Android?
  • ¿Utilizar el Administrador de alarmas incluso si la aplicación está cerrada?
  • Android AlarmManager a veces se activa tarde si el teléfono se ejecuta en la batería
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.