Android - Cara Mengganti tombol "Kembali" sehingga tidak Selesai () Aktivitas saya?


199

Saat ini saya memiliki Kegiatan yang ketika ditampilkan Pemberitahuan juga akan ditampilkan di bilah Pemberitahuan.

Ini agar ketika Pengguna menekan beranda dan Kegiatan didorong ke latar belakang, mereka dapat kembali ke Aktivitas melalui Pemberitahuan.

Masalah muncul ketika Pengguna menekan tombol kembali, Aktivitas saya dihancurkan tetapi Pemberitahuan tetap karena saya ingin pengguna dapat menekan kembali tetapi masih bisa sampai ke Aktivitas melalui Pemberitahuan. Tetapi ketika seorang USER mencoba ini, saya mendapatkan Null Pointers sebagai upaya untuk memulai aktivitas baru daripada mengembalikan yang lama.

Jadi pada dasarnya saya ingin tombol Kembali untuk bertindak sama persis seperti tombol Home dan di sini adalah bagaimana saya telah mencoba sejauh ini:


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

Namun kode di atas tampaknya masih memungkinkan Kegiatan saya dihancurkan, Bagaimana saya bisa menghentikan Aktivitas saya dari dihancurkan ketika tombol kembali ditekan?




Juga saya pikir Anda harus mengubah kode Anda ke `if (Integer.parseInt (android.os.Build.VERSION.SDK)> 5 , the <` harus menjadi >.
SudoPlz

1
Bahkan jika Anda menyelesaikan ini, Anda masih harus menangani kemungkinan sistem membunuh aplikasi Anda, kan? Maksud saya, kasus nol masih memungkinkan? Atau jika sistem membunuh aplikasi Anda karena alasan apa pun, apakah itu juga akan menghapus pemberitahuan Anda? Saya pikir ini pasti masalah, karena tujuan pemberitahuan ada meskipun aplikasi tidak.
ToolmakerSteve

Jawaban:


276

Hapus pendengar kunci Anda atau kembali trueketika Anda punya KEY_BACK.

Anda hanya perlu yang berikut ini untuk menangkap tombol kembali (Pastikan untuk tidak memanggil super masuk onBackPressed()).

Juga, jika Anda berencana untuk menjalankan layanan di latar belakang, pastikan untuk melihat startForeground()dan pastikan untuk memiliki pemberitahuan yang sedang berlangsung atau Android akan mematikan layanan Anda jika perlu mengosongkan memori.

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

70

Lebih mudah untuk mengimplementasikannya hanya dengan satu baris kode:

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

Ini harus menjadi jawaban yang diterima. Ini tidak persis apa yang ditanyakan pertanyaan dan menggunakan fungsionalitas built-in bersih.
Shadoninja

Terima kasih :) bisakah Anda menguraikan konsep di baliknya?
Farrukh Faizy

1
Anda cukup mengesampingkan acara onBackPressed (), membuatnya memindahkan aktivitas ke belakang.
Squirrelkiller

1
Solusi ini tidak akan mengembalikan aktivitas saat Anda meluncurkan kembali aplikasi dari layar beranda (jika ada aktivitas lain di tumpukan tugas).
IgorGanapolsky

12

Saya pikir apa yang Anda inginkan bukan untuk menimpa tombol kembali (yang sepertinya bukan ide yang bagus - Android OS mendefinisikan perilaku itu, mengapa mengubahnya?), Tetapi menggunakan Activity Lifecycle dan bertahan pengaturan / data Anda di acara onSaveInstanceState (Bundle) .

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

Kemudian Anda menggunakan onCreate (Bundle) untuk mendapatkan semuanya dari bundel yang ada dan buat kembali kondisi Anda.

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

Pertimbangkan kode psuedo di atas untuk mengarahkan Anda ke arah yang benar. Membaca tentang Siklus Hidup Aktivitas akan membantu Anda menentukan cara terbaik untuk mencapai apa yang Anda cari.


Hai Kiswa, ini benar, saya tidak ingin mengubah perilaku default. Saya telah mencoba menggunakan onSavedInstanceState dan itu tidak berfungsi tetapi saya yakin saya telah melihat kesalahan saya sekarang. Terima kasih
Donal Rafferty

5
Saya telah menemukan setidaknya beberapa situasi di mana saya ingin mensimulasikan perilaku tumpukan aktivitas standar tanpa benar-benar memulai Kegiatan baru. Dalam kasus ini, saya pikir, pantas untuk mengesampingkan perilaku onBackPressed () default. Secara umum, saya setuju: hindari mengungguli.
Matt Briançon

4
Saya setuju dengan @Matt. Saat ini saya sedang mengerjakan game lintas platform yang menggunakan NDK. Karena itu, paling mudah jika semuanya adalah satu kegiatan. Karena itu, perilaku default tombol kembali adalah untuk melarikan diri dari aplikasi, yang tidak seperti yang diharapkan sebagian besar pengguna. Jadi saya harus menimpa behavour default untuk membuat aktivitas berperilaku berbeda, seolah-olah pengguna benar-benar pergi ke aktivitas yang berbeda, dan hanya keluar dari aplikasi dalam situasi tertentu.
Leif Andersen

1
Bukankah onSaveInstanceState dan menyimpan data pertanyaan yang sama sekali berbeda?
Ted

@ Ted -jika Anda mengatakan bahwa selain untuk onSaveInstanceState, juga perlu ada kode yang tetap menggunakan data aplikasi non-UI, maka saya setuju. Segera setelah Anda melepaskan latar depan, aplikasi Anda bisa terbunuh tanpa peringatan lebih lanjut. Harus selalu menyimpan apa pun yang penting. Di sisi lain, saya pikir metode siklus hidup aplikasi akan dipanggil terlepas dari teknik apa yang Anda gunakan untuk menyembunyikan aplikasi tetapi tetap menggunakannya, jadi tidak perlu menambahkan logika simpan hanya untuk kasus ini. Aplikasi Anda membutuhkan kode itu di semua tempat yang tepat, terlepas dari mana.
ToolmakerSteve

11

lakukan saja ini ..

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

mengomentari //super.onBackPressed (); akan melakukan trik


1
Pengamatan yang bermanfaat, tetapi tidakkah ini menyebabkan tombol kembali tidak melakukan apa-apa, seolah-olah rusak? Itu bukan hal yang baik untuk dilakukan - membingungkan dan menjengkelkan bagi pengguna. IMHO harus menambahkan logika dari jawaban lain, untuk bertindak seperti tombol Beranda, seperti yang diminta dalam pertanyaan. Jawaban yang diterima menyebutkan bahwa mereka sengaja tidak memanggil metode super.
ToolmakerSteve

Ya, Anda benar sekali. Itu hanya akan mengesampingkan tombol kembali dan tidak akan melakukan apa pun sampai Anda memasukkan beberapa logika di sana. Mungkin kondisi untuk menekan dua kali tombol untuk menutup aplikasi atau Anda hanya ingin menonaktifkan operasi yang sedang berlangsung (dialog kemajuan) dll, tetapi sepenuhnya sesuai dengan kebutuhan.
androCoder-BD

5

Coba ini:

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

3

Kalau-kalau Anda ingin menangani perilaku tombol kembali (di bagian bawah telepon) dan tombol beranda (yang di sebelah kiri bilah tindakan), aktivitas kustom yang saya gunakan dalam proyek ini dapat membantu Anda .

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

Contoh penggunaan dalam aktivitas Anda:

public class SomeActivity extends BackActivity {

    // ....

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

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)

0

Di Kotlin:

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

Untuk informasi lebih lanjut, Anda dapat memeriksa ini .

Ada juga pertanyaan khusus tentang mengganti tombol kembali di Kotlin.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.