2011-09-02 12 views
6

Implementé AlarmManager para reactivar el teléfono una vez al día para realizar una tarea de actualización, actualizar widgets y enviar notificaciones si corresponde.Android AlarmManager setRepetir no se repite con intervalo largo

estoy usando setRepeating y ELAPSED_REALTIME_WAKEUP la alarma se activa por primera vez (SystemClock.elapsedRealtime()+60000) pero no consigue provocó 86400000 milisegundos (24 horas) más tarde.

Realmente estoy luchando con esto, estoy feliz de aceptar que estoy haciendo algo mal o si hay mejores formas de lograr lo que estoy tratando de hacer. Sin embargo, creo que mi código parece ser lo estándar que la gente parece hacer.

Es casi como si la alarma de repetición no hiciera lo que dice que debería en todos los casos. Si reduzco el intervalo para decir 10 minutos, funciona, mi alarma se dispara y el servicio se ejecuta una y otra vez.

La naturaleza de mi aplicación significa que actualizar más de una vez al día es excesivo. Necesito encontrar una solución realista y confiable para esto.

Gracias por su tiempo & espero que pueda señalarme en la dirección correcta.

Aquí está mi código de implementación de alarma ...

Manifiesto:

<receiver android:name=".SystemChangeReceiver"> 
    <intent-filter> 
     <action android:name="android.intent.action.BOOT_COMPLETED" /> 
     <action android:name="android.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE" /> 
    </intent-filter> 
</receiver> 
<receiver android:name=".UpdateAlarmReceiver" /> 
<service android:name=".UpdateService" /> 
<receiver android:name=".WidgetProviderSmall" android:label="@string/widget_small_label"> 
    <intent-filter> 
     <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
    </intent-filter> 
    <meta-data 
     android:name="android.appwidget.provider" 
     android:resource="@xml/appwidget_small" /> 
</receiver> 
<receiver android:name=".WidgetProviderLarge" android:label="@string/widget_large_label"> 
    <intent-filter> 
     <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
    </intent-filter> 
    <meta-data 
     android:name="android.appwidget.provider" 
     android:resource="@xml/appwidget_large" /> 
</receiver> 

SystemChangeReceiver escuchas para la emisión de arranque, comprueba si una alarma se debe establecer, si lo hace, que lo pone.

SystemChangeReceiver:

@Override 
public void onReceive(Context context, Intent intent) { 

    SharedPreferences prefs = context.getSharedPreferences(context.getString(R.string.prefs_name), 0); 

    Boolean notifications = prefs.getBoolean("enable_updates", false); 
    if(notifications == true) { 
     Utils.setNotificationAlarm(context); 
    } 
} 

El método setNotificationAlarm, pone en marcha la alarma repitiendo ...

public static void setNotificationAlarm(Context context) { 
     AlarmManager alarmManager=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE); 

     Intent intent = new Intent(context, UpdateAlarmReceiver.class); 
     PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0); 

     alarmManager.setRepeating(
      AlarmManager.ELAPSED_REALTIME_WAKEUP, 
      SystemClock.elapsedRealtime()+60000, 
      86400000, 
      pi); 
} 

Cuando se dispara la alarma UpdateAlarmReceiver mi receptor decide qué hacer y usar WakefulIntentService corre mi actualización en segundo plano proceso, el controlador para el servicio luego actualiza los widgets y envía las notificaciones según sea necesario

UpdateAlarmReceiver:

public void onReceive(Context context, Intent intent) { 
    WakefulIntentService.sendWakefulWork(context, UpdateService.class); 
} 
+0

Pregunta rápida que puede resolver todo esto: ¿Utiliza un asesino de tareas? ¿Tu aplicación está en la lista blanca? –

+0

En realidad estoy usando AutoKiller Memory Optimizer, no tiene una lista blanca, ¿podría ser el problema? Mi aplicación sigue ejecutándose según la lista de procesos. – Rob

Respuesta

1

Ha intentado establecer que no se repita. Luego, cuando se apaga, ¿configura la próxima alarma de disparo único durante 24 horas más tarde? Esto funcionaría como una alarma repetitiva, pero podría evitar algunos de los problemas que está viendo.

+0

No he considerado esto. Pensé que era básicamente lo que setRepeating hizo. Aunque lo intentaré, gracias. – Rob

+0

Hice una aplicación de tipo reloj despertador y así es como lo manejé y me pareció que funcionaba correctamente, lo que provocó que AlarmActivity se iniciara a la hora correcta al día siguiente. Nunca he usado el indicador setRepeating(), así que no estoy seguro de por qué eso no funcionaría, me parece también que estos dos enfoques deberían funcionar de la misma manera. ¿Podría ser que no está despertando el dispositivo correctamente cuando se dispara? – FoamyGuy

+0

Creo que está despertando bien, estoy usando 'WakefulIntentService' que usa' PowerManager.WakeLock' – Rob

2

No hay nada obviamente malo.

Por un período tan largo como ese, recomendaría RTC_WAKEUP, por lo que puede organizar que ocurra en el medio de la noche o tal vez en un tiempo seleccionable por el usuario, en lugar de cada 24 horas desde una semi punto de inicio aleatorio Es posible RTC_WAKEUP le dará mejores resultados.

también:

  • Añadir una declaración de registro en onReceive() de UpdateAlarmReceiver para confirmar si usted está consiguiendo el control en absoluto, o si el problema es (¡oh!) Con WakefulIntentService.
  • Intente aumentar constantemente su período. Dado que dices que 10 minutos funcionan, prueba una hora, luego cuatro horas, etc., y trata de tener una idea de cuándo se rompe.
  • "Uso el Optimizador de memoria AutoKiller, pero no tiene una lista blanca, ¿podría ser el problema? Mi aplicación todavía se está ejecutando según la lista de procesos". - Desactivaría todos los asesinos de tareas, solo para asegurarme de que no interfieran.
+0

Gracias Mark, ya he agregado el registro en varios lugares, con el largo intervalo ni siquiera toca el receptor de alarma, así que estoy bastante seguro de que es el administrador de alarma en algún lugar. Ahora he desactivado el optimizador de memoria, intentaré todas las otras sugerencias. – Rob

+0

@Rob: Lo único que sé que eliminará una alarma programada es: si 'cancel()' it, si el usuario Force lo detiene desde Manage Services en la aplicación Settings, o si un task killer lo detiene (y eso podría ser solo un problema en 2.1 y anteriores - No esperaría que 'killBackgroundProcesses()' elimine las alarmas, pero podría estar equivocado). Con suerte, encontrará que AutoKiller fue el culpable. – CommonsWare

Cuestiones relacionadas