Sostituisci il pulsante Indietro per agire come il pulsante Home


253

Premendo il pulsante Indietro, vorrei che la mia applicazione passasse allo stato di arresto, anziché a quello distrutto.

Nei documenti Android afferma:

... non tutte le attività hanno il comportamento di essere distrutte quando si preme BACK. Quando l'utente inizia a riprodurre musica nell'applicazione Musica e quindi preme INDIETRO, l'applicazione ignora il normale comportamento all'indietro, impedendo che l'attività del giocatore venga distrutta e continua a riprodurre musica, anche se la sua attività non è più visibile

Come posso replicare questa funzionalità nella mia applicazione?

Penso che ci debbano essere tre possibilità ...

  1. Cattura il pulsante Indietro premi (come sotto) e poi chiama qualunque metodo (i) il pulsante Home chiama.

    @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. Cattura il pulsante Indietro, quindi falsa la pressione di un pulsante Home.

  3. Cattura il pulsante Indietro, quindi avvia un'attività della schermata principale, ponendo efficacemente l'attività della mia applicazione nello stato di arresto.

Modifica: conosco i servizi e ne sto usando uno nell'applicazione a cui questo problema è correlato. Questa domanda riguarda in particolare il passaggio dell'attività allo stato di arresto anziché allo stato distrutto quando si preme il pulsante Indietro.


Risposte:


338

Il più delle volte è necessario creare un servizio per eseguire qualcosa in background e il tuo visibile lo Activitycontrolla semplicemente Service. (Sono sicuro che il lettore musicale funziona allo stesso modo, quindi l'esempio nei documenti sembra un po 'fuorviante.) In tal caso, la tua Activitylattina finishcome al solito e Servicecontinuerà a funzionare.

Un approccio più semplice è quello di catturare la Backpressione del pulsante e chiamare moveTaskToBack (true) come segue:

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

Penso che l'opzione preferita dovrebbe essere che un'attività si concluda normalmente e sia in grado di ricrearsi, ad esempio leggendo lo stato corrente da un servizio, se necessario. Ma moveTaskToBackpuò essere usato come una rapida alternativa in alcune occasioni.

NOTA : come sottolineato da Dave di seguito, Android 2.0 ha introdotto un nuovo onBackPressedmetodo e questi consigli su come gestire il pulsante Indietro.


1
moveTaskToBack () sembra funzionare come desiderato. Quali potrebbero essere gli svantaggi dell'utilizzo di questo metodo? Ci sono casi in cui questo potrebbe non funzionare come previsto?
bdls,

1
Dopo aver letto il suo documento più attentamente, in realtà penso che dovrebbe funzionare bene. (Inizialmente pensavo che si applicasse all'attività, ma in realtà dice il "compito che contiene questa attività".) Ma dovresti testarlo da solo, ovviamente. :)
Mirko N.

Grazie Mirko, il metodo sembra funzionare bene. Potrebbe essere bello se dai maggiore risalto alla tua modifica in fondo alla tua risposta per coloro che guardano a questa domanda in seguito - dato che era quello che stavo cercando!
bdls

4
Si prega di leggere android-developers.blogspot.com/2009/12/… per il modo consigliato di gestire il tasto Indietro.
hackbod

1
@bdls in teoria la tua attività in background potrebbe essere uccisa dal sistema se esaurisce le risorse, quindi per sicurezza dovrebbe essere in grado di ricrearsi comunque. Ho dato un'occhiata al codice sorgente per l'app Android Music e non ho visto alcuna gestione speciale dei pulsanti Indietro.
Mirko N.

46

Usa il seguente codice:

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

23

Se vuoi catturare il pulsante Indietro dai un'occhiata a questo post sul Blog degli sviluppatori Android . Copre il modo più semplice per farlo in Android 2.0 e il modo migliore per farlo per un'applicazione che funziona su 1.xe 2.0.

Tuttavia, se l'attività viene interrotta, potrebbe essere comunque interrotta a seconda della disponibilità di memoria sul dispositivo. Se si desidera eseguire un processo senza UI, è necessario creare un Service. La documentazione dice quanto segue sui Servizi:

Un servizio non ha un'interfaccia utente visiva, ma viene eseguito in background per un periodo di tempo indefinito. Ad esempio, un servizio potrebbe riprodurre musica di sottofondo mentre l'utente si occupa di altre questioni, oppure potrebbe recuperare dati sulla rete o calcolare qualcosa e fornire il risultato alle attività che ne hanno bisogno.

Questi sembrano appropriati per le tue esigenze.



14

se aiuta qualcun altro, ho avuto un'attività con 2 layout che ho attivato e disattivato per la visibilità, cercando di emulare una sorta di struttura page1> page2. se fossero a pagina 2 e premessero il pulsante Indietro, volevo che tornassero a pagina 1, se avessero premuto il pulsante Indietro a pagina 1, dovrebbe comunque funzionare normalmente. È piuttosto semplice ma funziona

@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
    }

}

spero che aiuti qualcuno, evviva


10

Esempio di lavoro ..

Assicurati di non chiamare 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);
}

In questo modo il tuo pulsante Indietro si comporta come il pulsante Home. Non termina la tua attività ma la porta in secondo piano

Secondo modo è quello di chiamare moveTaskToBack(true);in onBackPressede assicurarsi di rimuoveresuper.onBackPressed


0

Ancora meglio, che ne dici di OnPause () :

Chiamato come parte del ciclo di vita dell'attività quando un'attività sta andando in background, ma non è (ancora) stata uccisa. La controparte di onResume ().

Quando l'attività B viene avviata di fronte all'attività A, questo callback verrà invocato su A. B non verrà creato fino a quando il ritorno di A onPause () non ritorna, quindi assicurati di enter code herenon fare nulla di lungo qui.

Questo callback viene utilizzato principalmente per salvare qualsiasi stato persistente che l'attività sta modificando e per assicurarsi che nulla vada perso se non ci sono risorse sufficienti per avviare la nuova attività senza prima uccidere questa.

Questo è anche un buon posto per fare cose come fermare le animazioni e altre cose che consumano una notevole quantità di CPU per rendere il passaggio all'attività successiva il più velocemente possibile o per chiudere risorse che sono di accesso esclusivo come la videocamera.


0

Sostituisci onBackPressed () dopo Android 2.0. Ad esempio

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

0

Ho provato tutte le soluzioni di cui sopra, ma nessuna di queste ha funzionato per me. Il seguente codice mi ha aiutato, quando ho cercato di tornare a MainActivity in un modo che viene chiamato onCreate:

Intent.FLAG_ACTIVITY_CLEAR_TOP è la chiave.

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

-1

Ho usato @Mirko N. Answerer utilizzando il nuovo 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);
    }

}

Quindi imposta i dati della tua attività

 searchEditView.setViews(cancelBtn, titleRelativeLayout);

Grazie.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.