2012-06-02 14 views
6

He buscado durante 3 días pero no he encontrado una solución o problema/pregunta similar en otro lugar. Este es el trato:AlarmManager desencadena PendingIntent demasiado pronto

gatillo en 1 hora -> funciona correctamente

gatillo en 2 horas -> Va de en 1:23

gatillo en 1 día -> Va de en ~ 11: 00

¿Por qué el AlarmManager es tan impredecible y siempre demasiado pronto? ¿O qué estoy haciendo mal? ¿Y hay otra forma para que funcione correctamente?

Esta es la forma en registro mi PendingIntent en el AlarmManager (simplificada):

AlarmManager alarmManager = (AlarmManager)parent.getSystemService(ALARM_SERVICE); 
Intent myIntent = new Intent(parent, UpdateKlasRoostersService.class); 
PendingIntent pendingIntent = PendingIntent.getService(parent, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

//Set startdate of PendingIntent so it triggers in 10 minutes 
Calendar start = Calendar.getInstance(); 
start.setTimeInMillis(SystemClock.elapsedRealtime()); 
start.add(Calendar.MINUTE, 10); 

//Set interval of PendingIntent so it triggers every day 
Integer interval = 1*24*60*60*1000; 

//Cancel any similar instances of this PendingIntent if already scheduled 
alarmManager.cancel(pendingIntent); 

//Schedule PendingIntent 
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, start.getTimeInMillis(), interval, pendingIntent); 
//Old way I used to schedule a PendingIntent, didn't seem to work either 
//alarmManager.set(AlarmManager.RTC_WAKEUP, start.getTimeInMillis(), pendingIntent); 

que sería increíble si alguien tiene una solución. ¡Gracias por cualquier ayuda!

Actualización: Hace 2 horas funcionó para activarlo con un intervalo de 2 horas, pero después de eso se activó después de 1:20 horas. Se está poniendo realmente extraño. Seguiré los disparadores con un archivo de registro y lo publicaré aquí mañana.

Actualización: El PendingIntent está programado para ejecutarse cada 3 horas. A partir de la segunda línea del registro parece como un viejo PendingIntent programada todavía se está ejecutando:

[2012-5-3 2:15:42 519] Updating Klasroosters 
[2012-5-3 4:15:15 562] Updating Klasroosters 
[2012-5-3 5:15:42 749] Updating Klasroosters 
[2012-5-3 8:15:42 754] Updating Klasroosters 
[2012-5-3 11:15:42 522] Updating Klasroosters 

Pero, estoy seguro de que cancela la programada PendingIntent de antes de programar una nueva. Y cada PendingIntent no se recrea de la misma manera, por lo que debería ser exactamente igual. Si no, esta pregunta de hilos ya no es relevante.

+1

No puedo recrear tu problema. Exactamente, ¿cómo cambias 'start' para avanzar 2 horas, también 1 día? – Sam

+1

Agregué el archivo de registro y descubrí que probablemente todavía se está ejecutando un PendingIntent antiguo. – Wezelkrozum

+0

Tengo el mismo problema también, ¿tiene una solución de trabajo? – david

Respuesta

1

Al utilizar un calendario, se tiene en cuenta que el calendario utiliza el tiempo hasta Milli segundos. Quizás deberías poner el segundo campo de Milli y el campo de segundos en cero para que salga el punto.

También para un día que sería más fácil de usar este

Calendar cal = Calendar.getInstance(); 
cal.setTimeInMillis(0); 
cal.add(Calendar.DAY_OF_MONTH, 1); 

también cuando se utiliza getInstance que no establece el tiempo de calendarios a la vez que se crea lo que no debería haber ninguna necesidad de establecer el tiempo de nuevo, ¿verdad?

+1

Mirando en la documentación, SystemClock.elapsedRealtime() es el tiempo desde que se inició el teléfono, no la hora real. Además, no creo que la llamada a setTimeInMillis (0) sea necesaria, porque quiere que la alarma sea 1 día a partir de ahora, no 1 día a partir de época (que es hace años). –

+1

¿Pero creo que está usando el 1 día como un intervalo, no como un tiempo real? – FabianCook

+1

sí, pero supongo que este problema es con el tiempo de disparo que se establece con el 'Calendario'. El intervalo de 1 día se define utilizando el 'Entero 'y debería estar bien. –

1

Reescribió: Eventualmente vi su error, pero imprevisiblemente.

Yo cambié esto:

PendingIntent.getService(parent, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

a esto:

PendingIntent.getService(parent, 0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT); 

bajo el mismo supuesto que se que de alguna manera un viejo intención es la radiodifusión. No he visto la casualidad desde ...

También las únicas veces que lo vi fueron durante mi llamada inicial. Otro enfoque podría ser rastrear un objeto de calendario current y previous, si el intervalo no es el esperado, entonces ignore esta emisión "temprana".(Aunque este método parece redundante teniendo en cuenta la forma en que la alarma debe trabajo, que ayuda a prevenir esas llamadas extrañas teniendo en cuenta lo que la alarma es de trabajo ...)

Espero que ayude, que le permiten saber si encuentro Algo más.

+1

Gracias por su esfuerzo, pero ya lo he hecho. Cuando analizo estos datos, debe activar el PendingIntent a tiempo, pero no es así. Entonces, ese es el problema. – Wezelkrozum

+1

Lamento escuchar eso ... Etiquetarme cuando publique datos nuevos, lo ayudaré si puedo. – Sam

+1

He actualizado la pregunta con un archivo de registro – Wezelkrozum

1

Sé que esta pregunta es un poco vieja, pero tuve el mismo problema yo mismo. Descubrí que si trataba de declarar la variable Calendario fuera del método, no funcionaría bien y las alarmas se dispararían temprano. Debido a que su clase se reduce, es difícil decir exactamente a dónde llama la instancia del calendario.

Si lo configuro como tal, entonces sería disparar en el momento justo:

protected void nextAlarm(Context context, int seconds){ 
    Calendar nextAlarm = Calendar.getInstance(); 

    Intent intent = new Intent(context, MyClass.class); 
    PendingIntent pending = PendingIntent.getBroadcast(context, MainActivity.REPEATING_ALARM, intent, PendingIntent.FLAG_CANCEL_CURRENT); 

    AlarmManager amanager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); 
    nextAlarm.add(Calendar.SECOND, seconds); 

    amanager.set(AlarmManager.RTC_WAKEUP, nextAlarm.getTimeInMillis(), pending); 

} 
+1

Para ser sincero, yo soy esa no es la solución. Soy crear el calendario dentro del método. Pero veo una diferencia en la forma en que recuperamos nuestro PendingIntent. Usas el método getBroadcast mientras estoy usando el método getService. – Wezelkrozum

1

Asegúrese onStartCommand de su servicio devuelve START_NOT_STICKY, de lo contrario será automáticamente volviendo a intentar:

public class UpdateKlasRoostersService extends Service { 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     buildUpdate(); 
     return START_NOT_STICKY; 
    } 
} 
+1

¿Esto significa que mi servicio sigue intentando comenzar? – Wezelkrozum

Cuestiones relacionadas