Comment éviter de revenir à l'activité précédente?

210

Lorsque le bouton BACK est enfoncé sur le téléphone, je souhaite empêcher une activité spécifique de revenir à la précédente.

Plus précisément, j'ai des écrans de connexion et d'inscription, les deux démarrent une nouvelle activité appelée HomeScreenlorsque la connexion / l'inscription réussie se produit. Une fois HomeScreen démarré, je souhaite empêcher les utilisateurs de revenir aux écrans de connexion ou d'inscription en appuyant sur la touche RETOUR.

J'ai essayé d'utiliser Intent.FLAG_ACTIVITY_NO_HISTORY, mais comme l'application a une intégration Facebook, lorsque la `` Connexion avec Facebook '' est utilisée, Facebook devrait revenir à l'écran de connexion initial, donc je devrais garder un historique de ces activités.

J'ai pensé remplacer le comportement du bouton BACK HomeScreenpour terminer directement une application lorsque le bouton est enfoncé et j'ai utilisé

@Override
public void onBackPressed() {
    finish();
}

mais cela ne fonctionne pas non plus.

ecem
la source
1
Juste pour clarifier, essayez-vous de capturer le comportement de retour pour tout le monde sauf Facebook?
havexz
2
Dans un certain sens, oui, mais en fait, ce que je veux, c'est après une connexion réussie et l'ouverture de HomeScreen, l'utilisateur ne devrait pas pouvoir revenir à l'écran de connexion en appuyant sur le bouton BACK. Tout comme Twitter ou Foursquare par exemple, une fois que nous nous connectons à ces applications, nous ne voyons pas la page de connexion tant que nous ne nous déconnectons pas (même si nous appuyons sur RETOUR après la connexion).
ecem

Réponses:

345

Ma suggestion serait de terminer l'activité à laquelle vous ne voulez pas que les utilisateurs retournent. Par exemple, dans votre activité de connexion, juste après avoir appelé startActivity, appelez finish(). Lorsque les utilisateurs cliquent sur le bouton de retour, ils ne pourront pas accéder à l'activité de connexion, car celle-ci a été supprimée de la pile.

codeur
la source
2
Que faire si je souhaite que le thread de l'activité précédente reste en cours d'exécution?
AlleyOOP
2
Vous ne voudriez pas suivre mon approche alors. L'appel de finish () va tuer l'activité. Pourriez-vous démarrer votre processus que vous souhaitez exécuter dans l'activité que vous allez?
codeur
7
Remarque: si vous appelez finishpendant une transition partagée, vous pouvez avoir un saignement de l'activité précédente. par exemple, si vous avez HomeActivity-> IntermediateActivity-> FinalActivity, et vous appelez finish()au IntermediateActivityimmédiatement après le démarrage de la , FinalActivityvous verrez le HomeActivitypour un moment bref.
David Murdoch
101

La solution suivante peut être très utile dans le scénario de connexion / activité principale habituel ou dans la mise en œuvre d'un écran de blocage.

Pour minimiser l'application plutôt que de revenir à l'activité précédente, vous pouvez remplacer onBackPressed()comme ceci:

@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

moveTaskToBack(boolean nonRoot)laisse votre pile arrière telle qu'elle est, met simplement votre tâche (toutes les activités) en arrière-plan. Comme si l'utilisateur appuyait sur le bouton Accueil .

Paramètre boolean nonRoot- Si faux, cela ne fonctionne que si l'activité est la racine d'une tâche; si vrai, cela fonctionnera pour toute activité dans une tâche.

Marcel Bro
la source
3
Parfait pour un écran de connexion car il garde l'historique intact.
Hackmodford
Merci, j'ai essayé de trouver ça pendant environ trois jours. À cause d'Android: noHistory = "true", le drapeau Activity ne fonctionne pas comme prévu (le drapeau noHistory recrée l'activité après la minimisation) et finish () parfois ne fonctionne pas pour moi, mais pourquoi je ne comprends toujours pas.
Denshov
37

Je ne sais pas exactement ce que vous voulez, mais il semble que cela devrait être possible, et il semble également que vous soyez déjà sur la bonne voie.

Voici quelques liens qui pourraient vous aider:

Désactiver le bouton de retour dans Android

  MyActivity.java =>
    @Override
    public void onBackPressed() {

       return;
    }

Comment puis-je désactiver le retour à une activité?

  AndroidManifest.xml =>
<activity android:name=".SplashActivity" android:noHistory="true"/>
paulsm4
la source
1
Je ne peux pas utiliser l'option noHistory en raison du problème Facebook que j'ai essayé d'expliquer dans ma question et également l'un des commentaires. Mais le problème avec le bouton BACK n'est pas de le désactiver, mais de le faire quitter toute l'application comme System.exit(0)on l'appelle (je sais que ce n'est pas la meilleure pratique, mais je voulais juste donner un exemple).
ecem
Merci, cela a très bien fonctionné. La seule suggestion que je ferais ici serait, pas besoin de retour. Supprimez simplement super.onBackPressed () et laissez la méthode vide. Cela fonctionne aussi bien
hyperCoder
20

Il existe deux solutions pour votre cas, l'activité A démarre l'activité B, mais vous ne souhaitez pas revenir à l'activité A de l'activité B.

1. Suppression de l'activité précédente A de la pile arrière.

    Intent intent = new Intent(activityA.this, activityB.class);
    startActivity(intent);
    finish(); // Destroy activity A and not exist in Back stack

2. Désactiver l'action du bouton de retour dans l'activité B.

Il existe deux façons d'empêcher l'événement de retour en arrière comme ci-dessous,

1) Recommander une approche

@Override
public void onBackPressed() {
}

2, remplacer la méthode onKeyDown

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode==KeyEvent.KEYCODE_BACK) {
        return false;
    }
    return super.onKeyDown(keyCode, event);
}

J'espère que c'est utile, mais cela dépend toujours de vos situations.

Luna Kong
la source
3
N'est-ce pas une mauvaise expérience utilisateur de désactiver le onBackPressed ()?
C. Skjerdal
Cela dépend totalement de ce que vous essayez de faire, la fonctionnalité de l'application en a besoin, alors allez-y.
user3099225
C'est incroyable de voir comment j'ai complètement oublié la première méthode utilisant finish(). Inutilement réfléchi avec nohistoryattribut, indicateurs d'intention, balises de manifeste d'activité parent, etc.! Idiot, merci pour la réponse!
varun
8

Puisqu'il existe déjà de nombreuses grandes solutions suggérées, essayez mal de donner une explication plus dipictive.

Comment sauter pour revenir à l'activité précédente?

Supprimez l'activité précédente de Backstack. Facile

Comment supprimer l'activité précédente de Backstack?

finish()Méthode d' appel

Le flux normal:

entrez la description de l'image ici
Toutes les activités sont stockées dans une pile appelée Backstack.
Lorsque vous démarrez une nouvelle activité ( startActivity(...)), la nouvelle activité est poussée en haut de la pile et lorsque vous appuyez sur le bouton de retour, l'activité est extraite de la pile.
Un point clé à noter est que lorsque le bouton retour est enfoncé, la finish();méthode est appelée en interne. Il s'agit du comportement par défaut de la méthode onBackPressed ().

Donc, si vous voulez sauter l'activité B?

soit A <--- C

Ajoutez simplement la finish();méthode après votre startActvity(...)dans l'activité B

Intent i = new Intent(this, C.class);
startActivity(i);
finish();

entrez la description de l'image ici

Rohit Singh
la source
6

finish()vous donne la méthode pour fermer l'activité en cours et non la totalité de l'application. Et vous feriez mieux de ne pas chercher de méthodes pour tuer l'application. Petit conseil.

Avez-vous essayé la conjonction de Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NO_HISTORY? N'oubliez pas d'utiliser ces drapeaux pour Intentcommencer l'activité!

cadavre
la source
2
FLAG_ACTIVITY_NO_HISTORYempêche mon LoginScreen de capturer le rappel de Facebook lorsque la connexion avec Facebook est utilisée. Parce qu'une fois que le focus sort de l'écran de connexion, il ne peut pas être repris (car il n'y a pas d'historique). Mais je ne l'ai pas essayé avec Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS, je vais le vérifier, merci!
ecem
merci aussi pour la finish()méthode, je ne la connaissais pas.
ecem
4

Mettez finish()juste après

Intent i = new Intent(Summary1.this,MainActivity.class);
            startActivity(i);
finish();
Param Trivedi
la source
1
C'est essentiellement ce que la réponse acceptée de quatre ans a dit.
TylerH
3

La réponse de paulsm4 est la bonne. Si onBackPressed()vous venez de revenir, cela désactivera le bouton de retour. Cependant, je pense qu'une meilleure approche étant donné votre cas d'utilisation est d'inverser la logique d'activité, c'est-à-dire de faire de votre activité à domicile la principale, de vérifier si l'utilisateur y est connecté, sinon de démarrer l'activité de connexion. La raison en est que si vous remplacez le bouton de retour dans votre activité principale, la plupart des utilisateurs seront confus lorsqu'ils appuieront et votre application ne fera rien.

dmon
la source
3

Cette méthode fonctionne bien

Intent intent = new Intent(Profile.this, MainActivity.class); 
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent);
pulak
la source
2

Remplacez simplement la méthode onKeyDown et vérifiez si le bouton de retour a été enfoncé.

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    if (keyCode == KeyEvent.KEYCODE_BACK) 
    {
        //Back buttons was pressed, do whatever logic you want
    }

    return false;
}
Tribu des machines
la source
1
@Override
public void onBackPressed() {
}

Lorsque vous créez, onBackPressed()supprimez super.onBackPressed();et cela devrait fonctionner

hyperCoder
la source
1

Mettre

finish();

immédiatement après ActivityStart pour arrêter l'activité, empêchant tout moyen d'y revenir. Puis ajouter

onCreate(){
    getActionBar().setDisplayHomeAsUpEnabled(false);
    ...
}

à l'activité que vous commencez.

Brandon Dyer
la source