Como evitar voltar à atividade anterior?

210

Quando o botão VOLTAR é pressionado no telefone, desejo impedir que uma atividade específica retorne à anterior.

Especificamente, tenho telas de login e inscrição, ambas iniciam uma nova atividade chamada HomeScreenquando ocorre um login / inscrição bem-sucedida. Depois que o HomeScreen for iniciado, desejo impedir que os usuários possam retornar às telas de login ou inscrição pressionando a tecla VOLTAR.

Tentei usar Intent.FLAG_ACTIVITY_NO_HISTORY, mas como o aplicativo tem integração com o Facebook, quando o 'Login with Facebook' é usado, o Facebook deve retornar à tela de login inicial, portanto, devo manter um histórico dessas atividades.

Pensei em substituir o comportamento do botão VOLTAR HomeScreenpara finalizar diretamente um aplicativo quando o botão é pressionado e usei

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

mas isso também não funciona.

ecem
fonte
1
Só para esclarecer, você está tentando capturar comportamentos de volta para todos, exceto o facebook?
havexz
2
De certa forma, sim, mas na verdade o que eu quero é depois que um login bem-sucedido ocorrer e a tela inicial for aberta, o usuário não poderá voltar à tela de login pressionando o botão VOLTAR. Assim como o Twitter ou o Foursquare, por exemplo, uma vez que efetuamos login nesses aplicativos, não vemos a página de logon até terminarmos o logon (mesmo se pressionarmos VOLTAR após o login).
ecem

Respostas:

345

Minha sugestão seria concluir a atividade que você não deseja que os usuários voltem. Por exemplo, em sua atividade de login, logo após ligar startActivity, ligue finish(). Quando os usuários pressionam o botão Voltar, eles não poderão acessar a atividade de logon porque ela foi eliminada da pilha.

codificador
fonte
2
E se eu gostaria que o encadeamento da atividade anterior permanecesse em execução?
AlleyOOP
2
Você não gostaria de seguir minha abordagem então. Chamar finish () matará a atividade. Você poderia iniciar o processo que deseja executar na atividade em que irá?
Codificador
7
Nota: se você ligar finishdurante uma transição compartilhada, poderá sofrer um sangramento com a atividade anterior. por exemplo, se você tiver HomeActivity-> IntermediateActivity-> FinalActivity, e você chamar finish()na IntermediateActivityimediatamente após o início do FinalActivityque você vai ver o HomeActivitypor um momento breve.
David Murdoch
101

A solução a seguir pode ser bastante útil no cenário usual de login / atividade principal ou na implementação de uma tela de bloqueio.

Para minimizar o aplicativo em vez de voltar à atividade anterior, você pode substituir onBackPressed()assim:

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

moveTaskToBack(boolean nonRoot)deixa sua pilha de trás como está, apenas coloca sua tarefa (todas as atividades) em segundo plano. O mesmo que se o usuário tivesse pressionado o botão Início .

Parâmetro boolean nonRoot- Se falso, isso funcionará apenas se a atividade for a raiz de uma tarefa; se for verdade, funcionará para qualquer atividade em uma tarefa.

Marcel Bro
fonte
3
Perfeito para uma tela de login, pois mantém o histórico intacto.
Hackmodford
Obrigado, tentei encontrar isso por cerca de três dias. Por causa do sinalizador android: noHistory = "true" para Activity, não funciona conforme o esperado (o sinalizador noHistory recria a atividade após a minimização) e às vezes finish () às vezes não funciona para mim, mas por que eu ainda não entendi.
Denshov
37

Não sei exatamente o que você deseja, mas parece que deve ser possível e também parece que você já está no caminho certo.

Aqui estão alguns links que podem ajudar:

Desativar botão voltar no android

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

       return;
    }

Como posso desativar 'voltar' a alguma atividade?

  AndroidManifest.xml =>
<activity android:name=".SplashActivity" android:noHistory="true"/>
paulsm4
fonte
1
Não posso usar a opção noHistory devido ao problema do Facebook que tentei explicar na minha pergunta e também em um dos comentários. Mas a coisa com o botão VOLTAR não está desativando, mas fazendo com que saia de todo o aplicativo como System.exit(0)é chamado (eu sei que não é o melhor em prática, mas eu só queria dar um exemplo).
ecem
Graças isso funcionou muito bem. A única sugestão que eu faria aqui seria, sem necessidade de retorno. Apenas remova super.onBackPressed () e deixe o método em branco. Esta coima funciona tão bem
hyperCoder
20

Existem duas soluções para o seu caso, a atividade A inicia a atividade B, mas você não deseja voltar à atividade A na atividade B.

1. Removida a atividade anterior A da pilha traseira.

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

2. Desativado, ação do botão voltar na atividade B.

Existem duas maneiras de impedir o evento voltar atrás, como abaixo,

1) Recomendar abordagem

@Override
public void onBackPressed() {
}

2) Substituir método onKeyDown

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

Espero que seja útil, mas ainda depende das suas situações.

Luna Kong
fonte
3
Não é uma má experiência do usuário desativar o onBackPressed ()?
C. Skjerdal
Depende totalmente do que você está tentando fazer, pois a funcionalidade do aplicativo precisa disso e, em seguida, vá em frente.
user3099225
É incrível como eu esqueci completamente o primeiro método usando finish(). Excessivamente desnecessário com nohistoryatributo, sinalizadores de intenção, tags de manifesto de atividade pai, etc! Bobo, obrigado pela resposta!
varun
8

Como já existem muitas ótimas soluções sugeridas, tentarei dar uma explicação mais difusa.

Como pular a volta para a atividade anterior?

Remova a atividade anterior do Backstack. Simples

Como remover a atividade anterior do Backstack?

finish()Método de chamada

O fluxo normal:

insira a descrição da imagem aqui
Todas as atividades são armazenadas em uma pilha conhecida como Backstack.
Quando você inicia uma nova atividade ( startActivity(...)), a nova atividade é empurrada para o topo da pilha e, quando você pressiona o botão Voltar, a atividade é exibida na pilha.
Um ponto importante a ser observado é que, quando o botão Voltar é pressionado, o finish();método é chamado internamente. Esse é o comportamento padrão do método onBackPressed ().

Então, se você quiser pular a Atividade B?

ie A <--- C

Basta adicionar o finish();método após o seu startActvity(...)na Atividade B

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

insira a descrição da imagem aqui

Rohit Singh
fonte
6

finish()fornece o método para fechar o aplicativo atual da atividade, não todo. E é melhor você não tentar procurar métodos para matar aplicativos. Um pequeno conselho.

Você já tentou a conjunção de Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NO_HISTORY? Lembre-se de usar esses sinalizadores na Intentatividade inicial!

cadáver
fonte
2
FLAG_ACTIVITY_NO_HISTORYimpede que o meu LoginScreen capture o retorno de chamada do Facebook quando o Login com o Facebook é usado. Como o foco sai da tela de login, ele não pode ser retomado (pois não há histórico). Mas ainda não experimentei Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS, vou verificar, obrigado!
ecem
também obrigado sobre o finish()método, eu não sabia sobre isso.
ecem 26/12/11
4

Coloque finish()logo depois

Intent i = new Intent(Summary1.this,MainActivity.class);
            startActivity(i);
finish();
Param Trivedi
fonte
1
Isso é basicamente o que a resposta aceita de quatro anos antes disse.
TylerH
3

A resposta de paulsm4 é a correta. Se onBackPressed()você voltar, desabilitará o botão Voltar. No entanto, acho que uma abordagem melhor, dado o seu caso de uso, é inverter a lógica da atividade, ou seja, tornar a atividade em casa a principal, verificar se o usuário está conectado lá ou, se não, iniciar a atividade de entrada. O motivo é que, se você substituir o botão Voltar em sua atividade principal, a maioria dos usuários ficará confusa ao pressionar novamente e seu aplicativo não fará nada.

dmon
fonte
3

Este método está funcionando bem

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
fonte
2

Basta substituir o método onKeyDown e verificar se o botão Voltar foi pressionado.

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

    return false;
}
Tribo da Máquina
fonte
1
@Override
public void onBackPressed() {
}

Quando você cria, onBackPressed()basta remover super.onBackPressed();e isso deve funcionar

hyperCoder
fonte
1

Colocar

finish();

imediatamente após o ActivityStart para interromper a atividade, impedindo qualquer maneira de voltar a ela. Então adicione

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

para a atividade que você está iniciando.

Brandon Dyer
fonte