Android - Wie überschreibe ich die Schaltfläche "Zurück", damit meine Aktivität nicht beendet () wird?

199

Ich habe derzeit eine Aktivität, bei der eine Benachrichtigung auch in der Benachrichtigungsleiste angezeigt wird, wenn sie angezeigt wird.

Dies ist so, dass der Benutzer, wenn er nach Hause drückt und die Aktivität in den Hintergrund gerückt wird, über die Benachrichtigung zur Aktivität zurückkehren kann.

Das Problem tritt auf, wenn ein Benutzer die Zurück-Taste drückt, meine Aktivität zerstört wird, die Benachrichtigung jedoch so bleibt, 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 BENUTZER dies versucht, erhalte ich Nullzeiger als Versuch, eine neue Aktivität zu starten, anstatt die alte zurückzubringen.

Im Wesentlichen möchte ich, dass die Schaltfläche "Zurück" genauso funktioniert wie die Schaltfläche "Startseite". So habe ich es bisher versucht:


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

Der obige Code scheint jedoch weiterhin zu ermöglichen, 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?

Donal Rafferty
quelle
Es gibt eine ähnliche Frage: stackoverflow.com/questions/2459848/…
Aleung
1
Ähnliche Antwort .. stackoverflow.com/questions/5914040/…
Zar E Ahmer
Ich denke auch, dass Sie Ihren Code in `if (Integer.parseInt (android.os.Build.VERSION.SDK)> 5 , the <` ändern müssen, um ein >.
SudoPlz
1
Selbst wenn Sie dies lösen, müssen Sie dennoch mit der Möglichkeit umgehen, dass das System Ihre App beendet, oder? Ich meine, der Nullfall ist noch möglich? Oder wenn das System Ihre App aus irgendeinem Grund beendet, wird dadurch auch Ihre Benachrichtigung entfernt? Ich denke, dies muss ein Problem sein, da der Zweck einer Benachrichtigung darin besteht, auch dann zu existieren, wenn die App dies nicht tut.
ToolmakerSteve
Überprüfen Sie hier Beispiel Anwendungscode freakyjolly.com/how-to-add-back-arrow-in-android-activity
Code Spy

Antworten:

276

Entfernen Sie Ihren Key Listener oder kehren trueSie zurück, wenn Sie haben KEY_BACK.

Sie müssen nur die im Anschluss an die Zurück - Taste zu fangen (Achten Sie darauf , nicht zu nennen Super in onBackPressed()).

Wenn Sie vorhaben, einen Dienst im Hintergrund auszuführen startForeground(), sollten Sie sich eine laufende Benachrichtigung ansehen und sicherstellen, da Android sonst Ihren Dienst beendet, wenn Speicher freigegeben werden muss.

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

Es war einfacher, es nur mit einer Codezeile zu implementieren:

@Override
public void onBackPressed() {
   moveTaskToBack(true);
}
Teo Inke
quelle
Dies sollte die akzeptierte Antwort sein. Dies macht genau das, was die Frage stellt, und verwendet saubere integrierte Funktionen.
Shadoninja
Danke :) Kannst du das Konzept dahinter ausarbeiten?
Farrukh Faizy
1
Sie überschreiben einfach das Ereignis onBackPressed (), wodurch die Aktivität nach hinten verschoben wird.
Eichhörnchenkiller
1
Diese Lösung bringt die Aktivität nicht zurück, wenn Sie die App vom Startbildschirm aus neu starten (wenn sich eine andere Aktivität auf dem Aufgabenstapel befindet).
IgorGanapolsky
12

Ich denke, Sie möchten nicht die Schaltfläche "Zurück" überschreiben (das scheint einfach keine gute Idee zu sein - Android OS definiert dieses Verhalten, warum sollte es geändert werden?), Sondern den Aktivitätslebenszyklus verwenden und Ihre Einstellungen / Daten im beibehalten Ereignis onSaveInstanceState (Bundle) .

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

Dann verwenden Sie onCreate (Bundle) , um alles aus diesem dauerhaften Bundle herauszuholen und Ihren Status neu zu erstellen.

@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 Pseudocode, um in die richtige Richtung zu weisen. Wenn Sie sich über den Aktivitätslebenszyklus informieren , können Sie den besten Weg finden, um das zu erreichen, wonach Sie suchen.

kiswa
quelle
Hallo Kiswa, das stimmt, ich möchte das Standardverhalten nicht ändern. Ich habe versucht, den onSavedInstanceState zu verwenden, und er hat nicht funktioniert, aber ich glaube, ich habe meinen Fehler jetzt entdeckt. Vielen Dank
Donal Rafferty
5
Ich bin auf mindestens einige Situationen gestoßen, in denen ich das Standardverhalten des Aktivitätsstapels simulieren wollte, ohne tatsächlich neue Aktivitäten zu starten. In diesen Fällen ist es meines Erachtens angebracht, das Standardverhalten von onBackPressed () zu überschreiben. Im Allgemeinen stimme ich jedoch zu: Vermeiden Sie das Überschreiben.
Matt Briançon
4
Ich stimme @Matt zu. Ich arbeite derzeit an einem plattformübergreifenden Spiel, das das NDK verwendet. Daher ist es am einfachsten, wenn alles eine einzelne 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. Daher musste ich das Standardverhalten überschreiben, damit sich die Aktivität anders verhält, als ob der Benutzer tatsächlich zu einer anderen Aktivität gegangen wäre, und die App nur unter bestimmten Umständen beenden.
Leif Andersen
1
Ist der onSaveInstanceState und das Speichern von Daten nicht eine ganz andere Frage?
Ted
@Ted -wenn Sie sagen, dass zusätzlich zu onSaveInstanceState auch Code vorhanden sein muss, der Nicht-UI-App-Daten enthält, stimme ich zu. Sobald Sie den Vordergrund aufgeben, kann Ihre App ohne weitere Warnung beendet werden. Muss immer alles speichern, was zählt. Andererseits denke ich, dass die App-Lebenszyklusmethoden unabhängig von der Technik aufgerufen werden, mit der Sie die App ausblenden, aber beibehalten. Daher sollte es nicht erforderlich sein, nur für diesen Fall eine Speicherlogik hinzuzufügen. Ihre App benötigt diesen Code unabhängig davon an den richtigen Stellen.
ToolmakerSteve
11

mach das einfach ..

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

//super.onBackPressed () auskommentieren; wird den Trick machen

androCoder-BD
quelle
1
Eine nützliche Beobachtung, aber führt dies nicht dazu, dass der Zurück-Knopf überhaupt nichts tut, als wäre er kaputt? Das ist keine gute Sache - verwirrend und nervig für die Benutzer. IMHO muss Logik aus einer anderen Antwort hinzufügen, um wie die Home-Taste zu handeln, wie in der Frage angefordert. In der akzeptierten Antwort wird erwähnt, dass sie absichtlich keine Supermethode aufriefen.
ToolmakerSteve
Ja, du hast absolut recht. Es wird nur die Zurück-Taste überschreiben und nichts tun, bis Sie dort eine Logik setzen. Möglicherweise müssen Sie die Taste zweimal drücken, um die Anwendung zu schließen, oder Sie möchten nur einen laufenden Vorgang (Fortschrittsdialog) usw. deaktivieren, dies entspricht jedoch vollständig den Anforderungen.
AndroCoder-BD
5

Versuche dies:

@Override
public void onBackPressed() {
    finish();
}
Thakur
quelle
3

Nur für den Fall, dass Sie das Verhalten der Zurück-Taste (unten am Telefon) und der Home-Taste (links neben der Aktionsleiste) behandeln möchten, 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();
    }
}

Anwendungsbeispiel für Ihre Aktivität:

public class SomeActivity extends BackActivity {

    // ....

    @Override
    public void onBackPressed()
    {
        // Example of logic
        if ( yourConditionToOverride ) {
            // ... do your logic ...
        } else {
            super.onBackPressed();
        }
    }    
}
Ferran Maylinch
quelle
1
@Override
public void onBackPressed() {
// Put your code here.
}

//I had to go back to the dashboard. Hence,

@Override
public void onBackPressed() {
    Intent intent = new Intent(this,Dashboard.class);
    startActivity(intent);
}
Just write this above or below the onCreate Method(within the class)
user3156040
quelle
0

In Kotlin:

val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
    // Handle the back button event
}

Für weitere Informationen können Sie überprüfen diese .

Es gibt auch spezielle Fragen zum Überschreiben der Zurück-Schaltfläche in Kotlin.

Solaza
quelle