Android: Wie kann ich die aktuelle Vordergrundaktivität (von einem Dienst) abrufen?

180

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)?

George
quelle
Vielleicht kann dies Ihnen eine Idee geben stackoverflow.com/a/28423385/185022
AZ_

Antworten:

87

Gibt es eine native Android-Methode, um von einem Dienst einen Verweis auf die aktuell ausgeführte Aktivität zu erhalten?

Möglicherweise besitzen Sie nicht die "aktuell ausgeführte Aktivität".

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)?

  1. Senden Sie eine Sendung Intentan die Aktivität - hier ist ein Beispielprojekt das dieses Muster demonstriert
  2. Lassen Sie die Aktivität ein PendingIntent(z. B. viacreatePendingResult() ) angeben, das der Dienst aufruft
  3. Lassen Sie die Aktivität ein Rückruf- oder Listener-Objekt über den Dienst registrieren bindService() und den Dienst eine Ereignismethode für dieses Rückruf- / Listenerobjekt aufrufen
  4. Senden Sie eine bestellte Sendung Intentmit niedriger Priorität BroadcastReceiverals Backup an Notificationdie 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 Muster
CommonsWare
quelle
3
Danke, aber da ich eine Menge Aktivitäten habe und nicht alle aktualisieren möchte, suchte ich nach einem Android-Weg, um die Vordergrundaktivität zu erhalten. Wie Sie sagen, sollte ich das nicht können. Das heißt, ich muss mich darum kümmern.
George
1
@ George: Was du willst, würde dir sowieso nicht helfen. Wie Sie hervorheben, haben Sie "eine Menge Aktivitäten". Daher sind das alles getrennte Klassen. Daher kann Ihr Service nichts mit ihnen tun, ohne einen massiven If-Block von 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.
CommonsWare
2
Danke, aber ich habe eine bessere Lösung. Alle meine Aktivitäten erweitern eine angepasste BaseActivity-Klasse. Ich habe ein ContextRegister festgelegt, das die Aktivität immer dann als aktuell registriert, wenn sie im Vordergrund steht, mit literraly 3 Zeilen in meiner BaseActivity-Klasse. Trotzdem danke für die Unterstützung.
George
3
@ George: Achten Sie auf Speicherlecks. Veränderbare statische Datenelemente sind in Java nach Möglichkeit zu vermeiden.
CommonsWare
Ich habe das Objekt eng gekapselt, obwohl ich dies in der Tat berücksichtigen werde. Vielen Dank.
George
139

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.

    ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
    List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
    Log.d("topActivity", "CURRENT Activity ::" + taskInfo.get(0).topActivity.getClassName());
    ComponentName componentInfo = taskInfo.get(0).topActivity;
    componentInfo.getPackageName();

Sie benötigen die folgende Berechtigung für Ihr Manifest:

<uses-permission android:name="android.permission.GET_TASKS"/>
Nelson Ramirez
quelle
3
Ihre Antwort ist 100% richtig.Thanxx 4 it.It besser, dass Sie die gleiche Antwort hier posten
Shahzad Imam
1
@ArtOfWarfare wurde nicht überprüft, aber ja, die Anzahl der Fragmente, die Sie haben, ist irrelevant, da sie immer von einer einzelnen Aktivität gehostet werden.
Nelson Ramirez
2
Wenn ich die aktuelle Aktivität häufiger benötige, muss ich sehr häufig abfragen, oder? Gibt es eine Möglichkeit, ein Rückrufereignis zu erhalten, wenn sich die Vordergrundaktivität ändert?
Nizam.sp
43
Damit alle wissen, geben die Dokumente dies über die Methode getRunningTasks () an. -------- Hinweis: Diese Methode ist nur zum Debuggen und Präsentieren von Benutzeroberflächen für die Aufgabenverwaltung vorgesehen. Dies sollte niemals für die Kernlogik in einer Anwendung verwendet werden, z. B. für die Entscheidung zwischen verschiedenen Verhaltensweisen basierend auf den hier enthaltenen Informationen. Solche Verwendungen werden nicht unterstützt und werden wahrscheinlich in Zukunft nicht mehr verwendet. Wenn beispielsweise mehrere Anwendungen gleichzeitig aktiv ausgeführt werden können, sind Annahmen über die Bedeutung der Daten hier für Zwecke des Kontrollflusses falsch. ------------
Ryan
30
Semifake auf API 21As 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.
Sherpya
114

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

Leistungen

  • Getestet und funktioniert in Android 2.2 (API 8) bis Android 7.1 (API 25).
  • Benötigt keine Abfrage.
  • Benötigt keine GET_TASKSErlaubnis.

Nachteile

  • Jeder Benutzer muss den Dienst in den Eingabehilfen von Android aktivieren.
  • Dies ist nicht 100% zuverlässig. Gelegentlich sind die Ereignisse nicht in Ordnung.
  • Der Dienst wird immer ausgeführt.
  • Wenn ein Benutzer versucht, das zu aktivieren 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.
  • Die AccessibilityServiceaktuelle Aktivität wird erst bei der ersten Änderung der Aktivität bekannt.

Beispiel

Bedienung

public class WindowChangeDetectingService extends AccessibilityService {

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();

        //Configure these here for compatibility with API 13 and below.
        AccessibilityServiceInfo config = new AccessibilityServiceInfo();
        config.eventTypes = AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED;
        config.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;

        if (Build.VERSION.SDK_INT >= 16)
            //Just in case this helps
            config.flags = AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;

        setServiceInfo(config);
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            if (event.getPackageName() != null && event.getClassName() != null) {
                ComponentName componentName = new ComponentName(
                    event.getPackageName().toString(),
                    event.getClassName().toString()
                );

                ActivityInfo activityInfo = tryGetActivity(componentName);
                boolean isActivity = activityInfo != null;
                if (isActivity)
                    Log.i("CurrentActivity", componentName.flattenToShortString());
            }
        }
    }

    private ActivityInfo tryGetActivity(ComponentName componentName) {
        try {
            return getPackageManager().getActivityInfo(componentName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            return null;
        }
    }

    @Override
    public void onInterrupt() {}
}

AndroidManifest.xml

Füge dies in dein Manifest ein:

<application>
    <service
        android:label="@string/accessibility_service_name"
        android:name=".WindowChangeDetectingService"
        android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
        <intent-filter>
            <action android:name="android.accessibilityservice.AccessibilityService"/>
        </intent-filter>
        <meta-data
            android:name="android.accessibilityservice"
            android:resource="@xml/accessibilityservice"/>
    </service>
</application>

Serviceinfo

Geben Sie dies ein res/xml/accessibilityservice.xml:

<?xml version="1.0" encoding="utf-8"?>
<!-- These options MUST be specified here in order for the events to be received on first
 start in Android 4.1.1 -->
<accessibility-service
    xmlns:tools="http://schemas.android.com/tools"
    android:accessibilityEventTypes="typeWindowStateChanged"
    android:accessibilityFeedbackType="feedbackGeneric"
    android:accessibilityFlags="flagIncludeNotImportantViews"
    android:description="@string/accessibility_service_description"
    xmlns:android="http://schemas.android.com/apk/res/android"
    tools:ignore="UnusedAttribute"/>

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.

Sam
quelle
1
@lovemint, was ich damit gemeint habe, ist: Ich habe ein Beispiel settingsActivityfür angegeben your.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.
Sam
1
Vielen Dank, nur letzte Frage. Wenn ich von API 8 auf die aktuelle umsteigen muss, sollte ich das im Code tun, anstatt XML zu verwenden?
paolo2988
1
@ Lovemint, das stimmt. Ich habe gerade den Beispielcode aktualisiert, um dies zu tun.
Sam
1
@ Sam Ich kann bestätigen, dass dieser Service einwandfrei funktioniert. Ein seltsames Verhalten, ich habe in der Hauptaktivität eine Absicht verwendet, um den Accessibility Service zu aktivieren. Nach dieser ersten Aktivierung wird der Dienst aktiviert, onAccessibilityEventerhält jedoch kein Ereignis. Wenn ich den Dienst deaktiviere und wieder aktiviere, wird der Dienst erneut aktiviert und onAccessibilityEventbeginnt zu funktionieren.
paolo2988
2
Vielen Dank für Ihren Code. Ich habe diese App für Sie erstellt :)
Tresor
20

Dies kann geschehen durch:

  1. 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.

    public class App extends Application {
    
    private Activity activeActivity;
    
    @Override
    public void onCreate() {
        super.onCreate();
        setupActivityListener();
    }
    
    private void setupActivityListener() {
    registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            }
            @Override
            public void onActivityStarted(Activity activity) {
            }
            @Override
            public void onActivityResumed(Activity activity) {
                activeActivity = activity;
            }
            @Override
            public void onActivityPaused(Activity activity) {
                activeActivity = null;
            }
            @Override
            public void onActivityStopped(Activity activity) {
            }
            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
            }
            @Override
            public void onActivityDestroyed(Activity activity) {
            }
        });
    }
    
    public Activity getActiveActivity(){
        return activeActivity;
    }
    
    }
  2. Rufen getApplication()Sie in Ihrem Service-Aufruf Ihren App-Klassennamen an (in diesem Fall App). Dann können Sie anrufen app.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()

Vit Veres
quelle
1
Ich erhalte eine Nullpointer-Ausnahme bei activeActivity.getClass (). GetSimpleName (). Können Sie bitte helfen
Anfänger
Wie Sie aus den ActivityLifecycleCallbacks ersehen können, gibt application.getActiveActivity () null zurück, falls die Aktivität nicht sichtbar ist. Das bedeutet, dass keine Aktivität sichtbar ist. Sie müssen dies in Ihrem Dienst oder wo immer Sie dies verwenden, überprüfen.
Vit Veres
ok..aber falls die Aktivität fortgesetzt wird, sollte dies nicht null zurückgeben ?? Meine Aktivität hatte begonnen und in ihrem Lebenslauf bekam ich so
Anfänger
Schwer zu erraten, versuchen einzelne Stützpunkte zu stellen onActivityResumed(), onActivityPaused()und zu getActiveActivity()sehen , wie es ist , Callet, wenn auch noch so.
Vit Veres
@beginner muss man , wenn zu überprüfen activityund activeActivitygleich sind , bevor die Zuordnung activeActivitymit nullFehler zu vermeiden , um aufgrund verwirbelt Aufruf Reihenfolge der Lebenszyklus Methoden der verschiedenen Aktivitäten.
Rahul Tiwari
16

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:

public interface ContextProvider {
    Context getActivityContext();
}

public class MyApplication extends Application implements ContextProvider {
    private Activity currentActivity;

    @Override
    public Context getActivityContext() {
         return currentActivity;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                MyApplication.this.currentActivity = activity;
            }

            @Override
            public void onActivityStarted(Activity activity) {
                MyApplication.this.currentActivity = activity;
            }

            @Override
            public void onActivityResumed(Activity activity) {
                MyApplication.this.currentActivity = activity;
            }

            @Override
            public void onActivityPaused(Activity activity) {
                MyApplication.this.currentActivity = null;
            }

            @Override
            public void onActivityStopped(Activity activity) {
                // don't clear current activity because activity may get stopped after
                // the new activity is resumed
            }

            @Override
            public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

            }

            @Override
            public void onActivityDestroyed(Activity activity) {
                // don't clear current activity because activity may get destroyed after
                // the new activity is resumed
            }
        });
    }
}

Konfigurieren Sie dann Ihren DI-Container so, dass die Instanz von MyApplicationfor zurückgegeben wird ContextProvider, z

public class ApplicationModule extends AbstractModule {    
    @Provides
    ContextProvider provideMainActivity() {
        return MyApplication.getCurrent();
    }
}

(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.)

Muxa
quelle
4
muss man , wenn zu überprüfen activityund currentActivitygleich ist , bevor die Zuweisung currentActivitymit , nullum zu vermeiden , Fehler aufgrund von verwirbelt Aufruf Reihenfolge der Lifecycle - Methoden von verschiedenen Aktivitäten.
Rahul Tiwari
14

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:

Leistungen

  • Sollte bisher in allen Android-Versionen funktionieren.

Nachteile

  • Funktioniert nicht in Android 5.1+ (es wird nur Ihre eigene App zurückgegeben)
  • Die Dokumentation für diese APIs heißt es, dass sie nur zum Debuggen und Verwalten von Benutzeroberflächen vorgesehen sind.
  • Wenn Sie Echtzeit-Updates wünschen, müssen Sie Polling verwenden.
  • Verlässt sich auf eine versteckte API: ActivityManager.RunningAppProcessInfo.processState
  • Diese Implementierung nimmt die App Switcher-Aktivität nicht auf.

Beispiel (basierend auf KNaitos Code )

public class CurrentApplicationPackageRetriever {

    private final Context context;

    public CurrentApplicationPackageRetriever(Context context) {
        this.context = context;
    }

    public String get() {
        if (Build.VERSION.SDK_INT < 21)
            return getPreLollipop();
        else
            return getLollipop();
    }

    private String getPreLollipop() {
        @SuppressWarnings("deprecation")
        List<ActivityManager.RunningTaskInfo> tasks =
            activityManager().getRunningTasks(1);
        ActivityManager.RunningTaskInfo currentTask = tasks.get(0);
        ComponentName currentActivity = currentTask.topActivity;
        return currentActivity.getPackageName();
    }

    private String getLollipop() {
        final int PROCESS_STATE_TOP = 2;

        try {
            Field processStateField = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState");

            List<ActivityManager.RunningAppProcessInfo> processes =
                activityManager().getRunningAppProcesses();
            for (ActivityManager.RunningAppProcessInfo process : processes) {
                if (
                    // Filters out most non-activity processes
                    process.importance <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
                    &&
                    // Filters out processes that are just being
                    // _used_ by the process with the activity
                    process.importanceReasonCode == 0
                ) {
                    int state = processStateField.getInt(process);

                    if (state == PROCESS_STATE_TOP) {
                        String[] processNameParts = process.processName.split(":");
                        String packageName = processNameParts[0];

                        /*
                         If multiple candidate processes can get here,
                         it's most likely that apps are being switched.
                         The first one provided by the OS seems to be
                         the one being switched to, so we stop here.
                         */
                        return packageName;
                    }
                }
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }

        return null;
    }

    private ActivityManager activityManager() {
        return (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    }

}

Manifest

Fügen Sie die GET_TASKSBerechtigung hinzu zu AndroidManifest.xml:

<!--suppress DeprecatedClassUsageInspection -->
<uses-permission android:name="android.permission.GET_TASKS" />
Sam
quelle
10
Dies funktioniert nicht mehr auf Android M. getRunningAppProcesses () gibt jetzt nur das Paket Ihrer Anwendung zurück
Lior Iluz
1
Funktioniert auch nicht für API Level 22 (Android 5.1). Getestet auf Build LPB23
sumitb.mdi
9

Ich benutze dies für meine Tests. Es ist API> 19 und nur für Aktivitäten Ihrer App.

@TargetApi(Build.VERSION_CODES.KITKAT)
public static Activity getRunningActivity() {
    try {
        Class activityThreadClass = Class.forName("android.app.ActivityThread");
        Object activityThread = activityThreadClass.getMethod("currentActivityThread")
                .invoke(null);
        Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
        activitiesField.setAccessible(true);
        ArrayMap activities = (ArrayMap) activitiesField.get(activityThread);
        for (Object activityRecord : activities.values()) {
            Class activityRecordClass = activityRecord.getClass();
            Field pausedField = activityRecordClass.getDeclaredField("paused");
            pausedField.setAccessible(true);
            if (!pausedField.getBoolean(activityRecord)) {
                Field activityField = activityRecordClass.getDeclaredField("activity");
                activityField.setAccessible(true);
                return (Activity) activityField.get(activityRecord);
            }
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

    throw new RuntimeException("Didn't find the running activity");
}
Espinchi
quelle
Ersetzen Sie ArrayMap durch Map und es funktioniert auch unter 4.3. Frühere Android-Versionen nicht getestet.
Oliver Jonas
2

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.

if (Build.VERSION.SDK_INT >= 21) {
    String currentApp = null;
    UsageStatsManager usm = (UsageStatsManager) this.getSystemService(Context.USAGE_STATS_SERVICE);
    long time = System.currentTimeMillis();
    List<UsageStats> applist = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 1000, time);
    if (applist != null && applist.size() > 0) {
        SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
        for (UsageStats usageStats : applist) {
            mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);

        }
        if (mySortedMap != null && !mySortedMap.isEmpty()) {
            currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
        }
    }
Manish Godhani
quelle
Können Sie bitte näher erläutern, wie die Ergebnisse dieser Methode besser sind als die anderen Antworten?
Sam
Funktioniert dies auch mit dem Benachrichtigungsmenü? Ich stehe vor einem Problem, bei dem ich einen Anruf oder eine Nachricht erhalte. UsageStatsManager gibt mir anstelle meiner App den Paketnamen systemUi.
Kukroid
@kukroid, stellen Sie eine separate Frage und geben Sie Ihren Quellcode, Geräteinformationen und die von Ihnen verwendeten Messaging- und Telefon-Apps an.
Sam
0

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);

John3328
quelle
2
Dies setzt voraus, dass der Dienst im selben Prozess wie die Aktivität ausgeführt wird, oder?
Helleleye
0

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.

Vlad Vladescu
quelle
1
Wir suchen nach einem nativen Weg, dies zu tun
IgniteCoders
-3

Erst kürzlich davon erfahren. Mit apis als:

  • minSdkVersion 19
  • targetSdkVersion 26

    ActivityManager.getCurrentActivity (Kontext)

Hoffe, das nützt nichts.

user3709410
quelle
1
Hatte meine Hoffnungen geweckt. Vielleicht existierte es, als dies beantwortet wurde, aber derzeit gibt es keine getCurrentActivity()Funktion in der ActivityManagerKlasse ( developer.android.com/reference/android/app/ActivityManager ). Komisch, dass diese Funktion existiert : ActivityManager.isUserAMonkey().
ByteSlinger
1
Dadurch wird erkannt, ob Sie zum Testen Ihrer Aktivität ein Affentestmittel verwenden. Obwohl es ein lustiger Name ist, könnte er sehr nützlich sein, um developer.android.com/studio/test/monkeyrunner
Ken Corey am