Mit Hintergrund meine ich, dass derzeit keine der Aktivitäten der Anwendung für den Benutzer sichtbar sind.
Mit Hintergrund meine ich, dass derzeit keine der Aktivitäten der Anwendung für den Benutzer sichtbar sind.
Antworten:
Es gibt nur wenige Möglichkeiten, um festzustellen, ob Ihre Anwendung im Hintergrund ausgeführt wird, aber nur eine davon ist absolut zuverlässig:
Die richtige Lösung (Kredite gehen zu Dan , CommonsWare und NeTeInStEiN )
verfolgen Sichtbarkeit Ihrer Anwendung selbst verwendet Activity.onPause
, Activity.onResume
Methoden. Speichern Sie den Status "Sichtbarkeit" in einer anderen Klasse. Gute Entscheidungen sind Ihre eigene Implementierung von Application
oder a Service
(es gibt auch einige Variationen dieser Lösung, wenn Sie die Aktivitätssichtbarkeit des Dienstes überprüfen möchten).
Beispiel
Implementieren Sie eine benutzerdefinierte Application
Klasse (beachten Sie die isActivityVisible()
statische Methode):
public class MyApplication extends Application {
public static boolean isActivityVisible() {
return activityVisible;
}
public static void activityResumed() {
activityVisible = true;
}
public static void activityPaused() {
activityVisible = false;
}
private static boolean activityVisible;
}
Registrieren Sie Ihre Bewerbungsklasse in AndroidManifest.xml
:
<application
android:name="your.app.package.MyApplication"
android:icon="@drawable/icon"
android:label="@string/app_name" >
Fügen Sie onPause
und onResume
zu jedem Activity
im Projekt hinzu (Sie können einen gemeinsamen Vorfahren für Ihre Aktivitäten erstellen, wenn Sie möchten, aber wenn Ihre Aktivität bereits von MapActivity
/ ListActivity
usw. erweitert wurde, müssen Sie immer noch Folgendes von Hand schreiben):
@Override
protected void onResume() {
super.onResume();
MyApplication.activityResumed();
}
@Override
protected void onPause() {
super.onPause();
MyApplication.activityPaused();
}
Update
ActivityLifecycleCallbacks wurden in API Level 14 (Android 4.0) hinzugefügt. Sie können sie verwenden, um zu verfolgen, ob eine Aktivität Ihrer Anwendung derzeit für den Benutzer sichtbar ist. Überprüfen Sie die Antwort von Cornstalks unten für die Details.
Die falsche habe
ich verwendet, um die folgende Lösung vorzuschlagen:
Sie können die aktuelle Vordergrund- / Hintergrundanwendung erkennen, mit
ActivityManager.getRunningAppProcesses()
der eine Liste vonRunningAppProcessInfo
Datensätzen zurückgegeben wird. Um festzustellen, ob sich Ihre Anwendung im Vordergrund befindet, überprüfen Sie, ob dieRunningAppProcessInfo.importance
Gleichheit mitRunningAppProcessInfo.IMPORTANCE_FOREGROUND
whileRunningAppProcessInfo.processName
Ihrem Anwendungspaketnamen entspricht.Auch wenn Sie
ActivityManager.getRunningAppProcesses()
von Ihrem Anwendungs-UI-Thread aus aufrufen , wird die BedeutungIMPORTANCE_FOREGROUND
für Ihre Aufgabe zurückgegeben, unabhängig davon, ob sie tatsächlich im Vordergrund steht oder nicht. Rufen Sie es im Hintergrund-Thread auf (zum Beispiel überAsyncTask
) und es werden korrekte Ergebnisse zurückgegeben.
Obwohl diese Lösung möglicherweise funktioniert (und tatsächlich die meiste Zeit funktioniert), empfehle ich dringend, sie nicht zu verwenden. Und hier ist warum. Wie Dianne Hackborn schrieb :
Diese APIs sind nicht für Anwendungen gedacht, auf denen der UI-Fluss basiert, sondern um dem Benutzer 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 separat von Ihrem 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 für den Wechsel kurz gesperrt wird) treffen wir weiß eigentlich genau, was das nächste sein wird.
Und es ist nicht garantiert, dass die Implementierung und das globale Verhalten in Zukunft gleich bleiben.
Ich wünschte, ich hätte dies gelesen, bevor ich eine Antwort auf die SO gepostet habe, aber hoffentlich ist es nicht zu spät, meinen Fehler zuzugeben.
Eine andere falsche Lösung, die die
Droid-Fu- Bibliothek in einer der Antworten ActivityManager.getRunningTasks
für ihre isApplicationBroughtToBackground
Methode verwendet. Siehe Diannes Kommentar oben und verwende diese Methode auch nicht.
OnStop
Anfrage an isActivityVisible
.
Die Antwort von user1269737 ist der richtige (von Google / Android genehmigte) Weg, dies zu tun . Lies ihre Antwort und gib ihnen eine +1.
Ich werde meine ursprüngliche Antwort hier der Nachwelt zuliebe hinterlassen. Dies war das beste, das es 2012 gab, aber jetzt hat Android die richtige Unterstützung dafür.
Der Schlüssel wird verwendet ActivityLifecycleCallbacks
(beachten Sie, dass hierfür Android API Level 14 (Android 4.0) erforderlich ist). Überprüfen Sie einfach, ob die Anzahl der gestoppten Aktivitäten der Anzahl der gestarteten Aktivitäten entspricht. Wenn sie gleich sind, wird Ihre Anwendung im Hintergrund ausgeführt. Wenn mehr Aktivitäten gestartet wurden, ist Ihre Anwendung weiterhin sichtbar. Wenn mehr wieder aufgenommene als angehaltene Aktivitäten vorhanden sind, ist Ihre Anwendung nicht nur sichtbar, sondern steht auch im Vordergrund. Es gibt 3 Hauptzustände, in denen sich Ihre Aktivität befinden kann: sichtbar und im Vordergrund, sichtbar, aber nicht im Vordergrund und nicht sichtbar und nicht im Vordergrund (dh im Hintergrund).
Das wirklich Schöne an dieser Methode ist, dass sie nicht die asynchronen Probleme getRunningTasks()
hat, aber Sie müssen auch nicht alle Activity
in Ihrer Anwendung ändern , um etwas in onResumed()
/ zu setzen / zu deaktivieren onPaused()
. Es sind nur ein paar Codezeilen, die in sich geschlossen sind und in Ihrer gesamten Anwendung funktionieren. Außerdem sind keine funky Berechtigungen erforderlich.
MyLifecycleHandler.java:
public class MyLifecycleHandler implements ActivityLifecycleCallbacks {
// I use four separate variables here. You can, of course, just use two and
// increment/decrement them instead of using four and incrementing them all.
private int resumed;
private int paused;
private int started;
private int stopped;
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
++resumed;
}
@Override
public void onActivityPaused(Activity activity) {
++paused;
android.util.Log.w("test", "application is in foreground: " + (resumed > paused));
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityStarted(Activity activity) {
++started;
}
@Override
public void onActivityStopped(Activity activity) {
++stopped;
android.util.Log.w("test", "application is visible: " + (started > stopped));
}
// If you want a static function you can use to check if your application is
// foreground/background, you can use the following:
/*
// Replace the four variables above with these four
private static int resumed;
private static int paused;
private static int started;
private static int stopped;
// And these two public static functions
public static boolean isApplicationVisible() {
return started > stopped;
}
public static boolean isApplicationInForeground() {
return resumed > paused;
}
*/
}
MyApplication.java:
// Don't forget to add it to your manifest by doing
// <application android:name="your.package.MyApplication" ...
public class MyApplication extends Application {
@Override
public void onCreate() {
// Simply add the handler, and that's it! No need to add any code
// to every activity. Everything is contained in MyLifecycleHandler
// with just a few lines of code. Now *that's* nice.
registerActivityLifecycleCallbacks(new MyLifecycleHandler());
}
}
@Mewzer hat einige gute Fragen zu dieser Methode gestellt, auf die ich in dieser Antwort für alle antworten möchte:
onStop()
wird in Situationen mit wenig Speicher nicht aufgerufen; ist das hier ein problem
Nein. Die Dokumente onStop()
sagen:
Beachten Sie, dass diese Methode in Situationen mit wenig Arbeitsspeicher, in denen das System nicht über genügend Arbeitsspeicher verfügt, um den Prozess Ihrer Aktivität nach dem Aufruf der Methode onPause () auszuführen, möglicherweise nie aufgerufen wird.
Der Schlüssel hier ist "Halten Sie den Prozess Ihrer Aktivität am Laufen ...". Wenn diese Situation mit wenig Arbeitsspeicher jemals erreicht wird, wird Ihr Prozess tatsächlich beendet (nicht nur Ihre Aktivität). Dies bedeutet, dass diese Methode zur Überprüfung der Hintergründe weiterhin gültig ist, da a) Sie das Mitglied ohnehin nicht auf Hintergründe prüfen können, wenn Ihr Prozess beendet wird, und b) wenn Ihr Prozess erneut gestartet wird (weil eine neue Aktivität erstellt wird), das Mitglied Variablen (ob statisch oder nicht) für MyLifecycleHandler
werden auf zurückgesetzt 0
.
Funktioniert dies bei Konfigurationsänderungen?
Standardmäßig nein. Sie müssen explizit configChanges=orientation|screensize
( |
mit allem, was Sie wollen) in Ihrer Manifestdatei festlegen und die Konfigurationsänderungen behandeln, sonst wird Ihre Aktivität zerstört und neu erstellt. Wenn Sie dies nicht festlegen, werden die Methoden Ihrer Aktivität in der folgenden Reihenfolge aufgerufen : onCreate -> onStart -> onResume -> (now rotate) -> onPause -> onStop -> onDestroy -> onCreate -> onStart -> onResume
. Wie Sie sehen können, gibt es keine Überlappung (normalerweise überlappen sich zwei Aktivitäten sehr kurz, wenn zwischen den beiden gewechselt wird. So funktioniert diese Hintergrunderkennungsmethode). Um dies zu umgehen, müssen Sie festlegen configChanges
, dass Ihre Aktivität nicht zerstört wird. Zum Glück musste ich einstellenconfigChanges
Bereits in all meinen Projekten, weil es unerwünscht war, dass meine gesamte Aktivität auf dem Bildschirm zerstört wurde. Drehen / Ändern der Größe, daher habe ich dies nie als problematisch empfunden. (Danke an dpimka für das Auffrischen meines Gedächtnisses und das Korrigieren von mir!)
Eine Note:
Wenn ich hier in dieser Antwort "Hintergrund" gesagt habe, meine ich "Ihre App ist nicht mehr sichtbar". Android-Aktivitäten können sichtbar sein, jedoch nicht im Vordergrund (z. B. wenn eine transparente Benachrichtigungsüberlagerung vorhanden ist). Deshalb habe ich diese Antwort aktualisiert, um dies widerzuspiegeln.
Es ist wichtig zu wissen, dass Android beim Wechseln von Aktivitäten, bei denen nichts im Vordergrund steht, einen seltsamen Moment in der Schwebe hat . Wenn Sie beim Wechseln zwischen Aktivitäten (in derselben App) überprüfen, ob sich Ihre Anwendung im Vordergrund befindet, wird Ihnen aus diesem Grund mitgeteilt, dass Sie nicht im Vordergrund stehen (obwohl Ihre App immer noch die aktive App ist und sichtbar ist ).
Sie können überprüfen , ob Ihre App im Vordergrund in Ihrem sind Activity
‚s onPause()
Methode nach super.onPause()
. Denken Sie nur an den seltsamen Schwebezustand, über den ich gerade gesprochen habe.
Sie können überprüfen , ob Ihre App sichtbar sind (dh , wenn es nicht im Hintergrund ist) in Ihrem Activity
‚s onStop()
Methode nach super.onStop()
.
onStop()
Nach super.onStop()
. Überprüfen Sie nicht, ob Hintergrundinformationen vorhanden sind onPause()
.
GOOGLE-LÖSUNG - kein Hack wie bei früheren Lösungen. Verwenden Sie ProcessLifecycleOwner
Kotlin:
class ArchLifecycleApp : Application(), LifecycleObserver {
override fun onCreate() {
super.onCreate()
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onAppBackgrounded() {
//App in background
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onAppForegrounded() {
// App in foreground
}
}
Java:
public class ArchLifecycleApp extends Application implements LifecycleObserver {
@Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onAppBackgrounded() {
//App in background
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onAppForegrounded() {
// App in foreground
}
}
in app.gradle
dependencies {
...
implementation "android.arch.lifecycle:extensions:1.1.0"
//New Android X dependency is this -
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
}
allprojects {
repositories {
...
google()
jcenter()
maven { url 'https://maven.google.com' }
}
}
Weitere Informationen zu Lifecycle-bezogenen Architekturkomponenten finden Sie hier - https://developer.android.com/topic/libraries/architecture/lifecycle
companion object { private var foreground = false fun isForeground() : Boolean { return foreground } }
kann : Dann können Sie den Vordergrundstatus mitArchLifecycleApp.isForeground()
The LifecycleOwner for the whole application process. Note that if your application has multiple processes, this provider does not know about other processes.
, funktioniert dies nicht für multiple processes
Apps. Gibt es eine API, die wir elegant erreichen können?
Wenn Sie die Support-Bibliothek Version 26 starten , können Sie ProcessLifecycleOwner verwenden. Fügen Sie es einfach wie hier beschrieben zu Ihrer Abhängigkeit hinzu , zum Beispiel:
dependencies {
def lifecycle_version = "1.1.1"
// ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:$lifecycle_version"
// alternatively - Lifecycles only (no ViewModel or LiveData).
// Support library depends on this lightweight import
implementation "android.arch.lifecycle:runtime:$lifecycle_version"
annotationProcessor "android.arch.lifecycle:compiler:$lifecycle_version" // use kapt for Kotlin
}
Und ProcessLifecycleOwner
fragen Sie dann einfach ab, wann immer Sie den App-Status wünschen. Beispiele:
//Check if app is in background
ProcessLifecycleOwner.get().getLifecycle().getCurrentState() == Lifecycle.State.CREATED;
//Check if app is in foreground
ProcessLifecycleOwner.get().getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED);
Seit Android API 16 gibt es eine einfache Möglichkeit zu überprüfen, ob die App im Vordergrund steht. Es ist vielleicht nicht kinderleicht, aber keine Methoden unter Android sind kinderleicht. Diese Methode ist gut genug, um verwendet zu werden, wenn Ihr Dienst ein Update vom Server erhält und entscheiden muss, ob eine Benachrichtigung angezeigt werden soll oder nicht (denn wenn die Benutzeroberfläche im Vordergrund steht, wird der Benutzer das Update ohne Benachrichtigung bemerken).
RunningAppProcessInfo myProcess = new RunningAppProcessInfo();
ActivityManager.getMyMemoryState(myProcess);
isInBackground = myProcess.importance != RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
JobService
zu erkennen , dass der Dienst im Hintergrund ausgeführt wird .
Idolons Antwort ist fehleranfällig und viel komplizierter, obwohl hier wiederholt wird. Überprüfen Sie, ob die Android-Anwendung im Vordergrund steht oder nicht. und hier Bestimmen der aktuellen Vordergrundanwendung aus einer Hintergrundaufgabe oder einem Hintergrunddienst
Es gibt einen viel einfacheren Ansatz:
Auf einer BaseActivity, die alle Aktivitäten erweitern:
protected static boolean isVisible = false;
@Override
public void onResume()
{
super.onResume();
setVisible(true);
}
@Override
public void onPause()
{
super.onPause();
setVisible(false);
}
Wann immer Sie überprüfen müssen, ob eine Ihrer Anwendungsaktivitäten im Vordergrund steht, überprüfen Sie einfach isVisible()
;
Um diesen Ansatz zu verstehen, überprüfen Sie diese Antwort des Side-by-Side-Aktivitätslebenszyklus: Aktivität Side-by-Side-Lebenszyklus
Idolon's answer is error prone
- Leider muss ich dir zustimmen. Basierend auf dem Kommentar von Dianne Hackborn in den Google Groups habe ich meine Antwort aktualisiert. Überprüfen Sie es bitte für die Details.
onPause
, onStop
noch das onResume
Ereignis aufgerufen wird. Was machen Sie dann, wenn keines dieser Ereignisse ausgelöst wird?!
Ich habe die empfohlene Lösung ausprobiert, die Application.ActivityLifecycleCallbacks und viele andere verwendet, aber sie funktionierten nicht wie erwartet. Dank Sarge habe ich eine ziemlich einfache und unkomplizierte Lösung gefunden, die ich unten beschreibe.
Der Schlüssel der Lösung ist die Tatsache, dass wenn wir ActivityA und ActivityB haben und ActivityB von ActivityA aus aufrufen (und nicht aufrufen
ActivityA.finish
), ActivityB vor ActivityAonStart()
aufgerufen wird .onStop()
Das ist auch der Hauptunterschied zwischen onStop()
und dem onPause()
, den keiner in den Artikeln erwähnt hat, die ich gelesen habe.
Basierend auf dem Lebenszyklusverhalten dieser Aktivität können Sie einfach zählen, wie oft onStart()
und onPause()
in welchem Programm Sie aufgerufen wurden. Beachten Sie, dass Sie für jedes Activity
Programm die zum Zählen verwendete statische Variable überschreiben onStart()
und onStop()
dekrementieren müssen. Unten finden Sie den Code, der diese Logik implementiert. Beachten Sie, dass ich eine Klasse verwende, die erweitert Application
wird. Vergessen Sie also nicht, Manifest.xml
innerhalb des Application-Tags zu deklarieren : android:name=".Utilities"
obwohl dies auch mit einer einfachen benutzerdefinierten Klasse implementiert werden kann.
public class Utilities extends Application
{
private static int stateCounter;
public void onCreate()
{
super.onCreate();
stateCounter = 0;
}
/**
* @return true if application is on background
* */
public static boolean isApplicationOnBackground()
{
return stateCounter == 0;
}
//to be called on each Activity onStart()
public static void activityStarted()
{
stateCounter++;
}
//to be called on each Activity onStop()
public static void activityStopped()
{
stateCounter--;
}
}
Jetzt auf jeder Aktivität unseres Programms, sollten wir außer Kraft setzen onStart()
und onStop()
und Erhöhen / Verringern wie unten dargestellt:
@Override
public void onStart()
{
super.onStart();
Utilities.activityStarted();
}
@Override
public void onStop()
{
Utilities.activityStopped();
if(Utilities.isApplicationOnBackground())
{
//you should want to check here if your application is on background
}
super.onStop();
}
Mit dieser Logik gibt es zwei mögliche Fälle:
stateCounter = 0
: Die Anzahl der gestoppten Aktivitäten entspricht der Anzahl der gestarteten Aktivitäten. Dies bedeutet, dass die Anwendung im Hintergrund ausgeführt wird.stateCounter > 0
: Die Anzahl der gestarteten Anwendungen ist größer als die Anzahl der gestoppten Anwendungen. Dies bedeutet, dass die Anwendung im Vordergrund ausgeführt wird.Hinweis: Dies stateCounter < 0
würde bedeuten, dass mehr Aktivitäten gestoppt als gestartet werden, was unmöglich ist. Wenn Sie auf diesen Fall stoßen, bedeutet dies, dass Sie den Zähler nicht wie gewünscht erhöhen / verringern.
Sie sind bereit zu gehen. Sie sollten überprüfen wollen, ob sich Ihre Anwendung im Hintergrund befindet onStop()
.
if(Utilities.isApplicationOnBackground()) …
zu Utilities
. Denn sonst reagiert nur eine bestimmte Aktivität auf das Ereignis.
Es gibt keine Möglichkeit, ohne dass Sie es selbst verfolgen, festzustellen, ob eine Ihrer Aktivitäten sichtbar ist oder nicht. Vielleicht sollten Sie eine neue StackOverflow-Frage stellen und erklären, was Sie mit einer Benutzererfahrung erreichen möchten, damit wir Ihnen möglicherweise alternative Implementierungsideen geben können.
Service
. Wenn ja, lassen Sie Ihre Aktivitäten den Dienst benachrichtigen, sobald sie angezeigt werden und verschwinden. Wenn das Service
feststellt, dass keine Aktivitäten sichtbar sind und dies für einige Zeit so bleibt, stoppen Sie die Datenübertragung am nächsten logischen Stopppunkt. Ja, dies erfordert Code für jede Ihrer Aktivitäten, aber im Moment ist dies unvermeidlich, AFAIK.
MyActivityClass
die von Activity
den Lebenszyklusmethoden erbt und diese implementiert, und alle Ihre Aktivitäten erben lassen MyActivityClass
. Dies wird nicht funktionieren für PreferenceActivity
oder MapActivity
obwohl (siehe diese Frage )
Mit ComponentCallbacks2 können Sie feststellen, ob sich die App im Hintergrund befindet. Übrigens ist dieser Rückruf nur in API Level 14 (Ice Cream Sandwich) und höher verfügbar .
Sie erhalten einen Aufruf der Methode:
public abstract void onTrimMemory (int level)
Wenn das Level ist, befindet sich ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
die App im Hintergrund.
Sie können diese Schnittstelle zu einem Gerät activity
, service
usw.
public class MainActivity extends AppCompatActivity implements ComponentCallbacks2 {
@Override
public void onConfigurationChanged(final Configuration newConfig) {
}
@Override
public void onLowMemory() {
}
@Override
public void onTrimMemory(final int level) {
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
// app is in background
}
}
}
Aufbauend auf der Antwort von @Cornstalks mit einigen nützlichen Funktionen.
Zusätzliche Funktionen:
App.java
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(AppLifecycleHandler.getInstance());
}
}
AppLifecycleHandler.java
public class AppLifecycleHandler implements Application.ActivityLifecycleCallbacks {
private int resumed;
private int started;
private final String DebugName = "AppLifecycleHandler";
private boolean isVisible = false;
private boolean isInForeground = false;
private static AppLifecycleHandler instance;
public static AppLifecycleHandler getInstance() {
if (instance == null) {
instance = new AppLifecycleHandler();
}
return instance;
}
private AppLifecycleHandler() {
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
@Override
public void onActivityResumed(Activity activity) {
++resumed;
android.util.Log.w(DebugName, "onActivityResumed -> application is in foreground: " + (resumed > 0) + " (" + activity.getClass() + ")");
setForeground((resumed > 0));
}
@Override
public void onActivityPaused(Activity activity) {
--resumed;
android.util.Log.w(DebugName, "onActivityPaused -> application is in foreground: " + (resumed > 0) + " (" + activity.getClass() + ")");
setForeground((resumed > 0));
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityStarted(Activity activity) {
++started;
android.util.Log.w(DebugName, "onActivityStarted -> application is visible: " + (started > 0) + " (" + activity.getClass() + ")");
setVisible((started > 0));
}
@Override
public void onActivityStopped(Activity activity) {
--started;
android.util.Log.w(DebugName, "onActivityStopped -> application is visible: " + (started > 0) + " (" + activity.getClass() + ")");
setVisible((started > 0));
}
private void setVisible(boolean visible) {
if (isVisible == visible) {
// no change
return;
}
// visibility changed
isVisible = visible;
android.util.Log.w(DebugName, "App Visiblility Changed -> application is visible: " + isVisible);
// take some action on change of visibility
}
private void setForeground(boolean inForeground) {
if (isInForeground == inForeground) {
// no change
return;
}
// in foreground changed
isInForeground = inForeground;
android.util.Log.w(DebugName, "App In Foreground Changed -> application is in foreground: " + isInForeground);
// take some action on change of in foreground
}
public static boolean isApplicationVisible() {
return AppLifecycleHandler.getInstance().started > 0;
}
public static boolean isApplicationInForeground() {
return AppLifecycleHandler.getInstance().resumed > 0;
}
}
Die beste Lösung, die ich mir ausgedacht habe, verwendet Timer.
Sie haben einen Timer in onPause () gestartet und denselben Timer in onResume () abgebrochen. Es gibt 1 Instanz des Timers (normalerweise in der Application-Klasse definiert). Der Timer selbst ist so eingestellt, dass nach 2 Sekunden (oder einem beliebigen Intervall, das Sie für angemessen halten) ein Runnable ausgeführt wird. Wenn der Timer ausgelöst wird, setzen Sie ein Flag, das die Anwendung als im Hintergrund markiert.
In der onResume () -Methode können Sie vor dem Abbrechen des Timers das Hintergrundflag abfragen, um Startvorgänge auszuführen (z. B. Downloads starten oder Standortdienste aktivieren).
Mit dieser Lösung können Sie mehrere Aktivitäten auf dem Backstack ausführen und benötigen keine Implementierungsberechtigungen.
Diese Lösung funktioniert gut, wenn Sie auch einen Ereignisbus verwenden, da Ihr Timer einfach ein Ereignis auslösen kann und verschiedene Teile Ihrer App entsprechend reagieren können.
Wenn Sie die Entwicklereinstellungen "Aktivitäten nicht beibehalten" aktivieren, ist es nicht ausreichend, nur die Anzahl der erstellten Aktivitäten zu überprüfen. Sie müssen auch isSaveInstanceState überprüfen . Meine benutzerdefinierte Methode isApplicationRunning () prüft, ob die Android-App ausgeführt wird:
Hier mein Arbeitscode:
public class AppLifecycleService implements Application.ActivityLifecycleCallbacks {
private int created;
private boolean isSaveInstanceState;
private static AppLifecycleService instance;
private final static String TAG = AppLifecycleService.class.getName();
public static AppLifecycleService getInstance() {
if (instance == null) {
instance = new AppLifecycleService();
}
return instance;
}
public static boolean isApplicationRunning() {
boolean isApplicationRunning = true;
if (getCountCreatedActvities() == 0 && !isSaveInstanceState()) {
isApplicationRunning = false;
}
return isApplicationRunning;
}
public static boolean isSaveInstanceState() {
return AppLifecycleService.getInstance().isSaveInstanceState;
}
public static int getCountCreatedActvities() {
return AppLifecycleService.getInstance().created;
}
private AppLifecycleService() {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
this.isSaveInstanceState = true;
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
++created;
}
@Override
public void onActivityDestroyed(Activity activity) {
--created;
}
@Override
public void onActivityResumed(Activity activity) { }
@Override
public void onActivityPaused(Activity activity) { }
@Override
public void onActivityStarted(Activity activity) { }
@Override
public void onActivityStopped(Activity activity) { }
}
Die einzig richtige Lösung:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
MyApp.mainActivity = this;
super.onCreate(savedInstanceState);
...
}
public class MyApp extends Application implements LifecycleObserver {
public static MainActivity mainActivity = null;
@Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void onAppBackgrounded() {
// app in background
if (mainActivity != null) {
...
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void onAppForegrounded() {
// app in foreground
if (mainActivity != null) {
...
}
}
}
Um auf die Aussagen von CommonsWare und Key zurückzugreifen, können Sie möglicherweise die Application-Klasse erweitern und alle Ihre Aktivitäten dies für ihre onPause / onResume-Methoden aufrufen lassen. Auf diese Weise können Sie feststellen, welche Aktivitäten sichtbar sind, dies könnte jedoch wahrscheinlich besser gehandhabt werden.
Können Sie genau erläutern, was Sie vorhaben? Wenn Sie sagen, dass Sie im Hintergrund laufen, meinen Sie damit, dass Ihre Anwendung immer noch im Speicher ist, obwohl sie derzeit nicht auf dem Bildschirm angezeigt wird? Haben Sie darüber nachgedacht, Services als dauerhaftere Methode zur Verwaltung Ihrer App zu verwenden, wenn diese nicht im Fokus steht?
Application
hat nicht onPause()
oder onResume()
.
Ich habe ActivityLifecycleCallbacks selbst implementiert. Ich verwende SherlockActivity, aber für normale Aktivitäten könnte die Klasse funktionieren.
Zunächst erstelle ich eine Schnittstelle, die alle Methoden zum Verfolgen des Aktivitätslebenszyklus enthält:
public interface ActivityLifecycleCallbacks{
public void onActivityStopped(Activity activity);
public void onActivityStarted(Activity activity);
public void onActivitySaveInstanceState(Activity activity, Bundle outState);
public void onActivityResumed(Activity activity);
public void onActivityPaused(Activity activity);
public void onActivityDestroyed(Activity activity);
public void onActivityCreated(Activity activity, Bundle savedInstanceState);
}
Zweitens habe ich diese Schnittstelle in der Klasse meiner Anwendung implementiert:
public class MyApplication extends Application implements my.package.ActivityLifecycleCallbacks{
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onActivityStopped(Activity activity) {
Log.i("Tracking Activity Stopped", activity.getLocalClassName());
}
@Override
public void onActivityStarted(Activity activity) {
Log.i("Tracking Activity Started", activity.getLocalClassName());
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
Log.i("Tracking Activity SaveInstanceState", activity.getLocalClassName());
}
@Override
public void onActivityResumed(Activity activity) {
Log.i("Tracking Activity Resumed", activity.getLocalClassName());
}
@Override
public void onActivityPaused(Activity activity) {
Log.i("Tracking Activity Paused", activity.getLocalClassName());
}
@Override
public void onActivityDestroyed(Activity activity) {
Log.i("Tracking Activity Destroyed", activity.getLocalClassName());
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.i("Tracking Activity Created", activity.getLocalClassName());
}
}
Drittens erstelle ich eine Klasse, die von SherlockActivity ausgeht:
public class MySherlockActivity extends SherlockActivity {
protected MyApplication nMyApplication;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
nMyApplication = (MyApplication) getApplication();
nMyApplication.onActivityCreated(this, savedInstanceState);
}
protected void onResume() {
// TODO Auto-generated method stub
nMyApplication.onActivityResumed(this);
super.onResume();
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
nMyApplication.onActivityPaused(this);
super.onPause();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
nMyApplication.onActivityDestroyed(this);
super.onDestroy();
}
@Override
protected void onStart() {
nMyApplication.onActivityStarted(this);
super.onStart();
}
@Override
protected void onStop() {
nMyApplication.onActivityStopped(this);
super.onStop();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
nMyApplication.onActivitySaveInstanceState(this, outState);
super.onSaveInstanceState(outState);
}
}
Viertens habe ich alle Klassen, die von SherlockActivity ausgehen, durch MySherlockActivity ersetzt:
public class MainActivity extends MySherlockActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Jetzt sehen Sie im Logcat die Protokolle, die in der in MyApplication vorgenommenen Schnittstellenimplementierung programmiert wurden.
Da dies noch nicht erwähnt ist, empfehle ich den Lesern, ProcessLifecycleOwner zu erkunden, das über Android Architecture-Komponenten verfügbar ist
Das System unterscheidet zwischen Vordergrund- und Hintergrund-Apps. (Die Definition des Hintergrunds für Zwecke von Dienstbeschränkungen unterscheidet sich von der Definition, die von der Speicherverwaltung verwendet wird. Eine App befindet sich möglicherweise im Hintergrund , was die Speicherverwaltung betrifft , steht jedoch im Vordergrund, was die Fähigkeit zum Starten von Diensten betrifft.) Eine App ist gilt als im Vordergrund, wenn eine der folgenden Aussagen zutrifft:
Wenn keine dieser Bedingungen erfüllt ist, wird die App als im Hintergrund betrachtet.
Eine andere Lösung für diesen alten Beitrag (für diejenigen, denen es helfen könnte):
<application android:name=".BaseApplication" ... >
public class BaseApplication extends Application {
private class Status {
public boolean isVisible = true;
public boolean isFocused = true;
}
private Map<Activity, Status> activities;
@Override
public void onCreate() {
activities = new HashMap<Activity, Status>();
super.onCreate();
}
private boolean hasVisibleActivity() {
for (Status status : activities.values())
if (status.isVisible)
return true;
return false;
}
private boolean hasFocusedActivity() {
for (Status status : activities.values())
if (status.isFocused)
return true;
return false;
}
public void onActivityCreate(Activity activity, boolean isStarting) {
if (isStarting && activities.isEmpty())
onApplicationStart();
activities.put(activity, new Status());
}
public void onActivityStart(Activity activity) {
if (!hasVisibleActivity() && !hasFocusedActivity())
onApplicationForeground();
activities.get(activity).isVisible = true;
}
public void onActivityWindowFocusChanged(Activity activity, boolean hasFocus) {
activities.get(activity).isFocused = hasFocus;
}
public void onActivityStop(Activity activity, boolean isFinishing) {
activities.get(activity).isVisible = false;
if (!isFinishing && !hasVisibleActivity() && !hasFocusedActivity())
onApplicationBackground();
}
public void onActivityDestroy(Activity activity, boolean isFinishing) {
activities.remove(activity);
if(isFinishing && activities.isEmpty())
onApplicationStop();
}
private void onApplicationStart() {Log.i(null, "Start");}
private void onApplicationBackground() {Log.i(null, "Background");}
private void onApplicationForeground() {Log.i(null, "Foreground");}
private void onApplicationStop() {Log.i(null, "Stop");}
}
public class MyActivity extends BaseActivity {...}
public class BaseActivity extends Activity {
private BaseApplication application;
@Override
protected void onCreate(Bundle state) {
application = (BaseApplication) getApplication();
application.onActivityCreate(this, state == null);
super.onCreate(state);
}
@Override
protected void onStart() {
application.onActivityStart(this);
super.onStart();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
application.onActivityWindowFocusChanged(this, hasFocus);
super.onWindowFocusChanged(hasFocus);
}
@Override
protected void onStop() {
application.onActivityStop(this, isFinishing());
super.onStop();
}
@Override
protected void onDestroy() {
application.onActivityDestroy(this, isFinishing());
super.onDestroy();
}
}
Siehe den Kommentar in der Funktion onActivityDestroyed.
Funktioniert mit SDK-Zielversion 14>:
import android.app.Activity;
import android.app.Application;
import android.os.Bundle;
import android.util.Log;
public class AppLifecycleHandler implements Application.ActivityLifecycleCallbacks {
public static int active = 0;
@Override
public void onActivityStopped(Activity activity) {
Log.i("Tracking Activity Stopped", activity.getLocalClassName());
active--;
}
@Override
public void onActivityStarted(Activity activity) {
Log.i("Tracking Activity Started", activity.getLocalClassName());
active++;
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
Log.i("Tracking Activity SaveInstanceState", activity.getLocalClassName());
}
@Override
public void onActivityResumed(Activity activity) {
Log.i("Tracking Activity Resumed", activity.getLocalClassName());
active++;
}
@Override
public void onActivityPaused(Activity activity) {
Log.i("Tracking Activity Paused", activity.getLocalClassName());
active--;
}
@Override
public void onActivityDestroyed(Activity activity) {
Log.i("Tracking Activity Destroyed", activity.getLocalClassName());
active--;
// if active var here ever becomes zero, the app is closed or in background
if(active == 0){
...
}
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Log.i("Tracking Activity Created", activity.getLocalClassName());
active++;
}
}
Sie sollten eine gemeinsame Einstellung verwenden, um die Eigenschaft zu speichern und mithilfe der Servicebindung aus Ihren Aktivitäten darauf zu reagieren. Wenn Sie nur die Bindung verwenden (dh niemals startService verwenden), wird Ihr Dienst nur ausgeführt, wenn Sie an ihn binden (onResume binden und onPause aufheben), sodass er nur im Vordergrund ausgeführt wird und wenn Sie daran arbeiten möchten Hintergrund können Sie den regulären Start-Stopp-Dienst verwenden.
Ich denke, diese Frage sollte klarer sein. Wann? Wo? Was ist Ihre spezifische Situation, die Sie kennenlernen möchten, wenn sich Ihre App im Hintergrund befindet?
Ich stelle meine Lösung nur auf meine Weise vor.
Ich erreiche dies, indem ich das Feld "Wichtigkeit" der RunningAppProcessInfo
Klasse in der onStop
Methode jeder Aktivität in meiner App verwende. Dies kann einfach erreicht werden, indem BaseActivity
für andere Aktivitäten eine Erweiterung bereitgestellt wird , die die onStop
Methode implementiert , um den Wert von "Wichtigkeit" zu überprüfen. Hier ist der Code:
public static boolean isAppRunning(Context context) {
ActivityManager activityManager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> appProcesses = activityManager
.getRunningAppProcesses();
for (RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.processName.equals(context.getPackageName())) {
if (appProcess.importance != RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE) {
return true;
}
}
}
return false;
}
Ich empfehle, diese Seite durchzulesen : http://developer.android.com/reference/android/app/Activity.html
Kurz gesagt, Ihre Aktivität ist nach dem onStop()
Aufruf nicht mehr sichtbar .
onStop
; dazwischen onPause
und onStop
es ist sichtbar , aber nicht im Vordergrund .
onStop()
Aufruf nicht mehr sichtbar ist, was mit dem übereinstimmt, was Sie geschrieben haben.
onPause
aufgerufen wird: Eine kürzlich vorgenommene Bearbeitung hat dich korrigiert.
Meiner Meinung nach führen viele Antworten zu einer großen Menge an Code und bringen viel Komplexität und Nichtlesbarkeit mit sich.
Wenn Leute auf SO fragen, wie sie zwischen a Service
und a kommunizieren sollen Activity
, empfehle ich normalerweise, den LocalBroadcastManager zu verwenden .
Warum?
Nun, indem Sie die Dokumente zitieren:
Sie wissen, dass die von Ihnen gesendeten Daten Ihre App nicht verlassen. Sie müssen sich also keine Sorgen machen, dass private Daten verloren gehen.
Andere Anwendungen können diese Broadcasts nicht an Ihre App senden, sodass Sie sich keine Sorgen über Sicherheitslücken machen müssen, die sie ausnutzen können.
Es ist effizienter als das Senden einer globalen Sendung über das System.
Nicht in den Dokumenten:
Activity
, Application
...Beschreibung
Sie möchten also überprüfen, ob sich eines der Activity
Elemente derzeit im Vordergrund befindet. Das machst du normalerweise in einer Service
oder deiner Application
Klasse.
Dies bedeutet, dass Ihre Activity
Objekte zum Absender eines Signals werden (ich bin an / ich bin aus). Ihr Service
hingegen wird zum Receiver
.
Es gibt zwei Momente, in denen IhreActivity
erfahren, ob es im Vordergrund oder im Hintergrund läuft (ja, nur zwei ... nicht 6).
Wenn das Activity
in den Vordergrund tritt, wird die onResume()
Methode ausgelöst (auch nach aufgerufen)onCreate()
).
Wenn das Activity
in den Rücken geht,onPause()
wird gerufen.
Dies sind die Momente, in denen Sie Activity
das Signal an Ihre senden solltenService
um seinen Zustand zu beschreiben.
Denken Sie bei mehreren Activity
an die anActivity
in den Hintergrund tritt und dann ein anderes in den Vordergrund tritt.
Die Situation wäre also: *
Activity1 -- send --> Signal:OFF
Activity2 -- send --> Signal:ON
Das Service
/ Application
hört einfach weiter auf diese Signale und handelt entsprechend.
Code (TLDR)
Sie Service
müssen ein implementieren BroadcastReceiver
, um auf Signale zu warten.
this.localBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// received data if Activity is on / off
}
}
public static final IntentFilter SIGNAL_FILTER = new IntentFilter("com.you.yourapp.MY_SIGNAL")
Registrieren Sie die Receiver
inService::onCreate()
@Override
protected void onCreate() {
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(this.localBroadcastReceiver, SIGNAL_FILTER);
}
Heben Sie die Registrierung auf Service::onDestroy()
@Override
protected void onDestroy() {
// I'm dead, no need to listen to anything anymore.
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(this.localBroadcastReceiver);
}
Jetzt Activity
müssen Sie ihren Zustand mitteilen.
Im Activity::onResume()
Intent intent = new Intent();
intent.setAction(SomeActivity.SIGNAL_FILTER); // put ON boolean in intent
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
Im Activity::onPause()
Intent intent = new Intent();
intent.setAction(SomeActivity.SIGNAL_FILTER); // put OFF boolean in intent
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
Eine sehr, sehr häufige Situation
Entwickler: Ich möchte Daten von meinem senden
Service
und das aktualisierenActivity
. Wie überprüfe ich, ob dasActivity
im Vordergrund steht?
In der Regel muss nicht überprüft werden, ob sich das Activity
im Vordergrund befindet oder nicht. Senden Sie einfach die Daten über LocalBroadcastManager
von Ihrem Service
. Wenn das eingeschaltet Activity
ist, reagiert es und handelt.
Für diese sehr häufige Situation wird der Service
zum Absender und der Activity
implementiert den BroadcastReceiver
.
Erstellen Sie also eine Receiver
in Ihrem Activity
. Registrieren Sie es in onResume()
und heben Sie die Registrierung auf onPause()
. Es ist nicht erforderlich, die anderen Lebenszyklusmethoden zu verwenden .
Definieren Sie das Receiver
Verhalten in onReceive()
(ListView aktualisieren, dies tun, das tun, ...).
Auf diese Weise Activity
hört der Wille nur zu, wenn er im Vordergrund ist und nichts passiert, wenn er im Hintergrund ist oder zerstört wird.
Im Falle von mehreren Activity
wird jeder, der eingeschaltet Activity
ist, antworten (wenn sie auch das implementieren Receiver
).
Wenn sich alle im Hintergrund befinden, reagiert niemand und das Signal geht einfach verloren.
Senden Sie die Daten von der Service
Via Intent
(siehe Code oben), indem Sie die Signal-ID angeben.
fun isAppInForeground(): Boolean {
val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager ?: return false
val appProcesses = activityManager.runningAppProcesses ?: return false
val packageName = packageName
for (appProcess in appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName == packageName) {
return true
}
}
return false
}
Keine der Antworten passte ganz zum speziellen Fall, wenn Sie wissen möchten, ob sich eine bestimmte Aktivität im Vordergrund befindet und wenn Sie ein SDK ohne direkten Zugriff auf die Anwendung sind. Für mich war ich im Hintergrund-Thread, habe gerade eine Push-Benachrichtigung für eine neue Chat-Nachricht erhalten und möchte nur dann eine Systembenachrichtigung anzeigen, wenn der Chat-Bildschirm nicht im Vordergrund steht.
Mit dem ActivityLifecycleCallbacks
, wie in anderen Antworten empfohlen, habe ich eine kleine util-Klasse erstellt, die die Logik enthält, ob MyActivity
im Vordergrund steht oder nicht.
class MyActivityMonitor(context: Context) : Application.ActivityLifecycleCallbacks {
private var isMyActivityInForeground = false
init {
(context.applicationContext as Application).registerActivityLifecycleCallbacks(this)
}
fun isMyActivityForeground() = isMyActivityInForeground
override fun onActivityPaused(activity: Activity?) {
if (activity is MyActivity) {
isMyActivityInForeground = false
}
}
override fun onActivityResumed(activity: Activity?) {
if (activity is MyActivity) {
isMyActivityInForeground = true
}
}
}}
In meinen Aktivitäten onResume und onPause schreibe ich einen isVisible-Booleschen Wert in SharedPrefences.
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
Editor editor = sharedPrefs.edit();
editor.putBoolean("visible", false);
editor.commit();
Und lesen Sie es woanders, wenn nötig über,
// Show a Toast Notification if App is not visible (ie in background. Not running, etc)
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
if(!sharedPrefs.getBoolean("visible", true)){...}
Vielleicht nicht elegant, aber es funktioniert bei mir ...
Es mag zu spät sein, um zu antworten, aber wenn jemand zu Besuch kommt, dann ist hier die Lösung, die ich vorschlage: Der Grund, warum eine App wissen möchte, dass sie sich im Hintergrund befindet oder in den Vordergrund tritt, kann viele sein, einige sind, 1. Anzeigen von Toasts und Benachrichtigungen, wenn sich der Benutzer in BG befindet. 2.Um einige Aufgaben zum ersten Mal auszuführen, wenn der Benutzer von BG kommt, z. B. eine Umfrage, ein Neuzeichnen usw.
Die Lösung von Idolon und anderen kümmert sich um den ersten Teil, nicht jedoch um den zweiten. Wenn Ihre App mehrere Aktivitäten enthält und der Benutzer zwischen ihnen wechselt, ist das sichtbare Flag zu dem Zeitpunkt, an dem Sie sich in der zweiten Aktivität befinden, falsch. Es kann also nicht deterministisch verwendet werden.
Ich habe etwas getan, was von CommonsWare vorgeschlagen wurde: "Wenn der Dienst feststellt, dass keine Aktivitäten sichtbar sind und dies für einige Zeit so bleibt , stoppen Sie die Datenübertragung am nächsten logischen Stopppunkt."
Die fettgedruckte Zeile ist wichtig und kann verwendet werden, um einen zweiten Punkt zu erzielen. Wenn ich also onActivityPaused () erhalte, ändere ich das sichtbare nicht direkt in false, sondern habe einen Timer von 3 Sekunden (das ist das Maximum, mit dem die nächste Aktivität gestartet werden sollte) und wenn es nicht onActivityResumed gibt ( ) in den nächsten 3 Sekunden aufrufen, sichtbar in false ändern. Ähnlich wie bei onActivityResumed (), wenn es einen Timer gibt, brich ich ihn ab. Zusammenfassend wird das Sichtbare zu isAppInBackground.
Der Code kann leider nicht kopiert und eingefügt werden ...
Ich möchte Ihnen empfehlen, dies auf eine andere Weise zu tun.
Ich denke, Sie möchten den Startbildschirm anzeigen, während das Programm gestartet wird. Wenn es bereits im Backend ausgeführt wird, zeigen Sie es nicht an.
Ihre Anwendung kann kontinuierlich die aktuelle Zeit in eine bestimmte Datei schreiben. Überprüfen Sie beim Starten Ihrer Anwendung den letzten Zeitstempel. Wenn current_time-last_time> der Zeitbereich ist, den Sie zum Schreiben der letzten Zeit angegeben haben, bedeutet dies, dass Ihre Anwendung gestoppt wird, entweder vom System oder vom Benutzer selbst beendet.