2010-02-22 4 views
59

Ich habe einen BroadcastReceiver implementiert, der vom AlarmManager ausgelöst wird. Der AlarmManager wird auf BOOT_COMPLETED initialisiert. Also muss ich den Empfänger im Manifest deklarieren.So ermitteln Sie, ob eine meiner Aktivitäten im Vordergrund ist

Mein Problem ist, dass ich den BroadcastReceiver nur etwas tun soll, wenn keine meiner eigenen Aktivitäten im Vordergrund stehen (auch wenn der Benutzer nicht mit meiner Anwendung interagiert). Ich ziehe Informationen von einem Remote-Server und möchte den Benutzer nicht darüber informieren, wenn er sich gerade in meiner Anwendung befindet.

Bis jetzt habe ich noch keinen Weg gefunden, festzustellen, ob meine Anwendung im Vordergrund steht. Gibt es eine Möglichkeit, so etwas zu tun? Der ActivityManager sagt mir, ob meine Anwendung läuft, aber nicht, ob sie im Vordergrund ist. wie hier beschrieben

Das Problem ist so ziemlich das gleiche: Inform Activity from a BroadcastReceiver ONLY if it is in the foreground

LÖSUNG:

Nach mehreren Lösungen Auswertung i i schnell skizzieren wollen, was denken die beste Methode, mit Aktivitäten in der behandeln ist Hintergrund Vordergrund.

Die bevorzugte Möglichkeit besteht darin, einen Broadcast-Empfänger in der onResume-Methode Ihrer Aktivität zu registrieren und die Registrierung für die Aktivitäten von onPause aufzuheben. Jeder Dienst oder jedes andere Hintergrundelement muss dann eine Broadcast-Absicht mit einer bestimmten Aktion senden, die von Ihrer Aktivität abgefangen wird.

Wenn sich Ihre Aktivität im Vordergrund befindet, ist der Empfänger in der Absicht registriert und kann direkt mit der von Ihrem Dienst gesendeten Absicht umgehen. Wenn es nicht im Vordergrund ist, wird es nicht die Absicht erhalten, aber der Dienst, der die Übertragung aufgerufen hat, wird wissen, dass niemand seine Übertragungsabsicht abgefangen hat und in der Lage ist, selbst damit umzugehen. Zum Beispiel könnte es als die gewünschte Aktivität zu starten, zeigt eine Benachrichtigung usw.

+5

"der Dienst, der die Sendung aufgerufen wird wissen, dass niemand seine Sendung Absicht abgefangen" - vielleicht eine dumme Frage, aber wie wird es wissen? – ostergaard

+0

@ajostergaard Ich denke, es geht so: Broadcast gesendet "bist du im Voraus" Absicht. Wenn die Aktivität im Vordergrund ist, kann sie diese Absicht empfangen (weil die eigenen Empfänger in onResume registrieren) und die Antwort mit der Absicht "ja, ich bin im Vordergrund". Broadcast kann das erkennen, also über Activity State wissen. Übrigens. Überprüfen Sie meine Antwort für diese Frage unten :) – mklimek

Antwort

12

Ihre Aktivität kann als seinen eigenen Zustand verfolgen, ob es in dem Vordergrund (set boolean true in onStart(), zu false in onStop()) ist. Leider wird dieser boolesche Wert von Activity nicht automatisch zur Verfügung gestellt.

+0

Das wäre möglich, aber jede Aktivität in meiner Anwendung würde dieses Szenario unterstützen. Auch möchte ich dieses Verhalten nicht mit meinen Aktivitäten verbinden, sondern den BroadcastReceiver den tatsächlichen Zustand bestimmen lassen. – Moritz

+1

False, eine Aktivität kann im Hintergrund ausgeführt werden, ohne dass 'onStop()' aufgerufen wird. Lesen Sie diese: http://developer.android.com/reference/android/app/Activity.html –

+0

@ JorgeFuentesGonzález: Bitte zitieren Sie eine bestimmte Stelle auf dieser Seite, die Ihre Ansprüche sichert. – CommonsWare

4

ActivityManager#getRunningAppProcesses() gibt eine Liste von RunningAppProcessInfo zurück. Jede RunningAppProcessInfo hat ein Feld namens Wichtigkeit. Wichtigkeit gleich RunningAppProcessInfo.IMPORTANCE_FOREGROUND scheint zu zeigen, welche Aktivität vom Benutzer aktiv beobachtet wird. Es gibt auch RunningAppProcessInfo.IMPORTANCE_VISIBLE, die niedriger ist, könnte aber einen Blick wert sein.

+0

Danke. Ich werde das untersuchen. – Moritz

+0

Nachdem wir die Möglichkeiten des RunningAppProcesses untersucht haben, hat sich herausgestellt, dass sich die Wichtigkeit der Prozesse nie ändert. Für meine Tätigkeit war die Wichtigkeit IMPORTANCE_FOREGROUND (100) immer wichtig. Dies gilt, wenn die Aktivitäten überhaupt nicht gestartet wurden, die Aktivität im Vordergrund aktiv ist oder der Aktivitätsstapel nach hinten gesendet wird. Keine Änderungen im Wichtigkeitswert. Leider ist dies keine Lösung für mein Problem. :(Irgendwelche anderen Ideen? – Moritz

+0

Ich habe versucht, eines meiner Projekte zu starten und dann ein weiteres oben drauf zu setzen und das im Hintergrund ging zu IMPORTANCE_BACKGROUND (400). Es scheint nur den Paketnamen des gesamten Projekts zu zeigen Nun, ist Ihr Dienst Teil des Pakets, das Sie versuchen zu überprüfen? vielleicht mit dem Debugger angebracht ist die Bedeutung oder etwas zu erhöhen. – jqpubliq

26

Die folgende Antwort: "Is application running in background" fasst die verfügbaren Lösungen für die Hintergrund-/Vordergrundprüfung zusammen.

Hinweis:
Zuvor diese Antwort vorgeschlagen ActivityManager.getRunningAppProcesses() zu verwenden, aber das Verfahren nicht absolut zuverlässig zu sein schien und seine Verwendung abgeraten. Überprüfen Sie den obigen Link für die Details.

3

Ich habe einen BroadcastReceiver implementiert, der vom AlarmManager ausgelöst wird. Der AlarmManager wird auf BOOT_COMPLETED initialisiert. Also muss ich den Empfänger im Manifest deklarieren.

Mein Problem ist, dass ich den BroadcastReceiver nur etwas tun soll, wenn keine meiner eigenen Aktivitäten im Vordergrund stehen (auch wenn der Benutzer nicht mit meiner Anwendung interagiert). Ich ziehe Informationen von einem Remote-Server und möchte den Benutzer nicht darüber informieren, wenn er sich gerade in meiner Anwendung befindet.

Bis jetzt habe ich noch keinen Weg gefunden, festzustellen, ob meine Anwendung im Vordergrund steht. Gibt es eine Möglichkeit, so etwas zu tun? Der ActivityManager sagt mir, ob meine Anwendung läuft, aber nicht, ob sie im Vordergrund ist.

Es scheint keinen direkten Weg zu geben, festzustellen, ob eine Ihrer Aktivitäten die aktuelle Vordergrundaktivität ist. Sie können jedoch den gewünschten Effekt erzielen, indem Sie eine bestellte Sendung und zwei Rundfunkempfänger verwenden. Ein Broadcast-Empfänger muss in OnResume() registriert und in OnPause() nicht registriert werden. Der Empfänger des zweiten Broadcasts wird in Ihrem Manifest deklariert, wie Sie es bereits getan haben. Stellen Sie die androide: Priorität für Ihre Empfänger so ein, dass wenn der dynamisch registrierte Empfänger registriert ist, er zuerst die Absicht empfängt, dann können Sie die Absicht essen, so dass der Empfänger, den Sie in Ihrem Manifest registriert haben, nie benachrichtigt wird.

+0

Bestellte Broadcast-Empfänger sieht aus wie eine gute Lösung, die es wert ist, zu versuchen. – TieDad

1

Ich würde ActivityLifecycleCallbacks verwenden, um viel sauberere Lösung zu erhalten.

Es kann unsicher sein, lesen Sie this, bevor Sie sich entschieden haben, Beispiel unten in der Produktion zu verwenden. Es funktioniert in "Home Development" für mein Gerät und OS-Version.

public class App extends Application implements Application.ActivityLifecycleCallbacks { 

private boolean inForeground; 

@Override 
public void onCreate() { 
    super.onCreate(); 
    registerActivityLifecycleCallbacks(this); 
} 

@Override 
public void onActivityResumed(Activity activity) { 
    inForeground = activity instanceof YourActivity; 
} 

public boolean isInForeground() { 
    return inForeground; 
} 

Register App in AndroidManifest:

<application 
     android:name=".App" /> 

Und das letzte Stück des Puzzles:

public class YourReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     App app = (App) context.getApplicationContext(); 
     if(app.isInForeground()){ 
      // do some stuff 
     } 
    } 
}