9
votes

Utilisez une notification persistante pour permettre à l'utilisateur de revenir à l'application Android

Je développe une application avec de nombreuses activités. Je voudrais créer une notification persistante qui (plus ou moins) dit: "AppName - retourner à AppName" qui sera présent chaque fois que mes services de base sont en cours d'exécution. Créer et élimination de la notification n'était pas un problème.

Maintenant, l'utilisateur pourrait être sur l'une des écrans / activités, laissez l'application, puis souhaitez rentrer de l'application via la notification. Le problème est , la notification doit avoir une intention, qui lance une activité prédéterminée . Je souhaite que la notification renonce à ressaisir l'application dans Quelle que soit l'activité en haut de la pile d'historique .

Ma première tentative d'une planrière laid était de faire une activité (appelons-le "retourfromnotify") dont le seul travail était de "finir" elle-même dans sa "Oncreate". La notification ouvrirait «retour» dans la portée de l'historique des applications, qui se retirerait ensuite immédiatement en envoyant l'utilisateur à l'état de l'historique précédent dans la pile d'applications. Cela semble fonctionner ... Sauf si l'utilisateur n'a utilisé "Retour" pour revenir complètement hors de l'application. Ensuite, lorsqu'ils apportent la notification, "retourfromnotify" des charges, puis se termine, les envoyant à l'écran d'accueil (car il n'y a pas d'activités dans la pile d'historique de l'application).

J'ai envisagé d'essayer de détecter s'il y avait quelque chose dans la pile d'histoire avant "retourfromnotify", et sinon, allumez mon activité principale. Je n'arrive pas à trouver un moyen de faire cela, non plus.

Toute entrée ou suggestion pour un novice Java / Android? FYI, mon historique principal est avec des langues basées sur des scripts.


0 commentaires

5 Réponses :


3
votes

D'accord, je crois que j'ai trouvé un travail satisfaisant - autour pour mon cas particulier . J'ai ajouté un entier statique à ma "MainAlactivité" et à chaque fois que c'est "Oncreate" est tiré, il incrémente l'entier. Chaque fois que c'est "Ondestroy" est tiré, il diminue.

dans mon "retourfromnotify", je regarde l'entier statique pour voir si elle est supérieure à 0. Si oui, je suppose qu'il existe une "mainadicule" active, et que "finir" à l'intérieur "retourfromnotify" reviendra là-bas. . Sinon, il suppose que les utilisateurs ont "soutenu", se termine lui-même, utilisent ensuite "startactivité" pour enfiler une nouvelle instance de "MainAlacivité".

Ce n'est pas une solution universelle, mais à mes fins, je pense que cela suffira. Je suis toujours ouvert à d'autres réponses, et si quelqu'un peut frapper un trou dans ma logique, veuillez le faire - constructive critique est la bienvenue . Merci.


0 commentaires

1
votes

Je suppose qu'il n'y a pas de moyen facile de le faire, mais au lieu d'ajouter un compteur dans la MainActivity, je vais étendre Application :

classe de base pour ceux qui ont besoin de maintenir l'état de l'application globale. Tu peut fournir votre propre mise en œuvre par Spécifier son nom dans votre Androidmanifest.xml tag, qui causera que cette classe soit instancié pour vous quand le processus pour votre application / package est créé.

Je manierais la logique là-bas et j'ai une méthode comme: xxx

à appeler lorsque l'élément de notification est cliqué sur.


1 commentaires

Comment utiliserez-vous alors getintentforlastactivitown ()? N'aurait-il pas un moyen plus simple de conserver une poignée sur la notification de la classe d'application, puis à chaque fois que vous démarrez une nouvelle intention appelée SetLatesteEventInfo à partir de la notification et mettez à jour le PLANDINTENT à l'activité visible actuelle.



1
votes

Ma première approche serait d'utiliser SharedPreferences et stocker une paire de valeurs de clé appelée quelque chose comme lastdisplayedActivité . Ensuite, dans la onctume (et éventuellement `Oncreate '), vous auriez une ligne comme celle-ci: xxx

En d'autres termes, vous stockez une variable à l'échelle de l'application indiquant quelle activité a été affichée pour la dernière fois. Ensuite, vous venez de saisir cette variable de SharedPreferences et de lancer l'activité correspondante.


2 commentaires

Ce n'est pas une mauvaise idée, mais cela vous obligerait à ajouter du code au cycle de vie de chaque activité (que je préférerais ne pas faire). En outre, le lancement de l'activité correspondante maintient l'état de l'instance d'activité précédente ou ferait-il une nouvelle instance de cette activité? J'ai vraiment besoin de cela pour conserver n'importe quel état dans lequel ils se trouvaient.


Il peut restaurer l'état automatiquement dans certains cas, mais si votre activité n'est pas en cours d'affichage, Android peut le tuer à tout moment pour récupérer une mémoire supplémentaire. En d'autres termes, si vous voulez être sûr de sauvegarder l'état de l'activité, vous devez le stocker ailleurs. Il existe de nombreuses façons de le faire, mais si vous avez une bonne quantité de données, je vous recommanderais d'utiliser une base de données SQLite: développeur.android.com/guide/topics/data/data-storage.html#db



0
votes

J'utilise habituellement une activité nommée "Launcher" qui vérifie l'état de ma demande modèle et démarre des activités (ou fait d'autres choses) en fonction des règles du modèle. Je mets modèle dans ma classe d'application. modèle peut utiliser Préférences pour stocker son état. Je le fais pour éviter les champs statiques des activités.


0 commentaires

6
votes

J'aime votre idée originale de créer une activité "retourfromnotify" mieux que votre solution de contournement proposée, car il est possible em> est possible de détecter si la résuméeactivité est au bas de la pile (et donc la seule activité Dans la pile).

Voici comment vous pouvez le faire: p>

Ajoutez votre résuméactivité au manifeste et spécifiez le Nohistory Attribut: P>

public class ResumeActivity extends Activity {

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

        if(isOnlyActivityInStack()) { //check the application stack
            //This activity is the only activity in the application stack, so we need to launch the main activity
            Intent main = new Intent(this, MainActivity.class);
            main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(main);
        } else {
            //Return the user to the last activity they had open
            this.finish();
        }
    }

    /**
     * Checks the currently running tasks. If this activity is the base activity, we know it's the only activity in the stack
     *
     * @return  boolean  This activity is the only activity in the stack?
     **/
    private boolean isOnlyActivityInStack() {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        boolean onlyActivityInStack = false;

        for(RunningTaskInfo tasks : manager.getRunningTasks(Integer.MAX_VALUE)) {
            if(tasks.baseActivity.getPackageName().equals(this.getPackageName())) { //find this package's application stack
                if(tasks.baseActivity.getClassName().equals(this.getClass().getName())) {
                    //If the ResumeActivity is the base activity, we know that it is the only activity in the stack
                    onlyActivityInStack = true;
                    break;
                }
            }
        }

        return onlyActivityInStack;
    }

}


1 commentaires

Oui! Ce projet était pour un travail que je ne suis même plus avec plus, alors j'en ai totalement besoin ... mais ça sonne comme exactement ce que je cherchais, alors merci! Espérons que quelqu'un d'autre le trouvera utile aussi.