2015-08-12 14 views
13

Quindi ho un BroadcastReceiver e AlarmManager.AlarmManager non esegue sempre BroadcastReceiver

Diciamo che creo le Intenti in sospeso in questo modo:

Intent i; 
i = new Intent(context, MyReceiver.class); 
i.setAction(MyReceiver.ACTION_1); 
i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 
pendingIntent1 = PendingIntent.getBroadcast(context, 1, i, PendingIntent.FLAG_UPDATE_CURRENT); 

i = new Intent(context, MyReceiver.class); 
i.setAction(MyReceiver.ACTION_2); 
i.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 
pendingIntent2 = PendingIntent.getBroadcast(context, 2, i, PendingIntent.FLAG_UPDATE_CURRENT); 

e programmare gli allarmi in questo modo:

now = SystemClock.elapsedRealtime(); 
long time1 = now + 10 * 1000; 
long time2 = time1 + 60 * 1000; 

am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, time1, pendingIntent1); 
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, time2, pendingIntent2); 

ora sto sperimentando che il mio ricevitore trasmissione ottiene la trasmissione per ACTION_1 abbastanza affidabile , mentre ACTION_2 spesso non viene consegnato. Quindi, onReceive viene eseguito raramente o mai con un intento che mantiene l'azione ACTION_2. Come mai? Ho pensato, *_WAKEUP si assicura che le trasmissioni vengano consegnate comunque?

[Aggiornamento 15/09/2015] - Per scopi di test, sto tentando di stampare un messaggio di registro nel mio metodo onReceive. Continua a non funzionare. - Ho provato a utilizzare setExact su AlarmManager ora. Continua a non funzionare. - Ho anche provato a usare WakefulBroadcastReceiver. Continua a non funzionare. - Ho scoperto, tuttavia, che il dispositivo si attiva in modo affidabile quando è in stato di carica della batteria. Cosa potrebbe causare questo problema? Ho letto ovunque che i ricevitori delle trasmissioni siano garantiti per essere eseguiti se attivati ​​dal gestore degli allarmi tramite un intento in sospeso (e senza fare troppa roba in onReceive). Ho forse qualche politica aggressiva di risparmio energetico sul mio telefono che non posso davvero lavorare contro (senza acquisire un lungo wake-lock, vedere i commenti)?

[Aggiornamento 09/19/2015] Ho appena provato un'app sveglia (https://play.google.com/store/apps/details?id=com.alarmclock.xtreme.free) su Google Play e non riavvia in modo affidabile il telefono. Immagino, è davvero un bug e non per colpa mia. Mi limiterò alla soluzione wake lock, suppongo.

+0

qual è il valore di 'showAt'? –

+0

Oups mi dispiace, risolto. Doveva essere "time1". L'app è fondamentalmente dedicata alla visualizzazione di una finestra di dialogo (in un'attività trasparente) dopo un po 'di tempo in cui lo schermo si è spento (in questo caso 10 secondi) e lo nasconde di nuovo, se lo schermo era spento troppo a lungo (qui 10 + 60 = 70 secondi). – flxapps

+0

Ho risolto il mio problema acquisendo un wake lock in questo modo: 'wakeLock.acquire (time2 - now + 5000);' (mantenendo il telefono sveglio per - nell'esempio superiore - 70 secondi più 5 secondi come buffer) - Tuttavia, ritengo che questa sia una soluzione piuttosto hacky. Cosa ne pensi? È legittimo o troppo sporco, probabilmente causa problemi? – flxapps

risposta

6

Ho riscontrato lo stesso problema, la soluzione che ho trovato è creare l'intento solo tramite la stringa di azioni e registrare l'azione del destinatario in manifest. provare a cambiare l'intento di qualcosa di simile:

i = new Intent("com.app.ACTION_ONE"); 

poi nel file manifest aggiungere al ricevitore quanto segue:

<intent-filter> 
    <action android:name="com.app.ACTION_ONE" /> 
</intent-filter> 

La mia ipotesi è se non registrare almeno 1 azione al recevier lui muore appena termina l'applicazione.

Spero che funzioni, buona fortuna.

+0

Ancora non funziona. :/Un'altra nota a margine: se pianifico la prima trasmissione per es. 3 secondi dopo aver spento lo schermo, spesso viene eseguito dopo aver acceso di nuovo lo schermo (dopo che ho già aspettato come 10 secondi, comunque). – flxapps

2

Avete registrato BroadcastReceiver (o dal manifest)?

registerReceiver(new MyReceiver(), new IntentFilter(MyReceiver.class.getName())); 

ho usato l'ultima volta quasi gli stessi metodi, ma con AlarmManager.RTC_WAKEUP - se non si vuole svegliare il dispositivo dal sonno profondo, utilizzare AlarmManager.RTC

long time = System.currentTimeMillis() + 10*1000; 
alarmMgr.set(AlarmManager.RTC_WAKEUP, time, alarmIntent); 

L'alarmIntent come:

alarmIntent = PendingIntent.getBroadcast(this, 0, new Intent(MyReceiver.class.getName()), PendingIntent.FLAG_CANCEL_CURRENT); 
1

C'è poche cose che potrebbe essere utile notare:

  1. Si utilizza AlarmManager.set() metodo di strega pretende molto Non garantiamo il termine di consegna, se si vuole avere l'allarme deve essere attivato al momento esatto uso AlarmManager.setExact()

  2. È trasmettere intenti non ha senso per me. È implicito, ma non si suppone che le trasmissioni siano. Tale intento potrebbe essere utilizzato per strani comportamenti di androide. Se si desidera avere un intento implicito, inviarlo direttamente al servizio che lo gestisce. Nel caso in cui il ricevitore mi sento di raccomandare di utilizzare:

    Intent intent = new Intent(Contants.Action1); 
    
  3. Se il ricevitore è definita in intenti manifesto sarà consegnato anche se tutte le attività della vostra applicazione sono morti, se il ricevitore registrato dynamicly può ricevere solo intenti mentre il thread su quello che è stato confezionato è vivo.

  4. Versioni diverse di Android che tentano di ottimizzare gli allarmi in modo leggermente diverso, ma l'obiettivo è di attivare il numero di allarmi più posible allo stesso tempo per ottenere prestazioni della batteria migliori.

Tutto questo può essere abbastanza confuso. Ma gli intenti sono garantiti per essere consegnati, se il ricevitore è registrato correttamente.

+0

Ciao, grazie per la tua risposta. 1. Ho già cambiato il mio codice usando 'setExact' per' Build.VERSION.SDK_INT> = Build.VERSION_CODES.KITKAT'. 2. Ho già cambiato il mio codice usando 'new Intent (MyReceiver.ACTION_1);'. 3. Il mio ricevitore è attualmente definito in manifest (ho provato entrambi).~~ Beh, la mia esperienza, tuttavia, è a questo punto, che non sono garantiti per essere consegnati correttamente. Attualmente do la colpa a qualche rigida politica di risparmio energetico di Sony per il mio problema, ma non ne sono sicuro. Controlla anche la mia modifica: potrei riprodurre il comportamento scorretto con un'app di allarme. – flxapps

0

Dai un'occhiata alle impostazioni di "Stamina Mode" sui tuoi dispositivi Sony. Prova a disabilitare la modalità Stamina o aggiungi la tua app alla whitelist delle app consentite quando la modalità resistenza è attiva.

Spero che questo aiuti.

Problemi correlati