92 votes

Android comment effacer l'intention?

Mon application Android est appelé par une intention qui est la transmission de l'information (pendingintent dans la barre d'état).

Quand j'appuie sur le bouton home et rouvrir mon application en maintenant le bouton de la maison, il appelle l'intention à nouveau et même les 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 son supposé

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

Est-il un moyen pour effacer l'intention ou de vérifier si il a été utilisé avant?

155voto

Maks Points 1585

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:

 getIntent().removeExtra("key"); 
 

appel de méthode pour "effacer" l'intention.

Il est un peu tardif depuis que cela a été demandé il y a un an, mais j'espère que cela aidera d'autres à l'avenir.

38voto

tato.rodrigo Points 454

EDIT: je suis en train de monter à poster la solution complète que j'utilise.

Cette solution ne fonctionne pas si le problème est "Pas exécuter du code lorsque l'activité commence à partir de l'Histoire (Applications Récentes)".

Tout d'abord, déclarer boolean votre Activity pour indiquer si l' Intent a déjà été consommé:

    private boolean consumedIntent;

Puis, en toute sécurité stocker et restaurer cette valeur à l'aide de l' onSaveInstanceState et onCreate méthodes pour gérer les changements de configuration et les cas que le système peut tuer votre Activity quand il va à fond.

    private final String SAVED_INSTANCE_STATE_CONSUMED_INTENT = "SAVED_INSTANCE_STATE_CONSUMED_INTENT";

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(SAVED_INSTANCE_STATE_CONSUMED_INTENT, consumedIntent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //set content view ...

        if( savedInstanceState != null ) {
            consumedIntent = savedInstanceState.getBoolean(SAVED_INSTANCE_STATE_CONSUMED_INTENT);
        }

        //other initializations
    }

Maintenant, vérifiez si vous pouvez exécuter votre code en vertu de l' onResume méthode.

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

        //check if this intent should run your code
        //for example, check the Intent action
        boolean shouldThisIntentTriggerMyCode = [...];
        Intent intent = getIntent();
        boolean launchedFromHistory = intent != null ? (intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0 : false;
        if( !launchedFromHistory && shouldThisIntentTriggerMyCode && !consumedIntent ) {
            consumedIntent = true;
            //execute the code that should be executed if the activity was not launched from history
        }
    }

En outre, si votre Activity est configuré pour singleTop, vous devez réinitialiser votre drapeau lorsqu'un nouveau Intent est livré.

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        consumedIntent = false;
    }

19voto

Slynk Points 147

Maks answer travaille pour dégager un extra:

     getIntent().removeExtra("key"); 
 

Une autre commande utile est:

     getIntent().setAction("");
 

Vous pouvez également baliser une intention en appelant:

     getIntent().putExtra("used", true);
 

et puis juste pour vérifier la valeur.

7voto

Eugene Wechsler Points 21

Bref, la réponse est Aucun moyen

Réponse longue. Il n'y a pas une telle chose comme "one-shot" intention. De l'expérience, il est observé que l'activité récente de l'histoire moderne des Androïdes n'est rien de plus que "l'Intention de l'histoire". La dernière intention transmis à l'activité est simplement enregistré dans le système et que le deal. Les gens ci-dessus suggèrent d'utiliser

setAction("")

Mais il ne fonctionne pas, parce que l'intention est déjà connecté jusqu'au moment où vous obtenez à l'intérieur de onNewIntent() ou onStart() la méthode.

J'ai résolu le problème en évitant l'utilisation de ses intentions. Mon problème a été simmiliar à celui affiché par l'auteur. J'ai essayé de mettre en œuvre Globale de Sortie de l'application via le contrôle dans la zone de notification. Il devrait arrêter le service sous-jacent et à proximité de toutes les activités de l'application. Vous pouvez trouver même comportement dans Waze application.

L'algorithme:

  1. Créer PendingIntent pour la notification de contrôle qui passe à "Sortir" de l'action à l'activité. Mais à l'activité spéciale, qui est une simple procuration.
  2. Proxy activité onStart() code analyse de l'intention, de contrôles, d'action et définit l'état de certains modèle de "Quitté".
  3. Proxy activité onStart() code efface intention originale à l'aide de setIntent("") et puis les transfère vers la destination "Racine" de l'activité en appelant startActivity(intent).
  4. Proxy activité onStart() code invoquer finish().
  5. À l'intérieur de onStart() et onNewIntent() de la destination de l'activité de vérifier le modèle de l'état et de l'appel de finition() si elle est "Sorti" (et aussi appel stopService() dans mon cas).

J'espère que cela aidera à quelqu'un parce que je n'ai pas trouvé la réponse sur internet.

1voto

pixel Points 4391

J'ai exactement le même problème. Ma solution consistait à ajouter les variables boolean définies lorsque Intent était 'utilisé' et if sur la base de cette boolean pour vérifier si vous devriez utiliser Intent ou non.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: