Substituir o botão Voltar para agir como o botão Início

253

Ao pressionar o botão Voltar, gostaria que meu aplicativo fosse para o estado parado, em vez do estado destruído.

Nos documentos do Android , afirma:

... nem todas as atividades têm o comportamento de serem destruídas quando pressionar VOLTAR. Quando o usuário começa a tocar música no aplicativo Música e pressiona VOLTAR, o aplicativo substitui o comportamento normal das costas, impedindo que a atividade do player seja destruída e continua tocando, mesmo que sua atividade não seja mais visível.

Como replico essa funcionalidade no meu próprio aplicativo?

Eu acho que deve haver três possibilidades ...

  1. Capturar o botão Voltar pressione (como abaixo) e, em seguida, chame os métodos que o botão inicial chamar.

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK)) {
            Log.d(this.getClass().getName(), "back button pressed");
        }
        return super.onKeyDown(keyCode, event);
    }
  2. Capture o pressionamento do botão voltar e, em seguida, falsifique um pressionamento do botão home.

  3. Capture o botão voltar, pressione e inicie uma Atividade da tela inicial, colocando efetivamente a Atividade do meu aplicativo no estado parado.

Editar: Eu sei sobre serviços e estou usando um no aplicativo ao qual esse problema está relacionado. Esta pergunta é especificamente sobre colocar a Atividade no estado parado, e não no estado destruído ao pressionar o botão Voltar.

bdls
fonte
veja uma resposta semelhante stackoverflow.com/questions/5914040/…
Zar E Ahmer

Respostas:

338

Na maioria das vezes, você precisa criar um serviço para executar algo em segundo plano, e o seu visível Activitysimplesmente controla isso Service. (Tenho certeza de que o Music player funciona da mesma maneira, portanto, o exemplo nos documentos parece um pouco enganador.) Se for esse o caso, você Activitypoderá, finishcomo sempre, e Serviceainda estará em execução.

Uma abordagem mais simples é capturar o Backbotão pressionar e chamar moveTaskToBack (true) da seguinte maneira:

// 2.0 and above
@Override
public void onBackPressed() {
    moveTaskToBack(true);
}

// Before 2.0
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        moveTaskToBack(true);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

Eu acho que a opção preferida deve ser que uma Atividade termine normalmente e seja capaz de se recriar, por exemplo, lendo o estado atual de um Serviço, se necessário. Mas moveTaskToBackpode ser usado como uma alternativa rápida de vez em quando.

OBSERVAÇÃO : conforme apontado por Dave abaixo do Android 2.0, foi introduzido um novo onBackPressedmétodo e essas recomendações sobre como lidar com o botão Voltar.

Mirko N.
fonte
1
moveTaskToBack () parece funcionar como desejado. Quais podem ser as desvantagens de usar esse método? Existem casos em que isso pode não funcionar como esperado?
bdls
1
Depois de ler o documento com mais cuidado, acho que deve funcionar bem. (Inicialmente, pensei que se aplicava à atividade, mas na verdade diz a "tarefa que contém essa atividade".) Mas você deve testá-la por si mesma, é claro. :)
Mirko N.
Obrigado Mirko, o método parece funcionar bem. Pode ser legal se você der mais destaque à sua edição na parte inferior da sua resposta para aqueles que olharem para essa pergunta mais tarde - pois foi o que eu estava procurando!
bdls
4
Leia android-developers.blogspot.com/2009/12/… para a maneira recomendada de lidar com a tecla Voltar.
hackbod
1
@bdls, em teoria, sua atividade em segundo plano pode ser eliminada pelo sistema se houver poucos recursos; portanto, para garantir a segurança, ele poderá se recriar de qualquer maneira. Dei uma olhada no código-fonte do aplicativo Android Music e não vejo nenhum tratamento especial do botão Voltar.
Mirko N.
46

Use o seguinte código:

public void onBackPressed() {    
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_HOME);
    startActivity(intent);
}
Aniruddh Ambarkar
fonte
23

Se você quiser pegar o botão Voltar, dê uma olhada nesta postagem no Blog do desenvolvedor do Android . Ele cobre a maneira mais fácil de fazer isso no Android 2.0 e a melhor maneira de fazer isso para um aplicativo que roda em 1.xe 2.0.

No entanto, se sua atividade for interrompida, ela poderá ser interrompida, dependendo da disponibilidade de memória no dispositivo. Se você deseja que um processo seja executado sem interface do usuário, crie um Service. A documentação diz o seguinte sobre serviços:

Um serviço não possui uma interface visual do usuário, mas é executado em segundo plano por um período indeterminado. Por exemplo, um serviço pode tocar música de fundo enquanto o usuário atende a outros assuntos, ou pode buscar dados pela rede ou calcular algo e fornecer o resultado para as atividades que precisam dele.

Isso parece apropriado para suas necessidades.

Dave Webb
fonte
18

tente substituir o vazio onBackPressed()definido na classe android.app.Activity.

m-szalik
fonte
1
desde o android 2.0, essa é a coisa correta a ser substituída. developer.android.com/sdk/android-2.0.html
jay
14

se isso ajuda outra pessoa, eu tive uma atividade com dois layouts que eu alternava para visibilizar, tentando emular um tipo de estrutura página1> página2. se eles estavam na página 2 e pressionaram o botão Voltar, eu queria que eles voltassem à página 1; se eles pressionaram o botão Voltar na página 1, ainda deve funcionar normalmente. É bem básico, mas funciona

@Override
public void onBackPressed() {
// check if page 2 is open
    RelativeLayout page2layout = (RelativeLayout)findViewById(R.id.page2layout);
    if(page2layout.getVisibility() == View.VISIBLE){
        togglePageLayout(); // my method to toggle the views
        return;
    }else{
        super.onBackPressed(); // allows standard use of backbutton for page 1
    }

}

espero que ajude alguém, felicidades

craigk
fonte
10

Exemplo de trabalho ..

Certifique-se de não chamar super.onBackPressed ();

@Override
public void onBackPressed() {
   Log.d("CDA", "onBackPressed Called");
   Intent setIntent = new Intent(Intent.ACTION_MAIN);
   setIntent.addCategory(Intent.CATEGORY_HOME);
   setIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   startActivity(setIntent);
}

Dessa forma, o botão Voltar funciona como o botão Início. Não termina sua atividade, mas leva-a para segundo plano

A segunda maneira é chamar moveTaskToBack(true);em onBackPressede certifique-se de removersuper.onBackPressed

Zar E Ahmer
fonte
0

Ainda melhor, que tal OnPause () :

Chamado como parte do ciclo de vida da atividade quando uma atividade está em segundo plano, mas ainda não foi eliminada. A contraparte de onResume ().

Quando a atividade B é iniciada na frente da atividade A, esse retorno de chamada será invocado em A. B não será criado até que a onPause (A) retorne, portanto, enter code herenão faça nada longo aqui.

Esse retorno de chamada é usado principalmente para salvar qualquer estado persistente que a atividade esteja editando e garantir que nada seja perdido se não houver recursos suficientes para iniciar a nova atividade sem antes eliminar essa.

Esse também é um bom lugar para fazer coisas como interromper animações e outras coisas que consomem uma quantidade considerável de CPU para fazer a mudança para a próxima atividade o mais rápido possível ou fechar recursos que são de acesso exclusivo, como a câmera.

user1524315
fonte
0

Substitua onBackPressed () após o Android 2.0. Tal como

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

Eu tentei todas as soluções acima, mas nenhuma delas funcionou para mim. O código a seguir me ajudou, ao tentar retornar ao MainActivity de uma maneira que onCreate é chamado:

Intent.FLAG_ACTIVITY_CLEAR_TOP é a chave.

  @Override
  public void onBackPressed() {
      Intent intent = new Intent(this, MainActivity.class);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
      startActivity(intent);
  }
ubulon
fonte
-1

Eu uso o respondente @Mirko N. usando o novo Custom EditText

 public class EditViewCustom extends EditText {

    Button cancelBtn;
    RelativeLayout titleReleLayout;
    public EditViewCustom(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public EditViewCustom(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EditViewCustom(Context context) {
        super(context);
    }

    public void setViews(Button cancelBtn,RelativeLayout titleReleLayout){
        this.cancelBtn = cancelBtn;
        this.titleReleLayout = titleReleLayout;
    }

    @Override
    public boolean onKeyPreIme(int keyCode, KeyEvent event) {
        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            Log.d("KEYCODE_BACK","KEYCODE_BACK");
            cancelBtn.setVisibility(View.GONE);
            this.setFocusableInTouchMode(false);
            this.setFocusable(false);
            titleReleLayout.setVisibility(View.VISIBLE);

            return super.onKeyPreIme(keyCode, event);
          }

        return super.onKeyPreIme(keyCode, event);
    }

}

Em seguida, defina os dados da sua atividade

 searchEditView.setViews(cancelBtn, titleRelativeLayout);

Obrigado.

Sameer Z.
fonte