setResult tidak berfungsi saat tombol BACK ditekan

111

Saya mencoba untuk setResult setelah tombol KEMBALI ditekan. Saya memanggil onDestroy

Intent data = new Intent();
setResult(RESULT_OK, data) 

Tapi kalau sudah sampai

onActivityResult(int requestCode, int resultCode, Intent data) 

resultCode adalah 0 (RESULT_CANCELED) dan data adalah 'null'.

Lantas, bagaimana cara menyampaikan hasil dari aktivitas yang diakhiri dengan tombol BACK?

alex2k8.dll
sumber

Jawaban:

159

Anda perlu mengganti onBackPressed()metode dan menyetel hasilnya sebelum panggilan ke superclass, mis

@Override
public void onBackPressed() {
    Bundle bundle = new Bundle();
    bundle.putString(FIELD_A, mA.getText().toString());
    
    Intent mIntent = new Intent();
    mIntent.putExtras(bundle);
    setResult(RESULT_OK, mIntent);
    super.onBackPressed();
}
n224576
sumber
23
Perhatikan bahwa jika Anda menggunakan pendekatan ini, pemanggilan super.onBackPressed () harus terjadi setelah panggilan ke setResult () seperti yang ditunjukkan di atas atau Anda akan mendapatkan masalah awal lagi!
jengelsma
1
Itu jawaban terbaik disini. Jika kita menimpa onPause () atau onDestroy (), onBackPressed () akan dipanggil terlebih dahulu dan akan menyetel hasilnya ke 0. Harap diperhatikan!
Marek
atau Anda dapat menyetel hasil default di onCreate. Tempat apa pun sebelum finish () baik-baik saja.
Helin Wang
5
Saya menerapkan pendekatan serupa tetapi masih tidak berhasil. Untuk contoh saya memiliki kode permintaan dan maksud bekerja tetapi resultCode selalu 0.
Neon Warge
68

Activityhasil harus diatur sebelum finish() dipanggil. Mengklik KEMBALI sebenarnya memanggil finish()Anda activity, jadi Anda dapat menggunakan cuplikan berikut:

@Override
public void finish() {
    Intent data = new Intent();
    setResult(RESULT_OK, data); 

    super.finish();
}

Jika Anda menelepon NavUtils.navigateUpFromSameTask();di onOptionsItemSelected(), finish()disebut, tetapi Anda akan mendapatkan salah satu result code. Jadi Anda harus memanggil finish()tidak navigateUpFromSameTaskdi onOptionsItemSelected(). requestCode salah di onActivityResult

JBM
sumber
Ini berfungsi dalam kasus OP, tetapi tidak secara umum, bukan? Ada lebih banyak metode daripada finish () yang menyebabkan akhir siklus hidup aplikasi (melalui onPause () dan onDestroy ())? Lihat juga komentar saya di jawaban yang lain.
pjv
Dan bahkan jika tidak ada, Anda tidak akan mengetahuinya kapan itu akan diperkenalkan dalam pembaruan API. Tidak semudah yang Anda lakukan ketika perilaku onPause () atau onDestroy () berubah. Itu adalah metode yang seharusnya Anda timpa.
pjv
6
@pjv - Saya tidak mengerti maksud Anda, apa finishhubungannya dengan onPausedan onDestroy? Mereka yang benar-benar tidak berhubungan kecuali untuk yang finishmemulai proses terminasi yang onPausedan onDestroymerupakan bagian dari.
JBM
20

Jika Anda ingin mengatur beberapa kebiasaan RESULT_CODEdi onBackPressedacara maka Anda perlu untuk set pertama resultdan kemudian memanggil super.onBackPressed()dan Anda akan menerima sama RESULT_CODEdalam kegiatan pemanggil onActivityResultmetode

    @Override
    public void onBackPressed()
    {
         setResult(SOME_INTEGER);
         super.onBackPressed();
    }
Khurram Shehzad
sumber
10

Saya memperbarui kode saya. Awalnya saya menyiapkan beberapa data dan mengaturnya sebagai activity resultdi onDestroy(ini tidak bekerja). Sekarang saya mengatur activitydata setiap kali data yang akan dikembalikan diperbarui, dan tidak ada apa-apa onDestroy.

alex2k8.dll
sumber
Ini tidak berfungsi untuk saya karena data saya diperbarui di "onPause"
Bostone
Jika aktivitas Anda dibuat ulang setelah Anda menelepon setResult(), data Anda akan hilang.
Jarett Millard
3

Anda harus mengganti onOptionsItemSelected seperti ini:

@Override
public boolean onOptionsItemSelected(final MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home:
        final Intent mIntent = new Intent();
        mIntent.putExtra("param", "value");
        setResult(RESULT_OK, mIntent);
        finish();
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}
mdolanci.dll
sumber
2

Lihat dokumen onActivityResult (int, int, Intent)

Solusinya adalah memeriksa resultCode untuk nilai Activity.RESULT_CENCELED . Jika ya, berarti KEMBALI ditekan atau aktivitas macet. Semoga berhasil untuk kalian, berhasil untuk saya :).

Ankur
sumber
Ini adalah solusi yang tepat .. Anda harus Kode Hasil .. Tidak ada yang dapat mengatur hasil selain Anda dalam kode. Jadi, jika hasilnya tidak OK berarti kembali menekan Atau Hancur ..
John
0

onDestroysudah terlambat dalam rantai - alih-alih ganti onPausedan periksa isFinishing()untuk memeriksa apakah aktivitas Anda berada di akhir siklus hidupnya.

Roman Nurik
sumber
1
Tidak, ini juga sudah terlambat.
alex2k8
Sebenarnya saya menyebutnya bug: code.google.com/p/android/issues/detail?id=1671 . Dalam aplikasi yang kompleks, saya pikir karena ini hanya ada beberapa perilaku yang tidak dapat Anda program.
pjv
Ini juga sangat berlawanan dengan intuisi. Begitu banyak sehingga saya terus membuat kesalahan yang sama, selama 2 tahun sekarang.
pjv
Sebenarnya - ini bahkan lebih buruk. Dan itu ada di JB saat saya sedang coding. Jika saya memanggil setResult dari onPause, itu dijalankan tetapi resultCode atau data selanjutnya tidak disetel ketika onActivityReturn dijalankan. Mengapa?
Bostone
Dan itulah mengapa: "Penerapan metode ini (onPause) harus sangat cepat karena aktivitas berikutnya tidak akan dilanjutkan hingga metode ini kembali" goo.gl/8S2Y
Bostone
0

Coba ganti onBackPressed (dari android level 5 ke atas), atau timpa onKeyDown () dan tangkap KeyEvent.BUTTON_BACK (lihat Hasil Aktivitas Android ) Ini melakukan trik untuk saya.

MrJre
sumber
0

Jangan mengandalkan logika apa pun yang dijalankan di onPause salah satu aktivitas saat Anda kembali ke aktivitas awal. Menurut dokumen:

Implementasi metode ini (onPause) harus sangat cepat karena aktivitas berikutnya tidak akan dilanjutkan hingga metode ini kembali

Lihat http://goo.gl/8S2Y untuk detailnya.

Cara teraman adalah mengatur hasil setelah setiap operasi pengubahan hasil selesai (seperti yang Anda sebutkan dalam jawaban Anda)

Bostone
sumber
0

saya tempel jawabannya mungkin akan membantu orang lain: ketika satu set launcheMode dengan android: launchMode = "singleTask" saya juga tidak bisa mendapatkan hasilnya, dokumen mengatakan:

     /* <p>Note that this method should only be used with Intent protocols
 * that are defined to return a result.  In other protocols (such as
 * {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may
 * not get the result when you expect.  For example, if the activity you
 * are launching uses the singleTask launch mode, it will not run in your
 * task and thus you will immediately receive a cancel result.
 */

dan:

     /* <p>As a special case, if you call startActivityForResult() with a requestCode 
 * >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your
 * activity, then your window will not be displayed until a result is 
 * returned back from the started activity.  This is to avoid visible 
 * flickering when redirecting to another activity. 
 */
banxi1988
sumber