162

Ich habe derzeit eine Aktivität, bei der eine Benachrichtigung auch in der Benachrichtigungsleiste angezeigt wird.Android - Wie überschreiben Sie die Schaltfläche "Zurück", damit sie meine Aktivität nicht beendet()?

Dies ist der Fall, wenn der Benutzer nach Hause drückt und die Aktivität in den Hintergrund versetzt wird, können sie über die Benachrichtigung zur Aktivität zurückkehren.

Das Problem tritt auf, wenn ein Benutzer die Zurück-Taste drückt, meine Aktivität wird zerstört, aber die Benachrichtigung bleibt so, wie ich möchte, dass der Benutzer zurück drücken kann, aber dennoch über die Benachrichtigung zur Aktivität gelangen kann. Aber wenn ein USER dies versucht, bekomme ich Null Pointers, weil er versucht, eine neue Aktivität zu starten, anstatt die alte zurückzubringen.

So im Wesentlichen möchte ich die Zurück-Taste genau die gleiche wie die Home-Taste handeln und hier ist, wie ich versucht habe, so weit:


 @Override 
     public boolean onKeyDown(int keyCode, KeyEvent event) { 
      if (Integer.parseInt(android.os.Build.VERSION.SDK) < 5 
        && keyCode == KeyEvent.KEYCODE_BACK 
        && event.getRepeatCount() == 0) { 
       Log.d("CDA", "onKeyDown Called"); 
       onBackPressed(); 
      } 

      return super.onKeyDown(keyCode, event); 
     } 

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

      return; 
     } 

jedoch der obige Code scheint immer noch zu erlaube, dass meine Aktivität zerstört wird, Wie kann ich verhindern, dass meine Aktivität zerstört wird, wenn die Zurück-Taste gedrückt wird?

+0

Es gibt eine ähnliche Frage: http://stackoverflow.com/questions/2459848/android-prompt-user-to-save-changes- when-back-button-is-pressed – aleung

+1

Ähnliche Antwort .. http://stackoverflow.com/questions/5914040/onbackpressed-to-hide-not-destroy-activity/23759328#23759328 – Nepster

+0

Auch ich denke, Sie müssen Ihre ändern Code zu 'if (Integer.parseInt (android.os.Build.VERSION.SDK)> 5 ', sollte' <'ein'> 'werden. – SudoPlz

Antwort

229

Entfernen Sie Ihren Haupthörer oder geben Sie true zurück, wenn Sie KEY_BACK haben.

Sie benötigen nur die folgenden, um die Zurück-Taste zu fangen (Stellen Sie sicher, nicht Super in onBackPressed() zu rufen).

Wenn Sie einen Dienst im Hintergrund ausführen möchten, stellen Sie sicher, dass Sie sich startForeground() ansehen und sicherstellen, dass eine fortlaufende Benachrichtigung vorliegt. Andernfalls wird Android Ihren Dienst beenden, wenn er Arbeitsspeicher freigeben muss.

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (Integer.parseInt(android.os.Build.VERSION.SDK) > 5 
      && keyCode == KeyEvent.KEYCODE_BACK 
      && event.getRepeatCount() == 0) { 
     Log.d("CDA", "onKeyDown Called"); 
     onBackPressed(); 
     return true; 
    } 
    return super.onKeyDown(keyCode, event); 
} 


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

Ich denke, was Sie wollen, ist nicht die Schaltfläche zurück zu überschreiben (das scheint nur nicht eine gute Idee - Android OS definiert dieses Verhalten, warum ändern Sie es?), Aber die Activity Lifecycle verwenden und Ihre Einstellungen beibehalten/Daten im onSaveInstanceState(Bundle) Ereignis.

@Override 
onSaveInstanceState(Bundle frozenState) { 
    frozenState.putSerializable("object_key", 
     someSerializableClassYouWantToPersist); 
    // etc. until you have everything important stored in the bundle 
} 

Dann nutzen Sie onCreate(Bundle) alles aus, dass Bündel beharrte zu erhalten und Ihren Zustand wiederherzustellen.

@Override 
onCreate(Bundle savedInstanceState) { 
    if(savedInstanceState!=null){ //It could be null if starting the app. 
     mCustomObject = savedInstanceState.getSerializable("object_key"); 
    } 
    // etc. until you have reloaded everything you stored 
} 

Betrachten Sie den obigen Pseudo-Code, um Sie in die richtige Richtung zu weisen. Lesen Sie weiter auf der Activity Lifecycle sollte Ihnen helfen, den besten Weg zu finden, was Sie suchen.

+0

Hallo Kiswa, das ist wahr, ich möchte das Standardverhalten nicht ändern. Ich habe versucht, mit dem OnSavedInstanceState und es hat nicht funktioniert, aber ich glaube, ich habe meinen Fehler jetzt entdeckt. Danke –

+5

Ich bin mindestens auf einige Situationen gestoßen, in denen ich das Standardaktivitätsstapelverhalten simulieren wollte, ohne wirklich neue Aktivitäten zu beginnen. In diesen Fällen ist es angebracht, das Standardverhalten onBackPressed() zu überschreiben. Im Allgemeinen stimme ich jedoch zu: Vermeiden Sie das Überschreiben. –

+4

Ich stimme @Matt zu. Ich arbeite gerade an einem Cross-Plattform-Spiel, das den NDK verwendet. Daher ist es am einfachsten, wenn alles eine einzige Aktivität ist. Aus diesem Grund besteht das Standardverhalten der Zurück-Schaltfläche darin, die Anwendung zu verlassen, was die meisten Benutzer nicht erwarten. Also musste ich das Standardverhalten überschreiben, damit sich die Aktivität anders verhält, als wenn der Benutzer tatsächlich zu einer anderen Aktivität gegangen wäre und die App nur unter bestimmten Umständen verlassen würde. –

46

Es war einfacher, es mit einer Zeile Code nur zu implementieren:

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

Dies sollte die akzeptierte Antwort sein. Dies tut genau das, was die Frage stellt, und verwendet saubere eingebaute Funktionalität. – Shadoninja

+0

Danke :) können Sie das Konzept dahinter ausarbeiten? –

+0

Sie überschreiben einfach das onBackPressed() -Ereignis, wodurch die Aktivität in den Hintergrund verschoben wird. – Squirrelkiller

8

einfach das tun ..

@Override 
public void onBackPressed() { 
    //super.onBackPressed(); 
} 

die // Super Kommentierung aus.onBackPressed(); Der Trick

+1

Eine nützliche Beobachtung, aber wird dies nicht dazu führen, dass der Zurück-Knopf gar nichts tut, als wäre er kaputt? Das ist keine gute Sache - verwirrend und nervig für die Nutzer. IMHO muss Logik aus einer anderen Antwort hinzufügen, um wie die Schaltfläche "Home" zu fungieren, wie es in Frage gestellt wurde. Die akzeptierte Antwort * erwähnt *, dass sie absichtlich keine Supermethode genannt haben. – ToolmakerSteve

+0

Ja, Sie haben absolut Recht. Es wird nur die Zurück-Schaltfläche überschreiben und wird nichts tun, bis Sie etwas Logik dort setzen. Kann eine Bedingung für das Doppelte sein, drücke die Taste, um die Anwendung zu schließen, oder du möchtest nur eine laufende Operation (Fortschrittsdialog) usw. abschalten, aber es ist vollständig bis zur Anforderung. –

1

Try this tun:

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

Das ist so lustig. –

0

Für den Fall, Sie wollen das Verhalten der Zurück-Taste zu handhaben (am unteren Rand des Telefons) und die Home-Taste (die links von die Aktionsleiste), kann diese benutzerdefinierte Aktivität, die ich in meinem Projekt verwende, Ihnen helfen.

import android.os.Bundle; 
import android.support.v7.app.ActionBar; 
import android.support.v7.app.AppCompatActivity; 
import android.view.MenuItem; 

/** 
* Activity where the home action bar button behaves like back by default 
*/ 
public class BackActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setupHomeButton(); 
    } 

    private void setupHomeButton() { 
     final ActionBar actionBar = getSupportActionBar(); 
     if (actionBar != null) { 
      actionBar.setDisplayHomeAsUpEnabled(true); 
      actionBar.setHomeButtonEnabled(true); 
     } 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case android.R.id.home: 
       onMenuHomePressed(); 
       return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    protected void onMenuHomePressed() { 
     onBackPressed(); 
    } 
} 

Beispiel für den Einsatz in Ihrer Aktivität:

public class SomeActivity extends BackActivity { 

    // .... 

    @Override 
    public void onBackPressed() 
    { 
     // Example of logic 
     if (yourConditionToOverride) { 
      // ... do your logic ... 
     } else { 
      super.onBackPressed(); 
     } 
    }  
}