Gibt es eine native Android-Methode, um von einem Dienst einen Verweis auf die aktuell ausgeführte Aktivität zu erhalten?
Ich habe einen Dienst im Hintergrund ausgeführt und möchte meine aktuelle Aktivität aktualisieren, wenn ein Ereignis auftritt (im Dienst). Gibt es eine einfache Möglichkeit, dies zu tun (wie die oben vorgeschlagene)?
android
service
android-activity
George
quelle
quelle
Antworten:
Möglicherweise besitzen Sie nicht die "aktuell ausgeführte Aktivität".
Intent
an die Aktivität - hier ist ein Beispielprojekt das dieses Muster demonstriertPendingIntent
(z. B. viacreatePendingResult()
) angeben, das der Dienst aufruftbindService()
und den Dienst eine Ereignismethode für dieses Rückruf- / Listenerobjekt aufrufenIntent
mit niedriger PrioritätBroadcastReceiver
als Backup anNotification
die Aktivität (um eine zu aktivieren, wenn die Aktivität nicht auf dem Bildschirm angezeigt wird) - hier ist ein Blog-Beitrag mit weiteren Informationen zu diesem Musterquelle
instanceof
Überprüfungen durchzuführen oder die Aktivitäten umzugestalten, um eine gemeinsame Superklasse oder Schnittstelle zu teilen. Und wenn Sie die Aktivitäten umgestalten möchten, können Sie dies auch so tun, dass es besser zum Framework passt und mehr Szenarien abdeckt, z. B. dass keine Ihrer Aktivitäten aktiv ist. # 4 ist wahrscheinlich die am wenigsten arbeitende und flexibelste.Update : Dies funktioniert ab Android 5.0 nicht mehr mit den Aktivitäten anderer Apps
Hier ist eine gute Möglichkeit, dies mit dem Aktivitätsmanager zu tun. Grundsätzlich erhalten Sie die runningTasks vom Aktivitätsmanager. Es wird immer zuerst die aktuell aktive Aufgabe zurückgegeben. Von dort können Sie die topActivity erhalten.
Beispiel hier
Es gibt eine einfache Möglichkeit, eine Liste der ausgeführten Aufgaben vom ActivityManager-Dienst abzurufen. Sie können eine maximale Anzahl von Aufgaben anfordern, die auf dem Telefon ausgeführt werden. Standardmäßig wird die aktuell aktive Aufgabe zuerst zurückgegeben.
Sobald Sie das haben, können Sie ein ComponentName-Objekt erhalten, indem Sie die topActivity von Ihrer Liste anfordern.
Hier ist ein Beispiel.
Sie benötigen die folgende Berechtigung für Ihr Manifest:
quelle
As of LOLLIPOP, this method is no longer available to third party applications: the introduction of document-centric recents means it can leak person information to the caller. For backwards compatibility, it will still return a small subset of its data: at least the caller's own tasks, and possibly some other tasks such as home that are known to not be sensitive.
Warnung: Google Play-Verstoß
Google hat damit gedroht , Apps aus dem Play Store zu entfernen, wenn sie Barrierefreiheitsdienste für nicht barrierefreie Zwecke verwenden. Dies wird jedoch Berichten zufolge überdacht .
Benutze ein
AccessibilityService
AccessibilityService
.onAccessibilityEvent
Suchen Sie im Rückruf nach dem Ereignistyp, um festzustellen, wann sich das aktuelle Fenster ändert.TYPE_WINDOW_STATE_CHANGED
PackageManager.getActivityInfo()
.Leistungen
GET_TASKS
Erlaubnis.Nachteile
AccessibilityService
, kann er die OK-Taste nicht drücken, wenn eine App eine Überlagerung auf dem Bildschirm platziert hat. Einige Apps, die dies tun, sind Velis Auto Brightness und Lux. Dies kann verwirrend sein, da der Benutzer möglicherweise nicht weiß, warum er die Taste nicht drücken kann oder wie er sie umgehen kann.AccessibilityService
aktuelle Aktivität wird erst bei der ersten Änderung der Aktivität bekannt.Beispiel
Bedienung
AndroidManifest.xml
Füge dies in dein Manifest ein:
Serviceinfo
Geben Sie dies ein
res/xml/accessibilityservice.xml
:Aktivieren des Dienstes
Jeder Benutzer der App muss das explizit aktivieren
AccessibilityService
, damit es verwendet werden kann. Informationen dazu finden Sie in dieser StackOverflow-Antwort .Beachten Sie, dass der Benutzer die OK-Taste nicht drücken kann, wenn er versucht, den Eingabehilfedienst zu aktivieren, wenn eine App eine Überlagerung auf dem Bildschirm platziert hat, z. B. Velis Auto Brightness oder Lux.
quelle
settingsActivity
für angegebenyour.app.ServiceSettingsActivity
, daher sollten Sie dies in Ihre eigenen Einstellungsaktivität für Ihren Eingabehilfedienst ändern. Ich denke, die Einstellungsaktivität ist sowieso optional, deshalb habe ich diesen Teil aus meiner Antwort entfernt, um es einfacher zu machen.onAccessibilityEvent
erhält jedoch kein Ereignis. Wenn ich den Dienst deaktiviere und wieder aktiviere, wird der Dienst erneut aktiviert undonAccessibilityEvent
beginnt zu funktionieren.Dies kann geschehen durch:
Implementieren Sie Ihre eigene Anwendungsklasse, registrieren Sie sich für ActivityLifecycleCallbacks - auf diese Weise können Sie sehen, was mit unserer App los ist. Bei jedem erneuten Lebenslauf weist der Rückruf die aktuell sichtbare Aktivität auf dem Bildschirm zu und bei einer Pause wird die Zuordnung entfernt. Es verwendet eine Methode,
registerActivityLifecycleCallbacks()
die in API 14 hinzugefügt wurde.Rufen
getApplication()
Sie in Ihrem Service-Aufruf Ihren App-Klassennamen an (in diesem Fall App). Dann können Sie anrufenapp.getActiveActivity()
- das gibt Ihnen eine aktuell sichtbare Aktivität (oder null, wenn keine Aktivität sichtbar ist). Sie können den Namen der Aktivität erhalten, indem Sie anrufenactiveActivity.getClass().getSimpleName()
quelle
onActivityResumed()
,onActivityPaused()
und zugetActiveActivity()
sehen , wie es ist , Callet, wenn auch noch so.activity
undactiveActivity
gleich sind , bevor die ZuordnungactiveActivity
mitnull
Fehler zu vermeiden , um aufgrund verwirbelt Aufruf Reihenfolge der Lebenszyklus Methoden der verschiedenen Aktivitäten.Ich konnte keine Lösung finden, mit der unser Team zufrieden wäre, also haben wir unsere eigene gerollt. Wir verwenden
ActivityLifecycleCallbacks
, um die aktuellen Aktivitäten zu verfolgen und sie dann über einen Dienst verfügbar zu machen:Konfigurieren Sie dann Ihren DI-Container so, dass die Instanz von
MyApplication
for zurückgegeben wirdContextProvider
, z(Beachten Sie, dass die Implementierung
getCurrent()
von im obigen Code weggelassen wird. Es handelt sich nur um eine statische Variable, die vom Anwendungskonstruktor festgelegt wurde.)quelle
activity
undcurrentActivity
gleich ist , bevor die ZuweisungcurrentActivity
mit ,null
um zu vermeiden , Fehler aufgrund von verwirbelt Aufruf Reihenfolge der Lifecycle - Methoden von verschiedenen Aktivitäten.Verwenden
ActivityManager
Wenn Sie nur die Anwendung kennen möchten, die die aktuelle Aktivität enthält, können Sie dies mit verwenden
ActivityManager
. Welche Technik Sie verwenden können, hängt von der Version von Android ab:ActivityManager.getRunningTasks
( Beispiel )ActivityManager.getRunningAppProcesses
( Beispiel )Leistungen
Nachteile
ActivityManager.RunningAppProcessInfo.processState
Beispiel (basierend auf KNaitos Code )
Manifest
Fügen Sie die
GET_TASKS
Berechtigung hinzu zuAndroidManifest.xml
:quelle
Ich benutze dies für meine Tests. Es ist API> 19 und nur für Aktivitäten Ihrer App.
quelle
Verwenden Sie diesen Code für API 21 oder höher. Dies funktioniert und liefert im Vergleich zu den anderen Antworten ein besseres Ergebnis. Es erkennt den Vordergrundprozess perfekt.
quelle
Hier ist meine Antwort, die gut funktioniert ...
Sie sollten in der Lage sein, aktuelle Aktivitäten auf diese Weise abzurufen ... Wenn Sie Ihre App mit einigen Aktivitäten mit vielen Fragmenten strukturieren und verfolgen möchten, was Ihre aktuelle Aktivität ist, würde dies jedoch viel Arbeit erfordern. Mein Szenario war, dass ich eine Aktivität mit mehreren Fragmenten habe. So kann ich die aktuelle Aktivität über das Anwendungsobjekt verfolgen, in dem der gesamte aktuelle Status globaler Variablen gespeichert werden kann.
Hier ist ein Weg. Wenn Sie Ihre Aktivität starten, speichern Sie diese Aktivität nach Application.setCurrentActivity (getIntent ()). Diese Anwendung speichert es. In Ihrer Serviceklasse können Sie einfach Intent currentIntent = Application.getCurrentActivity () ausführen. getApplication (). startActivity (currentIntent);
quelle
Ich weiß nicht, ob es eine dumme Antwort ist, aber ich habe dieses Problem gelöst, indem ich jedes Mal, wenn ich onCreate () einer Aktivität eingegeben habe, ein Flag in freigegebenen Einstellungen gespeichert habe. Dann habe ich den Wert aus shered-Einstellungen verwendet, um herauszufinden, was die Vordergrundaktivität ist.
quelle
Erst kürzlich davon erfahren. Mit apis als:
targetSdkVersion 26
ActivityManager.getCurrentActivity (Kontext)
Hoffe, das nützt nichts.
quelle
getCurrentActivity()
Funktion in derActivityManager
Klasse ( developer.android.com/reference/android/app/ActivityManager ). Komisch, dass diese Funktion existiert :ActivityManager.isUserAMonkey()
.