Ich versuche, eine App zu schreiben, die etwas Bestimmtes tut, wenn sie nach einiger Zeit wieder in den Vordergrund gerückt wird. Gibt es eine Möglichkeit zu erkennen, wann eine App in den Hintergrund gesendet oder in den Vordergrund gestellt wird?
android
background
foreground
iHorse
quelle
quelle
Antworten:
Die Methoden
onPause()
undonResume()
werden aufgerufen, wenn die Anwendung wieder in den Hintergrund und in den Vordergrund gerückt wird. Sie werden jedoch auch aufgerufen, wenn die Anwendung zum ersten Mal gestartet wird und bevor sie beendet wird. Weitere Informationen finden Sie unter Aktivität .Es gibt keinen direkten Ansatz, um den Anwendungsstatus im Hintergrund oder im Vordergrund abzurufen, aber selbst ich habe mich diesem Problem gestellt und die Lösung mit
onWindowFocusChanged
und gefundenonStop
.Weitere Informationen finden Sie hier. Android: Lösung, um zu erkennen, wann eine Android-App in den Hintergrund tritt und ohne getRunningTasks oder getRunningAppProcesses wieder in den Vordergrund zurückkehrt .
quelle
2018: Android unterstützt dies nativ über Lebenszykluskomponenten.
März 2018 UPDATE : Es gibt jetzt eine bessere Lösung. Siehe ProcessLifecycleOwner . Sie müssen die neuen Architekturkomponenten 1.1.0 (aktuell zu diesem Zeitpunkt) verwenden, diese wurden jedoch speziell dafür entwickelt.
Diese Antwort enthält ein einfaches Beispiel , aber ich habe eine Beispiel-App und einen Blog-Beitrag darüber geschrieben.
Seit ich das 2014 geschrieben habe, sind verschiedene Lösungen entstanden. Einige funktionierten, andere funktionierten , hatten aber Fehler (einschließlich meiner!) Und wir als Community (Android) lernten, mit den Konsequenzen zu leben, und schrieben Problemumgehungen für die Sonderfälle.
Gehen Sie niemals davon aus, dass ein einziger Codeausschnitt die Lösung ist, nach der Sie suchen. Dies ist unwahrscheinlich. Besser noch, versuchen Sie zu verstehen, was es tut und warum es es tut.
Die
MemoryBoss
Klasse wurde von mir nie so verwendet, wie hier geschrieben, es war nur ein Stück Pseudocode, der zufällig funktionierte.Wenn es keinen triftigen Grund für Sie gibt, die neuen Architekturkomponenten nicht zu verwenden (und es gibt einige, insbesondere wenn Sie auf super alte APIs abzielen), fahren Sie fort und verwenden Sie sie. Sie sind alles andere als perfekt, aber sie waren es auch nicht
ComponentCallbacks2
.UPDATE / NOTES (November 2015) : Die Leute haben zwei Kommentare abgegeben. Erstens
>=
sollte diese verwendet werden, anstatt,==
weil in der Dokumentation angegeben ist, dass Sie nicht nach genauen Werten suchen sollten . Dies ist in den meisten Fällen in Ordnung, aber denken Sie daran, dass Sie == verwenden und es auch mit einer anderen Lösung (wie Activity Lifecycle-Rückrufen) oder Ihnen kombinieren müssen , wenn Sie nur etwas tun möchten, wenn die App in den Hintergrund tritt möglicherweise nicht den gewünschten Effekt erzielen. Das Beispiel (und das ist mir passiert) ist das, wenn Sie sperren möchtenWenn Ihre App mit einem Kennwortbildschirm in den Hintergrund tritt (wie 1Password, wenn Sie damit vertraut sind), können Sie Ihre App versehentlich sperren, wenn Ihnen der Arbeitsspeicher ausgeht und Sie plötzlich darauf testen>= TRIM_MEMORY
, da Android einenLOW MEMORY
Anruf auslöst höher als deins. Seien Sie also vorsichtig, wie / was Sie testen.Darüber hinaus haben einige Leute gefragt, wie Sie erkennen können, wann Sie zurückkommen.
Der einfachste Weg, den ich mir vorstellen kann, wird unten erklärt, aber da einige Leute damit nicht vertraut sind, füge ich hier einen Pseudocode hinzu. Angenommen, Sie haben
YourApplication
und dieMemoryBoss
Klassen in Ihrerclass BaseActivity extends Activity
(Sie müssen eine erstellen, wenn Sie keine haben).Ich empfehle onStart, da Dialoge eine Aktivität anhalten können. Ich wette, Sie möchten nicht, dass Ihre App denkt, dass sie in den Hintergrund tritt, wenn Sie nur einen Vollbilddialog angezeigt haben, aber Ihr Kilometerstand kann variieren.
Und das ist alles. Der Code in der if - Block wird nur einmal ausgeführt werden , auch wenn Sie auf eine andere Tätigkeit gehen, die neue (das auch
extends BaseActivity
) berichtenwasInBackground
ist ,false
so dass es den Code nicht ausgeführt wird, bisonMemoryTrimmed
aufgerufen wird und das Flag auf true gesetzt wieder .Ich hoffe, das hilft.
UPDATE / NOTES (April 2015) : Bevor Sie mit dem Kopieren und Einfügen dieses Codes beginnen, beachten Sie, dass ich einige Fälle gefunden habe, in denen er möglicherweise nicht 100% zuverlässig ist und mit anderen Methoden kombiniert werden muss , um die besten Ergebnisse zu erzielen. Insbesondere sind zwei Fälle bekannt, in denen die
onTrimMemory
Ausführung des Rückrufs nicht garantiert werden kann:Wenn Ihr Telefon den Bildschirm sperrt, während Ihre App sichtbar ist (sagen wir, Ihr Gerät wird nach nn Minuten gesperrt), wird dieser Rückruf nicht (oder nicht immer) aufgerufen, da der Sperrbildschirm nur oben angezeigt wird, Ihre App jedoch weiterhin "ausgeführt" wird, obwohl sie abgedeckt ist.
Wenn Ihr Gerät relativ wenig Speicherplatz hat (und unter Speicherstress steht), scheint das Betriebssystem diesen Aufruf zu ignorieren und direkt zu kritischeren Ebenen zu wechseln.
Abhängig davon, wie wichtig es für Sie ist, zu wissen, wann Ihre App in den Hintergrund getreten ist, müssen Sie diese Lösung möglicherweise erweitern oder nicht, um den Aktivitätslebenszyklus und so weiter zu verfolgen.
Denken Sie einfach an die oben genannten Punkte und haben Sie ein gutes QS-Team;)
ENDE DES UPDATE
Es mag spät sein, aber es gibt eine zuverlässige Methode in Ice Cream Sandwich (API 14) und höher .
Es stellt sich heraus, dass ein Rückruf ausgelöst wird, wenn Ihre App keine sichtbare Benutzeroberfläche mehr hat. Der Rückruf, den Sie in einer benutzerdefinierten Klasse implementieren können, heißt ComponentCallbacks2 (ja, mit zwei). Dieser Rückruf ist nur in API Level 14 (Ice Cream Sandwich) und höher verfügbar .
Grundsätzlich erhalten Sie einen Aufruf der Methode:
Das Level ist 20 oder genauer
Ich habe dies getestet und es funktioniert immer, da Level 20 nur ein "Vorschlag" ist, dass Sie möglicherweise einige Ressourcen freigeben möchten, da Ihre App nicht mehr sichtbar ist.
Um die offiziellen Dokumente zu zitieren:
Natürlich sollten Sie dies implementieren , um tatsächlich tun , was er sagt (Purge - Speicher , die in bestimmten Zeit verwendet hat, deaktivieren Sie einige Sammlungen nicht die ungenutzt gesessen haben usw. Die Möglichkeiten sind endlos (siehe die offiziellen Dokumente für andere möglich mehr kritische Ebenen).
Aber das Interessante ist, dass das Betriebssystem Ihnen sagt: Hey, Ihre App ist in den Hintergrund getreten!
Welches ist genau das, was Sie zuerst wissen wollten.
Wie bestimmen Sie, wann Sie zurück sind?
Nun, das ist einfach. Ich bin sicher, Sie haben eine "BaseActivity", sodass Sie mit onResume () darauf hinweisen können , dass Sie zurück sind. Denn Sie werden nur dann sagen, dass Sie nicht zurück sind, wenn Sie tatsächlich einen Anruf bei der oben genannten
onTrimMemory
Methode erhalten.Es klappt. Sie erhalten keine Fehlalarme. Wenn eine Aktivität wieder aufgenommen wird, sind Sie zu 100% zurück. Wenn der Benutzer wieder nach hinten geht, erhalten Sie einen weiteren
onTrimMemory()
Anruf.Sie müssen Ihre Aktivitäten (oder noch besser eine benutzerdefinierte Klasse) abonnieren.
Der einfachste Weg, um sicherzustellen, dass Sie dies immer erhalten, besteht darin, eine einfache Klasse wie die folgende zu erstellen:
Um dies zu verwenden, gehen Sie in Ihrer Anwendungsimplementierung ( Sie haben eine, RECHTS? ) So vor:
Wenn Sie ein erstellen
Interface
können Sie eine hinzufügenelse
zu , dassif
und implementierenComponentCallbacks
(ohne die 2) in etwas unterhalb API verwendet 14. Das Callback nur das hatonLowMemory()
Methode und nicht aufgerufen wird erhalten , wenn Sie in den Hintergrund , aber Sie es zu trimmen Speicher verwenden sollen .Starten Sie jetzt Ihre App und drücken Sie nach Hause. Ihre
onTrimMemory(final int level)
Methode sollte aufgerufen werden (Hinweis: Protokollierung hinzufügen).Der letzte Schritt besteht darin, die Registrierung vom Rückruf aufzuheben. Der wahrscheinlich beste Ort ist die
onTerminate()
Methode Ihrer App, aber diese Methode wird auf einem realen Gerät nicht aufgerufen:Wenn Sie also nicht wirklich eine Situation haben, in der Sie nicht mehr registriert werden möchten, können Sie dies ignorieren, da Ihr Prozess auf Betriebssystemebene ohnehin zum Erliegen kommt.
Wenn Sie sich irgendwann entscheiden, die Registrierung aufzuheben (wenn Sie beispielsweise einen Mechanismus zum Herunterfahren Ihrer App bereitstellen, um zu bereinigen und zu sterben), können Sie Folgendes tun:
Und das ist es.
quelle
level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
was das Problem in Ihrem Update vermeidet, Punkt 2. In Bezug auf Punkt 1 ist es mir kein Problem, da die App nicht wirklich in den Hintergrund getreten ist, also sollte es so funktionieren.So habe ich es geschafft, das zu lösen. Es wird davon ausgegangen, dass die Verwendung einer Zeitreferenz zwischen Aktivitätsübergängen höchstwahrscheinlich einen ausreichenden Beweis dafür liefert, dass eine App "im Hintergrund" ist oder nicht.
Zuerst habe ich eine android.app.Application-Instanz (nennen wir sie MyApplication) verwendet, die einen Timer, eine TimerTask, eine Konstante hat, um die maximale Anzahl von Millisekunden darzustellen, die der Übergang von einer Aktivität zu einer anderen vernünftigerweise dauern könnte (ich ging mit einem Wert von 2s) und einem Booleschen Wert, der angibt, ob sich die App "im Hintergrund" befand oder nicht:
Die Anwendung bietet außerdem zwei Methoden zum Starten und Stoppen des Timers / der Aufgabe:
Der letzte Teil dieser Lösung besteht darin, jeder dieser Methoden einen Aufruf aus den Ereignissen onResume () und onPause () aller Aktivitäten oder vorzugsweise einer Basisaktivität hinzuzufügen, von der alle Ihre konkreten Aktivitäten erben:
Wenn der Benutzer also einfach zwischen den Aktivitäten Ihrer App navigiert, startet die onPause () der abgehenden Aktivität den Timer, aber fast sofort bricht die neu eingegebene Aktivität den Timer ab, bevor er die maximale Übergangszeit erreichen kann. Und so wäre InBackground falsch .
Wenn andererseits eine Aktivität vom Launcher in den Vordergrund tritt, das Gerät aufwacht, den Telefonanruf beendet usw., wurde die Timer-Task höchstwahrscheinlich vor diesem Ereignis ausgeführt und somit wurde InBackground auf true gesetzt .
quelle
Bearbeiten: Die neuen Architekturkomponenten brachten etwas Vielversprechendes: ProcessLifecycleOwner , siehe @ vokilams Antwort
Die eigentliche Lösung nach einem Google I / O-Vortrag :
Ja. Ich weiß, es ist schwer zu glauben, dass diese einfache Lösung funktioniert, da wir hier so viele seltsame Lösungen haben.
Aber es gibt Hoffnung.
quelle
ProcessLifecycleOwner
scheint auch eine vielversprechende Lösung zu sein.Eine Implementierung kann so einfach sein wie
Der aktuelle Verzögerungswert beträgt laut Quellcode
700ms
.Für die Verwendung dieser Funktion ist Folgendes erforderlich
dependencies
:quelle
implementation "android.arch.lifecycle:extensions:1.0.0"
undannotationProcessor "android.arch.lifecycle:compiler:1.0.0"
aus dem Google-Repository (dhgoogle()
)Basierend auf Martín Marconcinis Antwort (danke!) Habe ich endlich eine zuverlässige (und sehr einfache) Lösung gefunden.
Fügen Sie dies dann zu Ihrem onCreate () Ihrer Anwendungsklasse hinzu
quelle
Wir verwenden diese Methode. Es sieht zu einfach aus, um zu arbeiten, aber es wurde in unserer App gut getestet und funktioniert in allen Fällen überraschend gut, einschließlich des Aufrufen des Startbildschirms über die Schaltfläche "Startseite", über die Schaltfläche "Zurück" oder nach der Bildschirmsperre. Versuche es.
Die Idee ist, dass Android im Vordergrund immer neue Aktivitäten startet, bevor die vorherige beendet wird. Das ist nicht garantiert, aber so funktioniert es. Übrigens scheint Flurry dieselbe Logik zu verwenden (nur eine Vermutung, das habe ich nicht überprüft, aber es hängt mit denselben Ereignissen zusammen).
Bearbeiten: Gemäß den Kommentaren sind wir in späteren Versionen des Codes auch zu onStart () übergegangen. Außerdem füge ich Superanrufe hinzu, die in meinem ersten Beitrag fehlten, da dies eher ein Konzept als ein Arbeitscode war.
quelle
onStop is called when the activity is no longer visible to the user
.Wenn Ihre App aus mehreren Aktivitäten und / oder gestapelten Aktivitäten wie einem Registerkartenleisten-Widget besteht, funktioniert das Überschreiben von onPause () und onResume () nicht. Das heißt, wenn eine neue Aktivität gestartet wird, werden die aktuellen Aktivitäten angehalten, bevor die neue erstellt wird. Gleiches gilt, wenn Sie eine Aktivität beenden (mit der Schaltfläche "Zurück").
Ich habe zwei Methoden gefunden, die wie gewünscht zu funktionieren scheinen.
Die erste erfordert die Berechtigung GET_TASKS und besteht aus einer einfachen Methode, die durch Vergleichen der Paketnamen überprüft, ob die am häufigsten ausgeführte Aktivität auf dem Gerät zur Anwendung gehört:
Diese Methode wurde im Droid-Fu-Framework (jetzt Ignition genannt) gefunden.
Die zweite Methode, die ich selbst implementiert habe, erfordert nicht die Berechtigung GET_TASKS, was gut ist. Stattdessen ist die Implementierung etwas komplizierter.
In Ihrer MainApplication-Klasse haben Sie eine Variable, die die Anzahl der ausgeführten Aktivitäten in Ihrer Anwendung verfolgt. In onResume () erhöhen Sie für jede Aktivität die Variable und in onPause () verringern Sie sie.
Wenn die Anzahl der ausgeführten Aktivitäten 0 erreicht, wird die Anwendung in den Hintergrund gestellt, wenn die folgenden Bedingungen erfüllt sind:
Wenn Sie feststellen können, dass die Anwendung im Hintergrund zurückgetreten ist, können Sie leicht erkennen, wenn sie ebenfalls wieder in den Vordergrund gestellt wird.
quelle
getRunnintTasks()
Erstellen Sie eine Klasse , die erweitert wird
Application
. Dann können wir darin seine Override-Methode verwendenonTrimMemory()
.Um festzustellen, ob die Anwendung in den Hintergrund getreten ist, verwenden wir:
quelle
FragmentActivity
Sie auch hinzufügen möchtenlevel == ComponentCallbacks2.TRIM_MEMORY_COMPLETE
auch.Erwägen Sie die Verwendung von onUserLeaveHint. Dies wird nur aufgerufen, wenn Ihre App in den Hintergrund tritt. onPause muss Eckfälle behandeln, da es aus anderen Gründen aufgerufen werden kann. Wenn der Benutzer beispielsweise eine andere Aktivität in Ihrer App öffnet, z. B. Ihre Einstellungsseite, wird die onPause-Methode Ihrer Hauptaktivität aufgerufen, obwohl sie sich noch in Ihrer App befindet. Das Verfolgen der Vorgänge führt zu Fehlern, wenn Sie stattdessen einfach den onUserLeaveHint-Rückruf verwenden können, der genau das tut, was Sie verlangen.
Wenn auf UserLeaveHint aufgerufen wird, können Sie ein boolesches inBackground-Flag auf true setzen. Wenn onResume aufgerufen wird, nehmen Sie nur an, dass Sie wieder in den Vordergrund zurückgekehrt sind, wenn das Flag inBackground gesetzt ist. Dies liegt daran, dass onResume auch für Ihre Hauptaktivität aufgerufen wird, wenn sich der Benutzer nur in Ihrem Einstellungsmenü befand und die App nie verlassen hat.
Denken Sie daran, dass onUserLeaveHint in Ihrer Einstellungsaktivität aufgerufen wird, wenn der Benutzer in Ihrem Einstellungsbildschirm auf die Home-Schaltfläche drückt, und wenn er zurückkehrt, wird onResume in Ihrer Einstellungsaktivität aufgerufen. Wenn Sie nur diesen Erkennungscode in Ihrer Hauptaktivität haben, werden Sie diesen Anwendungsfall verpassen. Um diesen Code in all Ihren Aktivitäten zu haben, ohne Code zu duplizieren, verfügen Sie über eine abstrakte Aktivitätsklasse, die die Aktivität erweitert, und fügen Sie Ihren gemeinsamen Code ein. Dann kann jede Aktivität, die Sie haben, diese abstrakte Aktivität erweitern.
Zum Beispiel:
quelle
ActivityLifecycleCallbacks sind möglicherweise von Interesse, aber nicht gut dokumentiert.
Wenn Sie registerActivityLifecycleCallbacks () aufrufen , sollten Sie in der Lage sein, Rückrufe zu erhalten, wenn Aktivitäten erstellt, zerstört usw. werden. Sie können getComponentName () für die Aktivität aufrufen .
quelle
Das Paket android.arch.lifecycle bietet Klassen und Schnittstellen, mit denen Sie lebenszyklusbewusste Komponenten erstellen können
Ihre Anwendung sollte die LifecycleObserver-Schnittstelle implementieren:
Dazu müssen Sie diese Abhängigkeit zu Ihrer build.gradle-Datei hinzufügen:
Wie von Google empfohlen, sollten Sie den Code minimieren, der in den Lebenszyklusmethoden von Aktivitäten ausgeführt wird:
Weitere Informationen finden Sie hier: https://developer.android.com/topic/libraries/architecture/lifecycle
quelle
Fügen Sie in Ihrer Anwendung den Rückruf hinzu und suchen Sie auf folgende Weise nach Root-Aktivitäten:
quelle
Ich habe ein Projekt auf Github App-Vordergrund-Hintergrund-Listen erstellt
Erstellen Sie eine BaseActivity für alle Aktivitäten in Ihrer Anwendung.
Verwenden Sie diese BaseActivity nun als Superklasse für alle Ihre Aktivitäten, wie MainActivity BaseActivity erweitert, und onAppStart wird aufgerufen, wenn Sie Ihre Anwendung starten, und onAppPause () wird aufgerufen, wenn die Anwendung von einem beliebigen Bildschirm aus in den Hintergrund tritt.
quelle
Dies ist mit ProcessLifecycleOwner ziemlich einfach
Fügen Sie diese Abhängigkeiten hinzu
In Kotlin :
Dann in Ihrer Basisaktivität:
Siehe meinen Artikel zu diesem Thema: https://medium.com/@egek92/how-to-actually-detect-foreground-background-changes-in-your-android-application-without-wanting-9719cc822c48
quelle
Sie können den ProcessLifecycleOwner verwenden, um einen Lebenszyklusbeobachter daran anzuhängen .
dann
onCreate()
nennen Sie in Ihrer Anwendungsklasse Folgendes:Auf diese Weise können Sie die Ereignisse
ON_PAUSE
undON_STOP
Anwendungen Ihrer Anwendung erfassen, die im Hintergrund auftreten.quelle
Es gibt keine einfachen Lebenszyklusmethoden, mit denen Sie feststellen können, wann die gesamte Anwendung in den Hintergrund tritt.
Ich habe das auf einfache Weise gemacht. Befolgen Sie die folgenden Anweisungen, um die Hintergrund- / Vordergrundphase der Anwendung zu erkennen.
Mit einer kleinen Problemumgehung ist dies möglich. Hier hilft ActivityLifecycleCallbacks . Lassen Sie mich Schritt für Schritt durchgehen.
Erstellen Sie zunächst eine Klasse, die die android.app.Application erweitert und die ActivityLifecycleCallbacks- Schnittstelle implementiert . Registrieren Sie in Application.onCreate () den Rückruf.
Registrieren Sie die App-Klasse im Manifest wie folgt
<application android:name=".App"
.Es befindet sich mindestens eine Aktivität im gestarteten Zustand, wenn sich die App im Vordergrund befindet, und es befindet sich keine Aktivität im gestarteten Zustand, wenn sich die App im Hintergrund befindet.
Deklarieren Sie 2 Variablen wie folgt in der Klasse „App“.
activityReferences
hält die Anzahl der Aktivitäten im gestarteten Zustand.isActivityChangingConfigurations
ist ein Flag, das angibt, ob die aktuelle Aktivität wie ein Orientierungsschalter eine Konfigurationsänderung durchläuft.Mit dem folgenden Code können Sie feststellen, ob die App im Vordergrund steht.
So erkennen Sie, ob die App in den Hintergrund tritt.
Wie es funktioniert:
Dies ist ein kleiner Trick, der mit der Art und Weise ausgeführt wird, wie die Lifecycle-Methoden nacheinander aufgerufen werden. Lassen Sie mich ein Szenario durchgehen.
Angenommen, der Benutzer startet die App und die Startaktivität A wird gestartet. Die Lifecycle-Aufrufe lauten:
Jetzt startet Aktivität A Aktivität B.
Dann navigiert der Benutzer von Aktivität B zurück.
Dann drückt der Benutzer die Home-Taste.
Falls der Benutzer die Home-Taste von Aktivität B anstelle der Zurück-Taste drückt, ist dies immer noch derselbe und die Aktivitätsreferenzen
0
. Daher können wir erkennen, wie die App den Hintergrund betritt.Also, was ist die Rolle von
isActivityChangingConfigurations
? Angenommen, die Aktivität B ändert im obigen Szenario die Ausrichtung. Die Rückrufsequenz lautet:Aus diesem Grund haben wir eine zusätzliche Überprüfung
isActivityChangingConfigurations
, um das Szenario zu vermeiden, in dem die Aktivität die Konfigurationsänderungen durchläuft.quelle
Ich habe eine gute Methode gefunden, um Anwendungen zu erkennen, unabhängig davon, ob sie in den Vordergrund oder in den Hintergrund treten. Hier ist mein Code . Hoffe das hilft dir.
}}
quelle
Sie können verwenden:
Unterschied zwischen Neustarts und Neustarts.
quelle
Edit 2: Was ich unten geschrieben habe, funktioniert eigentlich nicht. Google hat eine App abgelehnt, die einen Aufruf von ActivityManager.getRunningTasks () enthält. Aus der Dokumentation geht hervor, dass diese API nur zu Debugging- und Entwicklungszwecken dient. Ich werde diesen Beitrag aktualisieren, sobald ich Zeit habe, das GitHub-Projekt unten mit einem neuen Schema zu aktualisieren, das Timer verwendet und fast genauso gut ist.
Bearbeiten 1: Ich habe einen Blog-Beitrag geschrieben und ein einfaches GitHub-Repository erstellt , um dies wirklich einfach zu machen.
Die akzeptierte und die am besten bewertete Antwort sind nicht wirklich der beste Ansatz. Die Implementierung von isApplicationBroughtToBackground () durch die am besten bewertete Antwort behandelt nicht die Situation, in der die Hauptaktivität der Anwendung einer Aktivität nachgibt, die in derselben Anwendung definiert ist, aber ein anderes Java-Paket enthält. Ich habe einen Weg gefunden, dies zu tun, der in diesem Fall funktioniert.
Rufen Sie dies in onPause () auf, und Sie erfahren, ob Ihre Anwendung in den Hintergrund tritt, weil eine andere Anwendung gestartet wurde oder der Benutzer die Home-Taste gedrückt hat.
quelle
Richtige Antwort hier
Erstellen Sie eine Klasse mit dem Namen MyApp wie folgt:
Fügen Sie dann überall den gewünschten Code hinzu (bessere erste Aktivität, die in der App gestartet wurde):
Erledigt! Wenn sich die App im Hintergrund befindet, erhalten wir ein Protokoll,
status : we are out
und wenn wir in die App gehen, erhalten wir ein Protokollstatus : we are out
quelle
Meine Lösung wurde von der Antwort von @ d60402 inspiriert und basiert auch auf einem Zeitfenster, verwendet jedoch nicht Folgendes
Timer
:wo das
SingletonApplication
eine Erweiterung derApplication
Klasse ist:quelle
Ich habe dies mit Google Analytics EasyTracker verwendet und es hat funktioniert. Es könnte erweitert werden, um das zu tun, was Sie suchen, indem Sie eine einfache Ganzzahl verwenden.
quelle
Ich weiß, dass es etwas spät ist, aber ich denke, all diese Antworten haben einige Probleme, während ich es wie unten gemacht habe, und das funktioniert perfekt.
Erstellen Sie einen Aktivitätslebenszyklus-Rückruf wie folgt:
und registrieren Sie es einfach in Ihrer Anwendungsklasse wie folgt:
quelle
Dies scheint eine der kompliziertesten Fragen in Android zu sein, da Android (zum jetzigen Zeitpunkt) keine iOS-Entsprechungen
applicationDidEnterBackground()
oderapplicationWillEnterForeground()
Rückrufe hat. Ich habe eine AppState-Bibliothek verwendet , die von @jenzz zusammengestellt wurde .Es stellte sich heraus, dass dies genau das ist, was ich brauchte, insbesondere weil meine App mehrere Aktivitäten hatte, sodass das einfache Überprüfen
onStart()
oder AktivierenonStop()
einer Aktivität dies nicht verhindern würde.Zuerst habe ich diese Abhängigkeiten zu gradle hinzugefügt:
Dann war es einfach, diese Zeilen an einer geeigneten Stelle in Ihrem Code hinzuzufügen:
Abhängig davon, wie Sie das Observable abonnieren, müssen Sie es möglicherweise abbestellen, um Speicherverluste zu vermeiden. Nochmals mehr Infos auf der Github-Seite .
quelle
Dies ist die geänderte Version der Antwort von @ d60402: https://stackoverflow.com/a/15573121/4747587
Mach alles was dort erwähnt wird. Aber anstatt ein zu haben
Base Activity
und das als Elternteil für jede Aktivität und das Überschreiben desonResume()
und zu machenonPause
, gehen Sie wie folgt vor:Fügen Sie in Ihrer Anwendungsklasse die folgende Zeile hinzu:
registerActivityLifecycleCallbacks (Rückruf Application.ActivityLifecycleCallbacks);
Dies
callback
hat alle Methoden des Aktivitätslebenszyklus und Sie können jetztonActivityResumed()
und überschreibenonActivityPaused()
.Schauen Sie sich diese Übersicht an: https://gist.github.com/thsaravana/1fa576b6af9fc8fff20acfb2ac79fa1b
quelle
Sie können dies leicht mit Hilfe von
ActivityLifecycleCallbacks
und soComponentCallbacks2
etwas wie unten erreichen.Erstellen Sie eine Klasse,
AppLifeCycleHandler
die über diesen Schnittstellen implementiert ist.In Ihrer Klasse, die
Application
implementiertAppLifeCycleCallback
, implementieren Sie , um die Rückrufe zu erhalten, wenn die App zwischen Vordergrund und Hintergrund wechselt. So etwas wie unten.Hoffe das hilft.
BEARBEITEN Alternativ können Sie jetzt die Life Cycle-fähige Architekturkomponente verwenden.
quelle
Da ich keinen Ansatz gefunden habe, der auch die Rotation ohne Überprüfung der Zeitstempel handhabt, dachte ich, ich teile auch, wie wir es jetzt in unserer App machen. Die einzige Ergänzung zu dieser Antwort https://stackoverflow.com/a/42679191/5119746 ist, dass wir auch die Ausrichtung berücksichtigen.
Dann haben wir für die Rückrufe zuerst den Lebenslauf:
Und onActivityStopped:
Und dann kommt hier der Zusatz: Auf Orientierungsänderungen prüfen:
Das ist es. Hoffe das hilft jemandem :)
quelle
Wir können diese Lösung erweitern mit
LiveData
:Jetzt können wir diese LiveData abonnieren und die erforderlichen Ereignisse abfangen. Zum Beispiel:
quelle
Diese Antworten scheinen nicht richtig zu sein. Diese Methoden werden auch aufgerufen, wenn eine andere Aktivität beginnt und endet. Was Sie tun können, ist, ein globales Flag beizubehalten (ja, globale Werte sind schlecht :) und dies bei jedem Start einer neuen Aktivität auf true zu setzen. Setzen Sie es im onCreate jeder Aktivität auf false. Dann aktivieren Sie in der onPause dieses Flag. Wenn es falsch ist, tritt Ihre App in den Hintergrund oder wird getötet.
quelle