GERİ düğmesine basıldığında setResult çalışmıyor


111

GERİ düğmesine basıldıktan sonra sonucu ayarlamaya çalışıyorum. OnDestroy'u arıyorum

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

Ama söz konusu olduğunda

onActivityResult(int requestCode, int resultCode, Intent data) 

resultCode 0 (RESULT_CANCELED) ve veriler 'boş'.

Peki GERİ butonu ile sonlandırılan aktiviteden nasıl sonuç alabilirim?

Yanıtlar:


159

onBackPressed()Yöntemi geçersiz kılmanız ve sonucu süper sınıfa çağrı yapmadan önce ayarlamanız gerekir.

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

23
Bu yaklaşımı kullanırsanız, super.onBackPressed () çağrısının yukarıda gösterildiği gibi setResult () çağrısından sonra gerçekleşmesi gerektiğini veya orijinal sorunu yeniden yaşayacağınızı unutmayın!
jengelsma

1
Buradaki en iyi cevap bu. OnPause () veya onDestroy () 'u geçersiz kılarsak, önce onBackPressed () çağrılacak ve sonucu 0 olarak ayarlayacaktır. Lütfen bunun farkında olun!
Marek

veya onCreate'te varsayılan sonucu ayarlayabilirsiniz. Bitirmeden () önceki herhangi bir yer uygundur.
Helin Wang

5
Benzer bir yaklaşım uyguladım ama yine de çalışmıyor. Örneğin, istek kodum ve çalışan niyetim var ama sonuç kodu her zaman 0'dır.
Neon Warge

68

Activitysonuç çağrılmadan önce ayarlanmalıdır finish(). Tıklamak GERİ aslında çağıran finish()sizinle ilgili şu activityaşağıdaki parçacığını kullanabilmesi,:

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

    super.finish();
}

Eğer ararsanız NavUtils.navigateUpFromSameTask();içinde onOptionsItemSelected(), finish()denir, ama yanlış alacak result code. Yani aramak zorunda finish()değil navigateUpFromSameTaskiçinde onOptionsItemSelected(). onActivityResult'da yanlış requestCode


Bu OP'ler durumunda işe yarar, ancak genel olarak değil, değil mi? Uygulama yaşam döngüsünün sonunu (onPause () ve onDestroy () aracılığıyla) tetikleyen finish () 'den daha fazla yöntem var mı? Ayrıca diğer cevaptaki yorumuma bakın.
pjv

Ve olmasa bile, bir API güncellemesinde ne zaman tanıtılacağını bilemezsiniz. OnPause () veya onDestroy () davranışının değiştiği zamanki kadar kolay değil. Bunlar, geçersiz kılmanız gereken yöntemler .
pjv

6
@pjv - demek istediğini alamadım ne finishilgisi var onPauseve onDestroy? Bunlar tamamen bunun dışında ilgili olmayan finishsonlandırma işlemini başlatır onPauseve onDestroybir parçasıdır.
JBM

20

Bazı özel ayarlamak isterseniz RESULT_CODEde onBackPresseddaha sonra olay ilk sette gerekir resultve daha sonra çağrı super.onBackPressed()ve aynı alacak RESULT_CODEarayan etkinliğin içinde onActivityResultyöntemle

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

10

Kodumu yeniden düzenledim. Başlangıçta bazı verileri hazırlanmış ve olarak ayarlamak activity resultiçinde onDestroy(bu iş yoktu). Şimdi activity, döndürülecek veriler her güncellendiğinde verileri ayarlıyorum ve içinde hiçbir şey yok onDestroy.


Verilerim "Duraklat" da güncellendiğinden bu benim için çalışmıyor
Bostone

Siz aradıktan sonra etkinliğiniz yeniden oluşturulursa setResult()verileriniz kaybolur.
Jarett Millard

3

OnOptionsItemSelected öğesini şu şekilde geçersiz kılmalısınız :

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

2

OnActivityResult (int, int, Intent) belgesine bakın

Çözüm, Activity.RESULT_CENCELED değeri için resultCode'u kontrol etmektir . Eğer evet ise, o zaman ya GERİ düğmesine basıldığı ya da faaliyetin çöktüğü anlamına gelir. Umarım sizin için çalışır, benim için çalışır :).


Bu tam çözümdür .. Sonuç Kodunu Kullanmalısınız .. Kodda sizden başka hiç kimse sonucu ayarlayamaz. Yani, sonuç uygun değilse, ya geri basılması ya da Çökmesi anlamına gelir ..
John

0

onDestroyzincirde çok geç - bunun yerine geçersiz kılın onPauseve isFinishing()faaliyetinizin yaşam döngüsünün sonunda olup olmadığını kontrol edin.


1
Hayır, bu da çok geç.
alex2k8

Aslında buna bir hata diyorum: code.google.com/p/android/issues/detail?id=1671 . Karmaşık uygulamalarda bu nedenle programlayamayacağınız bazı davranışlar olduğunu düşünüyorum.
pjv

Aynı zamanda çok mantıksızdır. Öyle ki, 2 yıldan fazla bir süredir aynı hatayı yapmaya devam ediyorum.
pjv

Aslında - bu daha da kötü. Ve ben kodlarken JB'de var. SetResult'u onPause'dan çağırırsam çalıştırılır, ancak nether resultCode ne de onActivityReturn yürütüldüğünde veri ayarlanır. Neden?
Bostone

İşte bu yüzden: "Bu yöntemin (onPause) uygulamaları çok hızlı olmalıdır, çünkü bu yöntem geri dönene kadar bir sonraki etkinlik devam ettirilmeyecektir
Bostone

0

OnBackPressed'i geçersiz kılmayı deneyin (android düzey 5'ten itibaren) veya onKeyDown () öğesini geçersiz kılın ve KeyEvent.BUTTON_BACK'i yakalayın (bkz. Android Etkinlik Sonuçları ) Bu benim için hile yapıyor.


0

İlk aktiviteye döndüğünüzde, bir aktivitenin onPause'da çalıştırılan herhangi bir mantığa güvenmeyin. Dokümanlara göre:

Bu yöntemin (onPause) uygulamaları çok hızlı olmalıdır çünkü bu yöntem geri dönene kadar bir sonraki etkinlik devam ettirilmeyecektir.

Ayrıntılar için http://goo.gl/8S2Y adresine bakın.

En güvenli yol, her sonuç değiştirme işlemi tamamlandıktan sonra sonucu belirlemektir (cevabınızda belirttiğiniz gibi)


0

cevabı yapıştırmam diğer insanlara yardımcı olabilir: android: launcheMode ile bir set başlatıldığında: launchMode = "singleTask" sonucu da alamıyorum, doküman şöyle diyor:

     /* <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.
 */

ve:

     /* <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. 
 */
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.