Ich mache eine Statusleisten-Benachrichtigung in meiner Android-App, die von c2dm ausgelöst wird. Ich möchte die Benachrichtigung nicht anzeigen, wenn die App ausgeführt wird. Wie stellen Sie fest, ob die App ausgeführt wird und im Vordergrund steht?
android
android-activity
Andrew Thomas
quelle
quelle
Antworten:
Machen Sie eine globale Variable wie
private boolean mIsInForegroundMode;
und weisen Sie einenfalse
Wert inonPause()
und einentrue
Wert in zuonResume()
.Beispielcode:
quelle
Alternativ können Sie anhand der Methode überprüfen,
ActivityManager
welche Aufgaben ausgeführt werdengetRunningTasks
. Überprüfen Sie dann mit der ersten Aufgabe (Aufgabe im Vordergrund) in der zurückgegebenen Liste der Aufgaben, ob es sich um Ihre Aufgabe handelt.Hier ist das Codebeispiel:
Vergessen Sie nicht, die
GET_TASKS
Berechtigung in die Datei manifest.xml einzufügen, um diegetRunningTasks()
Methode im obigen Code ausführen zu können:p / s: Wenn Sie auf diese Weise zustimmen, beachten Sie bitte, dass diese Erlaubnis jetzt veraltet ist.
quelle
toString()
eines von zurückgegebenen StringsgetPackageName()
ist redundant. Da wir nur an der ersten Aufgabe interessiert sind, die von zurückgegeben wirdgetRunningTasks()
, können wir1
stattdessen bestehenInteger.MAX_VALUE
.Dies ist ein ziemlich alter Beitrag, aber immer noch ziemlich relevant. Die oben akzeptierte Lösung funktioniert möglicherweise, ist aber falsch. Wie Dianne Hackborn schrieb:
Diese APIs sind nicht für Anwendungen gedacht, auf denen der UI-Fluss basiert, sondern um dem Benutzer beispielsweise die ausgeführten Apps oder einen Task-Manager oder dergleichen anzuzeigen.
Ja, für diese Dinge wird eine Liste gespeichert. Es ist jedoch in einem anderen Prozess deaktiviert, der von Threads verwaltet wird, die getrennt von Ihren ausgeführt werden, und nicht etwas, auf das Sie zählen können, wenn Sie (a) rechtzeitig die richtige Entscheidung treffen oder (b) bei Ihrer Rückkehr ein konsistentes Bild haben. Außerdem wird die Entscheidung darüber, zu welcher "nächsten" Aktivität Sie gehen möchten, immer an dem Punkt getroffen, an dem der Wechsel stattfinden soll, und erst an genau diesem Punkt (an dem der Aktivitätsstatus kurz gesperrt wird, um den Wechsel durchzuführen) treffen wir weiß eigentlich dafür was das nächste sein wird.
Und die Implementierung und das globale Verhalten hier können in Zukunft nicht garantiert gleich bleiben.
Die richtige Lösung besteht darin, Folgendes zu implementieren: ActivityLifeCycleCallbacks .
Dies erfordert grundsätzlich eine Anwendungsklasse, und der Handler kann dort eingerichtet werden, um den Status Ihrer Aktivitäten in der App zu ermitteln.
quelle
onPause
undonResume
Methode?Wie Vinay sagt, ist die wahrscheinlich beste Lösung (um neuere Android-Versionen ab 14 zu unterstützen) die Verwendung
ActivityLifecycleCallbacks
in derApplication
Klassenimplementierung.Und in der Anwendungsmethode
onCreate()
:Dann
ApplicationLifecycleManager.isAppVisible()
oderApplicationLifecycleManager.isAppInForeground()
würde verwendet, um den gewünschten Zustand zu kennen.quelle
Seit API 16 können Sie dies folgendermaßen tun:
quelle
Zu Ihrer Information, wenn Sie eine Gadenkan-Lösung verwenden (was großartig ist !!), vergessen Sie nicht, diese hinzuzufügen
zum Manifest.
quelle
Leicht bereinigte Version der Gadenkan-Lösung . Setzen Sie es eine beliebige Aktivität oder vielleicht eine Basisklasse für alle Ihre Aktivitäten.
Um anrufen zu können
getRunningTasks()
, müssen Sie Folgendes hinzufügenAndroidManifest.xml
:Beachten Sie jedoch, was
ActivityManager.getRunningTasks()
Javadoc sagt:Update (Februar 2015)
Beachten Sie, dass
getRunningTasks()
wurde in API - Ebene 21 ist veraltet !Was ich früher geschrieben habe, ist also noch relevanter:
In vielen Fällen können Sie wahrscheinlich eine bessere Lösung finden. Zum Beispiel etwas in
onPause()
undonResume()
vielleicht in einer BaseActivity für alle Ihre Aktivitäten tun.(In unserem Fall wollten wir nicht, dass eine Offline-Warnaktivität gestartet wird, wenn wir nicht im Vordergrund stehen. In BaseActivity melden
onPause()
wir uns einfach vom RxJava ab und warten auf das SignalSubscription
"ging offline".)quelle
Nach Gadenkans Antwort brauchte ich so etwas, damit ich feststellen konnte, ob meine App nicht im Vordergrund lief, aber ich brauchte etwas, das app-weit war und nicht das Setzen / Deaktivieren von Flags in meiner gesamten Anwendung erforderte.
Gadenkans Code hat den Nagel auf den Kopf getroffen, aber er war nicht in meinem eigenen Stil und hatte das Gefühl, dass er aufgeräumter sein könnte, also hat er sich in meiner App darauf reduziert.
(Randnotiz: Sie können einfach das! Entfernen, wenn der Scheck umgekehrt funktionieren soll.)
Obwohl Sie bei diesem Ansatz die
GET_TASKS
Erlaubnis benötigen .quelle
Wenn Sie die Support-Bibliothek Version 26 starten , können Sie mit ProcessLifecycleOwner den aktuellen Status der App ermitteln. Fügen Sie ihn einfach zu Ihren Abhängigkeiten hinzu, wie hier beschrieben , zum Beispiel:
Jetzt können Sie abfragen,
ProcessLifecycleOwner
wann immer Sie den App-Status überprüfen möchten. Um beispielsweise zu überprüfen, ob die App im Vordergrund ausgeführt wird, müssen Sie nur Folgendes tun:quelle
Basierend auf den verschiedenen Antworten und Kommentaren finden Sie hier eine ausführlichere Version, die Sie einer Hilfsklasse hinzufügen können:
Wie in anderen Antworten erwähnt, müssen Sie die folgende Berechtigung zu Ihrer hinzufügen
AndroidManifest.xml
.quelle
Ich möchte hinzufügen, dass eine sicherere Möglichkeit, dies zu tun, als zu überprüfen, ob sich Ihre App im Hintergrund befindet, bevor eine Benachrichtigung erstellt wird, darin besteht, den Broadcast-Empfänger onPause () bzw. onResume () zu deaktivieren und zu aktivieren.
Diese Methode gibt Ihnen mehr Kontrolle über die eigentliche Anwendungslogik und wird sich in Zukunft wahrscheinlich nicht ändern.
quelle
Ich habe eine einfachere und genauere Möglichkeit gefunden, um zu überprüfen, ob sich die Anwendung im Vordergrund oder im Hintergrund befindet, indem ich die Aktivitäten einem Booleschen Wert zugeordnet habe.
Überprüfen Sie das komplette Wesentliche hier
quelle
Hier ist der Code für eine schöne einfache Lösung, die oben von @ user2690455 beschrieben wurde. Obwohl es ein bisschen ausführlich aussieht, werden Sie sehen, dass es insgesamt ziemlich leicht ist
In meinem Fall verwenden wir auch AppCompatActivity, daher musste ich 2 Basisklassen haben.
quelle
Dies ist nur dann nützlich, wenn Sie eine Aktion ausführen möchten, sobald Ihre Aktivität beginnt, und wenn Sie überprüfen möchten, ob sich die App im Vordergrund oder im Hintergrund befindet.
Anstatt Activity Manager zu verwenden, gibt es einen einfachen Trick, den Sie über Code ausführen können. Wenn Sie den Aktivitätszyklus genau beobachten, ist der Fluss zwischen zwei Aktivitäten und Vordergrund zu Hintergrund wie folgt. Angenommen, A und B sind zwei Aktivitäten.
Beim Übergang von A nach B: 1. onPause () von A heißt 2. onResume () von B heißt 3. onStop () von A wird aufgerufen, wenn B vollständig wieder aufgenommen wird
Wenn die App in den Hintergrund tritt: 1. onPause () von A wird aufgerufen 2. onStop () von A wird aufgerufen
Sie können Ihr Hintergrundereignis erkennen, indem Sie einfach ein Flag in die Aktivität setzen.
Erstellen Sie eine abstrakte Aktivität und erweitern Sie sie von Ihren anderen Aktivitäten, sodass Sie den Code für alle anderen Aktivitäten nicht kopieren und einfügen müssen, wo immer Sie ein Hintergrundereignis benötigen.
In abstrakten Aktivitäten erstellen Flag isAppInBackground.
In der onCreate () -Methode: isAppInBackground = false;
In der onPause () -Methode: isAppInBackground = false;
In der onStop () -Methode: isAppInBackground = true;
Sie müssen nur in onResume () einchecken, ob isAppInBackground wahr ist. n Nachdem Sie Ihr Flag überprüft haben, setzen Sie erneut isAppInBackground = false
Beim Übergang zwischen zwei Aktivitäten wird onSTop () von first immer wieder aufgerufen, nachdem die zweite Aktivität wieder aufgenommen wurde. Das Flag ist niemals wahr. Wenn sich die App im Hintergrund befindet, wird onStop () der Aktivität unmittelbar nach onPause aufgerufen, und daher ist das Flag true, wenn Sie öffnen die App später.
Bei diesem Ansatz gibt es jedoch noch ein weiteres Szenario. Wenn einer Ihrer App-Bildschirme bereits geöffnet ist und Sie das Handy in den Leerlauf versetzen, wechselt das Handy nach einiger Zeit in den Ruhemodus. Wenn Sie das Handy entsperren, wird es beim Hintergrundereignis behandelt.
quelle
Hier ist eine Methode, die ich verwende (und die unterstützende Methode):
quelle
Hierfür gibt es keinen globalen Rückruf, aber für jede Aktivität ist es onStop (). Sie müssen sich nicht mit einem atomaren Int anlegen. Haben Sie einfach ein globales int mit der Anzahl der gestarteten Aktivitäten, inkrementieren Sie es in jeder Aktivität in onStart () und dekrementieren Sie es in onStop ().
Folgen Sie diesem
quelle
quelle
Die hier genannten bisherigen Ansätze sind nicht optimal. Der aufgabenbasierte Ansatz erfordert eine Berechtigung, die möglicherweise nicht erwünscht ist, und der "Boolesche" Ansatz ist anfällig für gleichzeitige Änderungsfehler.
Der Ansatz, den ich verwende und der (glaube ich) in den meisten Fällen recht gut funktioniert:
Verwenden Sie eine "MainApplication" -Klasse, um die Anzahl der Aktivitäten in AtomicInteger zu verfolgen :
Und erstellen Sie eine Basis-Aktivitätsklasse, die andere Aktivitäten erweitern würden:
quelle