Mon application Android est appelée par une intention qui transmet des informations (en attente d'intention dans la barre d'état).
Lorsque j'appuie sur le bouton d'accueil et que je rouvre mon application en maintenant le bouton d'accueil, il appelle à nouveau l'intention et les mêmes extras sont toujours là.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
c'est le code qui ne fonctionne pas comme prévu
String imgUrl;
Bundle extras = this.getIntent().getExtras();
if(extras != null){
imgUrl = extras.getString("imgUrl");
if( !imgUrl.equals(textView01.getText().toString()) ){
imageView.setImageDrawable( getImageFromUrl( imgUrl ) );
layout1.setVisibility(0);
textView01.setText(imgUrl);//textview to hold the url
}
}
Et mon intention:
public void showNotification(String ticker, String title, String message,
String imgUrl){
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(ns);
int icon = R.drawable.icon; // icon from resources
long when = System.currentTimeMillis(); // notification time
CharSequence tickerText = ticker; // ticker-text
//make intent
Intent notificationIntent = new Intent(this, activity.class);
notificationIntent.putExtra("imgUrl", imgUrl);
notificationIntent.setFlags(
PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_ONE_SHOT);
PendingIntent contentIntent =
PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT |
PendingIntent.FLAG_ONE_SHOT);
//make notification
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(this, title, message, contentIntent);
//flags
notification.flags = Notification.FLAG_SHOW_LIGHTS |
Notification.FLAG_ONGOING_EVENT |
Notification.FLAG_ONLY_ALERT_ONCE |
Notification.FLAG_AUTO_CANCEL;
//sounds
notification.defaults |= Notification.DEFAULT_SOUND;
//notify
mNotificationManager.notify(1, notification);
}
Existe-t-il un moyen d'effacer l'intention ou de vérifier s'il a déjà été utilisé?
Réponses:
METTRE À JOUR:
Je ne savais pas que cette réponse serait autant mentionnée lorsque je l'ai écrite pour la première fois il y a plus de 5 ans!
Je clarifierai pour souligner que selon la réponse @ tato-rodrigo, cela ne vous aidera pas à détecter une intention déjà gérée dans certaines situations.
Je dois également souligner que je mets «effacer» entre guillemets pour une raison - vous n'effacez pas vraiment l'intention en faisant cela, vous utilisez simplement la suppression de l'extra comme indicateur que cette intention a déjà été vue par l'activité .
J'ai eu exactement le même problème.
La réponse ci-dessus m'a mis sur la bonne voie et j'ai trouvé une solution encore plus simple, utilisez le:
appel de méthode pour "effacer" l'intention.
C'est un peu tard pour répondre car cela a été demandé il y a un an, mais j'espère que cela aidera d'autres à l'avenir.
la source
setIntent(new Intent())
et son fonctionnement très bien maintenant.EDIT: J'édite pour publier la solution complète que j'utilise.
Cette solution fonctionnera si le problème est "Ne pas exécuter du code lorsque l'activité démarre à partir de l'historique (applications récentes)" .
Tout d'abord, déclarez un
boolean
dans votreActivity
pour indiquer si leIntent
a déjà été consommé:Ensuite, stockez et restaurez en toute sécurité cette valeur à l'aide des méthodes
onSaveInstanceState
etonCreate
pour gérer les modifications de configuration et les cas où le système peut vous tuerActivity
lorsqu'il passe en arrière-plan.Maintenant, vérifiez si vous pouvez exécuter votre code sous
onResume
method.De plus, si votre
Activity
est configuré sursingleTop
, vous devez réinitialiser votre indicateur lorsqu'un nouveauIntent
est livré.la source
(intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)
J'ai aidé ce code donc maintenant je peux comprendre quand le début de l'activité est de l'histoire et je peux ignorer mes extras.boolean shouldThisIntentTriggerMyCode = [...];
de la réponse (à quoi sert-il?)consumedIntent
commeString
contenant une notification Uid. Cet Uid peut être simplement ajouté à la notification au niveau du backend comme horodatage actuel. Vous devez également enregistrer cet UidonSaveInstanceState
uniquement si l'intention a été formuléeonCreate
. Cela signifie que vous ne devriez pas enregistrer Uid à partir deonNewIntent
.Maks answer fonctionne pour effacer un extra:
Une autre commande utile est:
Vous pouvez également baliser une intention en appelant:
puis vérifiez simplement la valeur.
la source
Lorsque nous lançons des applications Android à partir de l'historique (applications récentes), l'application peut être lancée avec principalement trois indicateurs d'intention différents.
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
C'est à ce moment que l'activité est lancée à partir de l'historique d'une application qui a été minimisée (appuyez longuement sur la touche d'accueil).
Valeur constante: 1048576 (0x00100000)
FLAG_ACTIVITY_NEW_TASK
C'est à ce moment que l'activité est lancée via "cliquer sur l'icône de l'application" ou via " Filtres d'intention ". Ici, l'activité deviendra le début d'une nouvelle tâche sur cette pile d'historique.
Valeur constante: 268435456 (0x10000000)
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY | FLAG_ACTIVITY_NEW_TASK
C'est à ce moment que l'application a été fermée en appuyant sur le bouton Retour, puis à partir de l'historique (applications récentes).
Valeur constante: 269484032 (0x10100000)
La valeur constante peut être récupérée via
getIntent().getFlags()
Dans le troisième cas, Android recharge les dernières valeurs d'intention de sa mémoire. L'intention de votre application (
getIntent
) aura donc les valeurs de la dernière intention qui a lancé l'application.En fait, l'application doit se comporter comme s'il s'agissait d'un nouveau lancement, avec des valeurs d'intention pour un nouveau lancement plutôt que les valeurs d'intention du lancement précédent. Ce comportement peut être observé si vous lancez l'application en cliquant sur l'icône de l'application, elle n'aura jamais d'anciennes valeurs d'intention. En effet, Android utilise le filtre d'intention suivant pour ce scénario
Mais dans le troisième cas (l'application qui a été fermée, est lancée à partir de l'historique des applications récentes), Android OS utilise cette dernière intention qui a lancé l'application avant qu'elle ne soit fermée (en appuyant sur le bouton retour). Vous finissez donc par avoir d'anciennes valeurs d'intention et le flux d'application n'est pas approprié.
Supprimer l'intention est un moyen de le résoudre, mais cela ne résoudrait pas complètement le problème! Lorsque le système d'exploitation Android recharge l'intention à partir du dernier lancement des applications, et non de la dernière instance de l'intention de lancement.
Un moyen simple d'éviter que cela ne se produise est de le gérer en obtenant le type d' intention pour déterminer le type de lancement.
Donc , dans votre LaunchActivity (celui qui a le filtre défini dans l' intention manifeste), vous pouvez utiliser le code suivant dans les
onCreate()
,onStart()
ou lesonResume()
méthodes.Je présume
normalLaunch()
, ne devrait pas utiliser les paramètres de l'intention; Sinon, vous devrez séparer et optimiser votre méthode de lancement par défaut pour ne pas utiliser les paramètres d'intention.la source
getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
peu importe si je démarre l'activité à partir d'une autre activité (méthode startActivity) ou la rouvre à partir de la pile d'historique (applications récentes).Effacer un objet d' intention :
la source
La réponse courte est impossible
Longue réponse. Il n’existe pas d’intention «ponctuelle». De l'expérience, il est observé que l'histoire récente de l'activité dans les androïdes modernes n'est rien de plus qu'une «histoire d'intention». La dernière intention transmise à l'activité est simplement connectée au système et c'est l'affaire. Les gens ci-dessus suggèrent d'utiliser
Mais cela ne fonctionne pas car l'intention est déjà enregistrée jusqu'au moment où vous l'obtenez dans la méthode onNewIntent () ou onStart ().
J'ai résolu le problème en évitant d'utiliser des intentions. Mon problème était similaire à celui posté par l'auteur. J'ai essayé d'implémenter Global Exit depuis l'application via le contrôle dans la zone de notification. Il doit arrêter le service sous-jacent et fermer toutes les activités de l'application. Vous pouvez trouver le même comportement dans l'application Waze.
L'algorithme:
J'espère que cela aidera quelqu'un car je n'ai pas trouvé de réponse sur Internet.
la source
Assurez - vous que vous utilisez PendingIntent.FLAG_UPDATE_CURRENT drapeau pour PendingIntent .
Où
mPutIntent
est votreIntent
.J'espère que ceci vous aidera.
la source
J'ai récemment eu ce problème et je l'ai résolu en ajoutant un horodatage comme paramètre supplémentaire à l'intention:
Après cela, enregistrez l'horodatage dans les préférences partagées:
la source
J'ai exactement le même problème. Ma solution était d'ajouter une
boolean
variable qui était définie quandIntent
était «utilisé» et uneif
déclaration basée sur celaboolean
pour vérifier si vous deviez utiliserIntent
ou non.la source
Lorsque vous avez terminé de traiter l'intention, procédez comme suit:
Vous ne verrez plus cette intention traitée et vous ne masquerez pas le problème en modifiant le contenu de l'intention traitée.
la source
Je n'ai pas trouvé de moyen de supprimer Intent Extra . Aucune des réponses sur la suppression des extras de l'intention ne fonctionne si vous activez «Ne pas conserver les activités » dans les options du développeur (de cette façon, vous pouvez détruire l'activité et revenir pour tester si les extras sont toujours là).
Pour résoudre le problème, j'ai stocké la valeur booléenne dans SharedPreferences après le traitement des extras d'intention. Lorsque la même intention est renvoyée à l'activité, je vérifie la valeur SharedPreference et décide de traiter l'intent supplémentaire. Si vous envoyez un autre nouveau Intent Extra à la même activité, vous définissez la valeur SharedPreference sur false et Activity la traitera. Exemple :
la source
Même après avoir effacé manuellement les extras Intent et Intent après leur analyse, il semble que Activity.getIntent () retournera toujours l'intention d'origine qui a démarré l'activité.
Pour contourner cela, je recommande quelque chose comme ceci:
De cette façon, il existe un mécanisme pour vider l'intention d'origine tout en conservant la possibilité de conserver explicitement certaines parties des extras d'intention / intention d'origine.
Notez que je n'ai pas testé tous les modes de lancement d'activité.
la source
Le moyen le plus simple est d'éviter d'appeler getIntent () à partir de méthodes autres que onCreate (). Mais cela posera un problème lors du prochain lancement si l'utilisateur a quitté notre activité en appuyant sur le bouton Accueil. Je pense que ce problème n'a pas de solution entièrement fonctionnelle.
la source
Je suis confronté au même problème et j'essaie d'utiliser les méthodes ci-dessus mais cela ne fonctionne pas.
Je pense que cela peut être à cause du mode de lancement de l'acitvity que j'ai utilisé en mode singleTop.
Lorsque j'utilise une application en arrière-plan et que j'utilise RamEater pour simuler un problème, cette intention a toujours un supplément, même si je la définis comme null ou que je supprime la clé.
Le problème est résolu en utilisant le stockage des préférences sur Android pour vérifier que le transfert est passé.
la source
Ce n'est pas une bonne pratique d'ajouter un autre extra juste pour savoir si les extras ont été consommés ou non, pourquoi ne pas le faire?:
la source
Que dis-tu de ça? Définit newIntent comme intention.
la source
Que diriez-vous lorsque vous souhaitez effacer l'intention - le remplacer par un vide?
par exemple.
la source
J'espère que cela aidera tout le monde. Alors d'abord, nous avons l'intention
Placez-le quelque part sur Créer
Maintenant, définissons ceci afin que chaque fois que notre application soit détruite ou quittée, nous supprimerons les données
Vous avez l'idée, si cela ne suffit pas, trouvez simplement plus de rappels `` sur ''
la source
Bien que le
Intent.removeExtra("key")
supprime une clé spécifique des extras, il existe également la méthode Intent.replaceExtras (Bundle) , qui peut être utilisée pour supprimer tous les extras de l'intention, si ellenull
est passée en paramètre.À partir de la documentation:
Étant donné que les méthodes putXXX () initialisent les extras avec un nouveau Bundle s'il est nul, ce n'est pas un problème.
la source
la source