Android - come widget di aggiornamento spesso, ma solo quando è visibile?
-
19-09-2019 - |
Domanda
ho intenzione di creare widget di che ha bisogno di aggiornare il suo contenuto di ogni minuto (che mostra i dati relativi al tempo).
Tuttavia, non v'è alcuna necessità di aggiornare widget di se è attualmente invisibile, che vuol dire:
- schermo è spento
- un'altra applicazione è in esecuzione
- widget viene posizionato su un altro (invisibile) scheda della schermata iniziale
Qual è il modo migliore per aggiornare solo widget di visibile ogni minuto - senza svegliare dispositivo né effettuare i calcoli inutili? Dopo widget di diventa visibile, piccolo ritardo prima dell'aggiornamento è accettabile.
Soluzione
Per evitare di aggiornamento quando lo schermo è spento, utilizzare il AlarmManager per programmare un allarme ricorrente che non WakeUp il telefono.
Gli altri due punti elenco che hai nella tua domanda non sono possibili. Non v'è alcun modo per rilevare se il widget è su una schermata iniziale che non è attualmente visibile, e non v'è alcun modo per determinare se un applicazione è in esecuzione che si nasconde nella schermata iniziale. Ho presentato un biglietto su http://b.android.com richiedere questa funzionalità da aggiungere ad Android. Se ti senti come interpretato da esso, lo aiuterà guadagnare priorità: http://code.google.com/p/android/issues/detail?id=5529&q=reporter:mark.r.baird&colspec=ID%20Type % 20Status% 20Owner% 20Summary% 20Stars
Altri suggerimenti
- È possibile chiedere al PowerManager circa isScreenOn ()
- È possibile registrarsi per Intent ACTION_SCREEN_OFF / ACTION_SCREEN_ON e trasformarvi timer on / off di conseguenza.
Il solo fatto che la risposta di cui sopra, relativa alla AlarmManager è corretta potrebbe non essere sufficiente in quanto ho osservato molti telefoni che forniscono anche gli allarmi, anche se non sono di tipo * _WAKEUP. Questo può accadere se ci sono altre applicazioni installate che stanno svegliando il dispositivo. E se è una volta svegli, offre tutti gli allarmi pendenti.
Ho trovato questo nell'ambito di un progetto denominato 24clock nel codice Goole . Si cerca di non aggiornare il widget mentre l'utente è lontano da casa:
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> runningTasks = am.getRunningTasks(2);
for (RunningTaskInfo t : runningTasks) {
if (t != null && t.numRunning > 0) {
ComponentName cn = t.baseActivity;
if (cn == null) continue;
String clz = cn.getClassName();
String pkg = cn.getPackageName();
// TODO make this configurable
if (pkg != null && pkg.startsWith("com.android.launcher")) {
return true;
}
return false;
}
}
Potrebbe essere una risposta per voi requisito 2 #. Anche se potrebbe non funzionare con altri lanciatori 3rd party.
== Aggiornamento ==
Qualche mese più tardi, improvvisamente hanno un'idea nella mia mente su come rilevare se schermata iniziale sta mostrando. L'ho messo nel mio blog , e mi sono imbattuto testare il mio desiderio e funziona benissimo. Il metodo è di interrogare l'Android per tutti i pacchetti installati che uno di esso contiene l'abilità "avvio", e quindi verificare se sia nella parte alta della pila esecuzione. Se qualcuno ha testato per favore fatemelo sapere il risultato, così, dal momento che non ho accesso ad altri dispositivi Android.
La risposta accettata dalla mbaird colpisce il chiodo sulla testa. Il metodo proposto onVisivilityChange()
, se attuata, dovrebbe coprire tutti i casi di cui sopra.
Nel frattempo questo è ancora un problema reale per alcuni tipi di widget. Jom ha introdotto la possibilità di registrare per ricevere ACTION_SCREEN_OFF intenti / ACTION_SCREEN_ON. Questo è utile perché basandosi su un allarme non sveglia ricorrente non è sufficiente come altri servizi di fare causa wakeups. E 'difficile perché tali azioni non possono essere sottoscritte tramite AndroidManifest.xml e un AppWidgetProvider non è permesso di chiamare context.registerReceiver()
. Questi temi sono affrontati in diverse altre questioni, tra cui StackOverflow Ascolto per ACTION_SCREEN_OFF , android.intent.action.SCREEN_ON doesn 't funziona come ricevitore intento filtro e Android -?. come ricevere gli intenti di trasmissione ACTION_SCREEN_ON / OFF
sono riuscito a sottoscrivere ACTION_SCREEN_OFF intenti / ACTION_SCREEN_ON in un widget con la creazione di un'istanza sussidiaria Purtroppo, naturalmente, questo non riuscirà se e quando l'applicazione è mai ucciso. BroascastReceiver
e utilizzando context.getApplicationContext().registerReceiver()
per registrarlo. Questa potrebbe essere barare e, almeno in alcune successivo rilascio di Android, potrebbe non riuscire in fase di registrazione o forse, quest'ultimo non potrà consegnati gli eventi. Ho codificato per gestire questi casi, ma per ora funziona.
Un'altra possibilità è quella di utilizzare un isHomeScreenShowing()
tipo di procedimento, come descritto qui , a cui fa riferimento la risposta di Xandy. Le idee ci potrebbe probabilmente essere ottimizzati mettendo in cache l'elenco generato delle applicazioni installate CATEGORY_HOME
e l'ascolto di ACTION_PACKAGE_ADDED / cambiato trasmissioni / rimosso per aggiornarlo.
La mia strategia è:
- Prova per evitare di essere chiamato (tramite un allarme ripetizione) quando non è visibile.
- Quando si chiama, controllare lo stato dello schermo e altri indicatori di visibilità prima di fare qualsiasi cosa costosa.
- Solo allora richiamare un
IntentService
per gestire il lavoro relativamente costosi, che include una connessione di rete persistente. Ciò è necessario per monitorare lo stato di un servizio remoto in tempo reale.