7

Ho creato un'app che funzionava sempre fino ad Android 6.0. Penso che sia la funzione Doze che non permette al mio allarme di sparare.Problema di Alarm Manager in Android 6.0 Modalità Doze

Io uso sharedpreferences di gestire le opzioni:

//ENABLE NIGHT MODE TIMER 
    int sHour = blockerTimerPreferences.getInt("sHour", 00); 
    int sMinute = blockerTimerPreferences.getInt("sMinute", 00); 

    Calendar sTime = Calendar.getInstance(); 
    sTime.set(Calendar.HOUR_OF_DAY, sHour); 
    sTime.set(Calendar.MINUTE, sMinute); 

    Intent enableTimer = new Intent(context, CallReceiver.class); 
    enableTimer.putExtra("activate", true); 
    PendingIntent startingTimer = PendingIntent.getBroadcast(context, 11002233, enableTimer, PendingIntent.FLAG_UPDATE_CURRENT); 
    AlarmManager sAlarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
    sAlarm.setRepeating(AlarmManager.RTC_WAKEUP, 
      sTime.getTimeInMillis(), 
      AlarmManager.INTERVAL_DAY, startingTimer); 

Qualsiasi indizio di che cosa è male qui?

Questa è un'applicazione per bloccare le chiamate. Grazie!

EDIT: Ho 3 file (di più, ma ...), come:

MainActivity (All code) 
CallReceiver (Broadcast that triggers the alarm again (reboot etc)) 
CallReceiverService (Handles the call/phone state) 
+1

Usa 'dumpsys adb shell alarm' per confermare che la sveglia è in programma. Si noti che 'setRepeating()' è inesatto su Android 4.4+. "Questo sta causando anche il consumo della batteria" - sembra improbabile. Il codice che non funziona non dovrebbe consumare batteria. – CommonsWare

+0

Ciao @CommonsWare, 52 riattivi e 52 allarmi ... Fa sempre scattare gli allarmi. 'setRepeating()' sparerà in quel minuto, nessun problema penso. – FilipeOS

+0

@FilipeOS Hai fatto funzionare? Possiamo implementare alarmManager.setRepeating() nella modalità doze? – devgeek

risposta

13

La modalità Doze ritarderà l'allarme fino alla successiva finestra di manutenzione. Per evitare che Doze mode blocchi la sveglia, è possibile utilizzare setAndAllowWhileIdle(), setExactAndAllowWhileIdle() o setAlarmClock(). Avrete circa 10 secondi per eseguire il codice e impostare il vostro prossimo allarme (non più di una volta per 15 minuti per i metodi con _AndAllowWhileIdle però)

Se si desidera verificare la modalità Doze, è possibile utilizzare ADB command:

  1. Configurare un dispositivo hardware o dispositivo virtuale con un'immagine di sistema Android 6.0 (livello di API 23) o superiore.

  2. Collegare il dispositivo al computer di sviluppo e installare l'app.

  3. Esegui la tua app e lasciala attiva.
  4. Spegnere lo schermo del dispositivo. (L'applicazione rimane attiva.) forzare il sistema per passare da modalità Doze eseguendo i seguenti comandi:

    adb shell dumpsys battery unplug

    adb shell dumpsys deviceidle step

  5. potrebbe essere necessario eseguire il secondo comando più di una volta. Ripeti fino a quando lo stato del dispositivo diventa inattivo.

  6. Osservare il comportamento della propria app dopo aver riattivato il dispositivo. Assicurati che l'app si ripristini correttamente quando il dispositivo esce da Doze.

Edit: Aggiungere esempio setAlarmClock

Non dimenticare di controllare il livello di SDK (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)

AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE); 
Intent intent = new Intent(this, MyAlarmReceiver.class); //or just new Intent() for implicit intent 
//set action to know this come from the alarm clock 
intent.setAction("from.alarm.clock"); 
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 
//Alarm fire in 5s. 
am.setAlarmClock(new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + 5000, pi), pi); 
+0

Ciao @xiaomi, basta sostituire 'setRepeating' per' setAlarmClock'? Con gli stessi parametri? Puoi per favore fare un esempio? Grazie! – FilipeOS

+0

Modifica la mia risposta, ma questa non è molto diversa dalle altre modalità di allarme. – xiaomi

+0

Questo è solo un esempio per far scattare un allarme dopo 5 secondi. Scegli l'ora che vuoi. – xiaomi

1

Se il dispositivo è in modalità di dormiveglia, è necessario utilizzare una di queste API: setExactAndAllowWhileIdle o setAndAllowWhileIdle.

Nota che non esiste alcuna API per svegliare il dispositivo mentre sei in modalità doze per un allarme ripetuto, quindi se hai bisogno di un allarme ripetuto per riattivare il dispositivo mentre sei in doze, devi utilizzare le API sopra e re-armare il timer ad ogni occorrenza dell'avvio del timer.

Problemi correlati