2014-07-13 13 views
10

Utilizzo di Android 19+AlarmManager setExact con WakefulBroadcastReceiver a volte non è esatta

setExact in congiunzione con WakefulBroadcastReceiver a volte non si attiva in tempo (può essere un paio di secondi o così tardi). Intendo la maggior parte del tempo che fa. probabilmente 49 volte su 50 è corretto.

non sono sicuro se il suo solo perché il sistema è occupato al momento e non è in grado di gestire il carico di lavoro o che cosa

Ecco come ho impostato la sveglia:

AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); 
    Intent intent = new Intent(AlarmReceiver.INTENT_FILTER); 
    PendingIntent alarmIntent = PendingIntent.getBroadcast(context, MyApplication.ALARM_REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
    alarmMgr.setExact(AlarmManager.RTC_WAKEUP, timeToWakeUp, alarmIntent); 

Qui è il mio codice ricevitore:

public class AlarmReceiver extends WakefulBroadcastReceiver { 

public static final String INTENT_FILTER = "myfilter"; 

@Override 
public void onReceive(Context context, Intent intent) { 
    Intent service = new Intent(context, MyWakefulService.class); 
    startWakefulService(context, service); 

} 

} 

E nel WakefulService

public class MyWakefulService extends IntentService { 

.... 

@Override 
protected void onHandleIntent(Intent intent) { 

.... 
+0

Quando si sta calcolando il tempo per timeToWakeUp, stai riportano i secondi e millesimi di secondo a 0? – JDJ

+0

@JDJ ho impostato i secondi di conseguenza, però io non impostare il millisecondi. i Proverò che – MobileMon

+0

@JDJ, credo che impostare i millisecondi rende il timer ancora più preciso, grazie per questo, ma non risolve il problema a portata di mano . Sono abbastanza sicuro che è solo perché il sistema è così occupato che l'evento non può sparare in quel momento esatto. Perché succede sempre se riavvio il dispositivo e pianifico l'allarme prima che l'avvio sia terminato. Ovviamente non è l'unica volta che c'è un ritardo, ma penso che lo scriverò fino a sistema occupato a meno che non senta il contrario – MobileMon

risposta

8

Questo comportamento viene aggiunto in API 19:

iniziano con API 19 (KitKat) consegna allarme è inesatta: il sistema operativo si sposterà gli allarmi al fine di minimizzare wakeups e l'uso della batteria. Ci sono nuove API per supportare applicazioni che richiedono rigide garanzie di consegna; vedi setWindow(int, long, long, PendingIntent) e setExact(int, long, PendingIntent). Le applicazioni con targetSdkVersion precedente all'API 19 continueranno a vedere il comportamento precedente in cui tutti gli allarmi vengono recapitati esattamente quando richiesto.

da AlarmManager.

Importante: setExact() non ha ancora per l'esattezza, come lo stato docs:

L'allarme saranno consegnati il ​​più vicino possibile al tempo di attivazione richiesto.

+0

Questo è sbagliato. set() è ora inesatto. Tuttavia, hanno aggiunto setExact() per quando è necessario essere esatti (API 19+) – MobileMon

+1

Sì, è per questo che è stato aggiunto il secondo paragrafo. Può ancora essere inesatto, viene consegnato ** il più vicino possibile **. – Manu

+0

Tutto ciò che hai detto aiuta, ma ancora ogni tanto non funzionerà (10 secondi circa). è solo perché il sistema è occupato ??? Non vedo altri motivi – MobileMon

23

Per Marshmallow era (?), Abbiamo bisogno di alcuni codici di brutto come di seguito ... :( E "delayInMillis" param dovrebbero essere più di 15 minuti a l'API 23. In caso contrario, il sistema ignora i minuti meno di 15 minuti.

private void registerExactAlarm(PendingIntent sender, long delayInMillis) { 
    final int SDK_INT = Build.VERSION.SDK_INT; 
    AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE); 
    long timeInMillis = (System.currentTimeMillis() + delayInMillis)/1000 * 1000;  //> example 

    if (SDK_INT < Build.VERSION_CODES.KITKAT) { 
     am.set(AlarmManager.RTC_WAKEUP, timeInMillis, sender); 
    } 
    else if (Build.VERSION_CODES.KITKAT <= SDK_INT && SDK_INT < Build.VERSION_CODES.M) { 
     am.setExact(AlarmManager.RTC_WAKEUP, timeInMillis, sender); 
    } 
    else if (SDK_INT >= Build.VERSION_CODES.M) { 
     am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeInMillis, sender); 
    } 
} 
+0

Ciao, da dove hai preso che triggerAtMillis (timeInMillis) dovrebbe essere superiore a 15 minuti? Non riesco a trovare alcuna documentazione in merito. grazie – Loebre

+0

E se posso un'altra domanda, perché non usi il setExact (...) per Build.VERSION> M? Grazie al metodo – Loebre

+0

@Loebre "setExact" non si imposta più esattamente il timer su Mashmellow. Se vuoi essere richiamato alle 07:00 e usare il metodo "setEaxct". Il sistema non ti chiama alle 07:00 quando sei in modalità DOZE. Penso che dovresti leggere alcuni documenti su DOZE. – cmcromance

Problemi correlati