Existe-t-il un moyen Android natif pour obtenir une référence à l'activité en cours d'exécution à partir d'un service?
J'ai un service en cours d'exécution en arrière-plan et je souhaite mettre à jour mon activité actuelle lorsqu'un événement se produit (dans le service). Existe-t-il un moyen simple de le faire (comme celui que j'ai suggéré ci-dessus)?
android
service
android-activity
George
la source
la source
Réponses:
Vous n'êtes peut-être pas propriétaire de «l'activité en cours d'exécution».
Intent
à l'activité - voici un exemple de projet illustrant ce modèlePendingIntent
(par exemple, viacreatePendingResult()
) que le service appellebindService()
, et que le service appelle une méthode d'événement sur cet objet de rappel / d'écouteIntent
à l'activité, avec une priorité faibleBroadcastReceiver
comme sauvegarde (pour augmenter uneNotification
si l'activité n'est pas à l'écran) - voici un article de blog avec plus d'informations sur ce modèlela source
instanceof
vérifications ou sans refactoriser les activités pour partager une superclasse ou une interface commune. Et si vous comptez refactoriser les activités, vous pouvez tout aussi bien le faire d'une manière qui correspond mieux au cadre et couvre plus de scénarios, comme aucune de vos activités n'est active. Le n ° 4 est probablement le moins de travail et le plus flexible.Mise à jour : cela ne fonctionne plus avec les activités des autres applications à partir d'Android 5.0
Voici une bonne façon de le faire en utilisant le gestionnaire d'activités. Vous obtenez essentiellement les runningTasks du gestionnaire d'activités. Il retournera toujours la tâche actuellement active en premier. De là, vous pouvez obtenir le topActivity.
Exemple ici
Il existe un moyen simple d'obtenir une liste des tâches en cours d'exécution à partir du service ActivityManager. Vous pouvez demander un nombre maximum de tâches en cours d'exécution sur le téléphone et, par défaut, la tâche actuellement active est renvoyée en premier.
Une fois que vous avez cela, vous pouvez obtenir un objet ComponentName en demandant le topActivity de votre liste.
Voici un exemple.
Vous aurez besoin de l'autorisation suivante sur votre manifeste:
la source
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.
Avertissement: violation de Google Play
Google a menacé de supprimer des applications du Play Store si elles utilisent des services d'accessibilité à des fins non d'accessibilité. Cependant, cela serait en cours de réexamen .
Utilisez un
AccessibilityService
AccessibilityService
.onAccessibilityEvent
rappel, vérifiez le type d'événement pour déterminer quand la fenêtre actuelle change.TYPE_WINDOW_STATE_CHANGED
PackageManager.getActivityInfo()
.Avantages
GET_TASKS
permission.Désavantages
AccessibilityService
, il ne peut pas appuyer sur le bouton OK si une application a placé une superposition à l'écran. Certaines applications qui font cela sont Velis Auto Brightness et Lux. Cela peut être déroutant car l'utilisateur peut ne pas savoir pourquoi il ne peut pas appuyer sur le bouton ou comment le contourner.AccessibilityService
ne connaîtront pas l'activité en cours avant le premier changement d'activité.Exemple
Un service
AndroidManifest.xml
Fusionnez ceci dans votre manifeste:
Info service
Mettez ceci dans
res/xml/accessibilityservice.xml
:Activation du service
Chaque utilisateur de l'application devra activer explicitement le
AccessibilityService
pour pouvoir l'utiliser. Consultez cette réponse StackOverflow pour savoir comment procéder.Notez que l'utilisateur ne pourra pas appuyer sur le bouton OK lorsqu'il essaie d'activer le service d'accessibilité si une application a placé une superposition à l'écran, telle que Velis Auto Brightness ou Lux.
la source
settingsActivity
deyour.app.ServiceSettingsActivity
, vous devriez donc le changer pour votre propre activité de paramètres pour votre service d'accessibilité. Je pense que l'activité des paramètres est facultative de toute façon, j'ai donc supprimé cette partie de ma réponse pour la rendre plus simple.onAccessibilityEvent
ne reçoit aucun événement, mais si je désactive et réactive le service d'accessibilité, le service est réactivé etonAccessibilityEvent
commence à fonctionner.Cela peut être fait par:
Implémentez votre propre classe d'application, inscrivez-vous à ActivityLifecycleCallbacks - de cette façon, vous pouvez voir ce qui se passe avec notre application. À chaque reprise, le rappel attribue l'activité visible actuelle à l'écran et en pause, il supprime l'affectation. Il utilise une méthode
registerActivityLifecycleCallbacks()
qui a été ajoutée dans l'API 14.Dans votre appel de service
getApplication()
et cast dans le nom de votre classe d'application (App dans ce cas). Que vous pouvez appelerapp.getActiveActivity()
- cela vous donnera une activité visible actuelle (ou nulle lorsqu'aucune activité n'est visible). Vous pouvez obtenir le nom de l'activité en appelantactiveActivity.getClass().getSimpleName()
la source
onActivityResumed()
,onActivityPaused()
etgetActiveActivity()
de voir comment est-il callet, le cas échéant.activity
etactiveActivity
sont les mêmes avant d'assigneractiveActivity
avecnull
afin d'éviter les erreurs dues à l'ordre d'appel entremêlé des méthodes de cycle de vie de diverses activités.Je n'ai pas trouvé de solution qui plairait à notre équipe, alors nous avons lancé la nôtre. Nous utilisons
ActivityLifecycleCallbacks
pour garder une trace de l'activité actuelle, puis l'exposer via un service:Configurez ensuite votre conteneur DI pour renvoyer l'instance de
MyApplication
forContextProvider
, par exemple(Notez que l'implémentation de
getCurrent()
est omise du code ci-dessus. Il s'agit simplement d'une variable statique définie à partir du constructeur de l'application)la source
activity
etcurrentActivity
sont identiques avant d'affectercurrentActivity
avecnull
afin d'éviter les erreurs dues à l'ordre d'appel entremêlé des méthodes du cycle de vie de diverses activités.Utilisation
ActivityManager
Si vous souhaitez uniquement connaître l' application contenant l'activité en cours, vous pouvez le faire en utilisant
ActivityManager
. La technique que vous pouvez utiliser dépend de la version d'Android:ActivityManager.getRunningTasks
( exemple )ActivityManager.getRunningAppProcesses
( exemple )Avantages
Désavantages
ActivityManager.RunningAppProcessInfo.processState
Exemple (basé sur le code de KNaito )
Manifeste
Ajoutez l'
GET_TASKS
autorisation àAndroidManifest.xml
:la source
J'utilise ceci pour mes tests. C'est API> 19, et uniquement pour les activités de votre application.
la source
Utilisez ce code pour l'API 21 ou supérieur. Cela fonctionne et donne un meilleur résultat par rapport aux autres réponses, il détecte parfaitement le processus de premier plan.
la source
Voici ma réponse qui fonctionne très bien ...
Vous devriez pouvoir obtenir l'activité actuelle de cette manière ... Si vous structurez votre application avec quelques activités avec de nombreux fragments et que vous souhaitez garder une trace de votre activité actuelle, cela prendrait beaucoup de travail. Mon senario était que j'avais une activité avec plusieurs fragments. Ainsi, je peux garder une trace de l'activité actuelle via l'objet d'application, qui peut stocker tout l'état actuel des variables globales.
Voici un moyen. Lorsque vous démarrez votre activité, vous stockez cette activité par Application.setCurrentActivity (getIntent ()); Cette application le stockera. Sur votre classe de service, vous pouvez simplement faire comme Intent currentIntent = Application.getCurrentActivity (); getApplication (). startActivity (currentIntent);
la source
Je ne sais pas si c'est une réponse stupide, mais j'ai résolu ce problème en stockant un drapeau dans les préférences partagées chaque fois que je suis entré dans onCreate () d'une activité, puis j'ai utilisé la valeur des préférences shered pour savoir en quoi consiste l'activité de premier plan.
la source
Récemment découvert à ce sujet. Avec des API comme:
targetSdkVersion 26
ActivityManager.getCurrentActivity (contexte)
J'espère que c'est utile.
la source
getCurrentActivity()
fonction dans laActivityManager
classe ( developer.android.com/reference/android/app/ActivityManager ). Drôle que cette fonction existe:ActivityManager.isUserAMonkey()
.