Funkcja setResult nie działa po naciśnięciu przycisku BACK


90

Próbuję ustawićRozmiar po naciśnięciu przycisku BACK. Zadzwonię w onDestroy

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

Ale jeśli chodzi o

onActivityResult(int requestCode, int resultCode, Intent data) 

ResultCode wynosi 0 (RESULT_CANCELED) oraz dane jest 'zerowy'.

Jak mogę przekazać wynik z działania zakończonego przyciskiem POWRÓT?

9

I refactored my code. Początkowo przygotowałem dane i ustawiłem je jako activity result w onDestroy (to nie zadziałało). Teraz ustawiam activity danych za każdym razem, gdy dane do zwrócenia są aktualizowane i nie mają nic w onDestroy.

  0

To nie działa dla mnie, ponieważ moje dane są update w "onPause" 22 lip. 122012-07-22 17:49:53

  0

Jeśli twoja aktywność zostanie odtworzona po wywołaniu 'setResult()', twoje dane zostaną utracone. 12 maj. 162016-05-12 13:40:41


0

onDestroy jest zbyt późno w łańcuchu — zamiast zastąpić i sprawdzić isFinishing() aby sprawdzić, czy działalność jest na końcu cyklu ich życia.

+1

Nie, to też jest za późno. 22 kwi. 102010-04-22 03:01:15

+1

Och, whoops .. :) 22 kwi. 102010-04-22 04:39:11

  0

Właściwie nazywam to błędem: http://code.google.com/p/android/issues/detail?id=1671. W złożonych aplikacjach myślę, że z tego powodu jest tylko pewne zachowanie, którego nie można zaprogramować. 16 mar. 112011-03-16 22:21:54

  0

Jest to również bardzo sprzeczne z intuicją. Tak bardzo, że popełniam ten sam błąd przez ponad 2 lata. 16 mar. 112011-03-16 22:28:31

  0

W rzeczywistości - jest jeszcze gorzej. I istnieje w JB, kiedy koduję. Jeśli wywołasz setResult z opcji onPause, jest ona wykonywana, ale parametr resultCode lub data jest ustawiany, gdy wykonywany jest onActivityReturn. Czemu? 22 lip. 122012-07-22 17:49:20

  0

I dlatego: "Implementacje tej metody (onPause) muszą być bardzo szybkie, ponieważ następna czynność nie zostanie wznowiona, dopóki ta metoda nie powróci" http://goo.gl/8S2Y 22 lip. 122012-07-22 17:52:47


56

Activity wynik musi być ustawiony przedfinish() jest wywoływana. Kliknięcie BACK faktycznie nazywa finish() na swojej activity, więc można użyć następującego fragmentu:

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

    super.finish(); 
} 

Jeśli zadzwonisz NavUtils.navigateUpFromSameTask(); w onOptionsItemSelected(), finish() nazywa, ale dostaniesz złą result code. Musisz więc zadzwonić pod numer finish(), a nie navigateUpFromSameTask w onOptionsItemSelected(). wrong requestCode in onActivityResult

  0

Działa to w przypadku OP, ale ogólnie nie, prawda? Istnieje więcej metod niż finish(), które powodują koniec cyklu życia aplikacji (za pomocą onPause() i onDestroy())? Zobacz także mój komentarz w innej odpowiedzi. 16 mar. 112011-03-16 22:24:08

  0

A nawet gdyby tak nie było, nie wiedziałbyś o tym, kiedy zostanie wprowadzony w aktualizacji API. Nie tak łatwo jak wtedy, gdy zmieni się zachowanie onPause() lub onDestroy(). Są to metody, które * masz * zastąpić. 16 mar. 112011-03-16 22:31:58

+5

@pjv - Nie rozumiem, co 'finish' ma wspólnego z' onPause' i 'onDestroy'? Nie są one całkowicie powiązane, z wyjątkiem tego, że 'finish' rozpoczyna proces kończenia, którego częścią są' onPause' i 'onDestroy'. 30 sie. 112011-08-30 19:45:13


3

Patrz onActivityResult(int, int, Intent) doc

Rozwiązanie jest sprawdzenie ResultCode na wartość Activity.RESULT_CENCELED. Jeśli tak, oznacza to, że naciśnięto przycisk WSTECZ lub wystąpił błąd. Mam nadzieję, że to działa dla was, pracuje dla mnie :).

  0

To jest dokładne rozwiązanie .. Musisz Wynik kodu. Nikt nie może ustawić wyniku innego niż w kodzie. Tak więc, jeśli wynik nie jest w porządku, oznacza to, że albo jego back prasy, albo Crashhed .. 15 wrz. 152015-09-15 14:16:26


0

Spróbuj nadrzędnymi onBackPressed (od android poziom 5 w górę) lub zastąpić onKeyDown() i złapać KeyEvent.BUTTON_BACK (patrz Android Activity Results) To załatwia sprawę dla mnie.


128

Trzeba overide metodę onBackPressed() i ustawić wynik przed wywołaniem nadrzędnej, czyli

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

Należy zauważyć, że jeśli używasz tego podejścia, wywołanie super.onBackPressed() musi nastąpić po wywołaniu setResult(), jak pokazano powyżej lub będziesz miał oryginalny problem od nowa! 24 maj. 122012-05-24 18:28:43

+1

To najlepsza odpowiedź tutaj. Jeśli przesłonimy on onPause() lub onDestroy(), onBackPressed() zostanie wywołany jako pierwszy i ustawi wynik na 0. Pamiętaj, że! 05 lip. 132013-07-05 05:02:13

  0

lub możesz ustawić domyślny wynik onCreate. Każde miejsce przed metą() jest w porządku. 26 wrz. 132013-09-26 15:35:03

+4

Zaimplementowałem podobne podejście, ale nadal nie działa. Na przykład mam kod żądania i intencję działającą, ale kod resultCode ma zawsze wartość 0. 30 kwi. 152015-04-30 14:35:19


0

nie należy liczyć na jakiekolwiek logiki zawartej w OnPause jednej działalności po powrocie do początkowego jeden. Zgodnie z docs:

implementacji tej metody (OnPause) musi być bardzo szybki, ponieważ następna czynność nie zostanie wznowione, dopóki ta metoda zwraca

Zobacz http://goo.gl/8S2Y szczegóły.

Najbezpieczniejszym sposobem jest ustawiony wynik po każdej operacji wynik przerabianie jest kompletna (jak wspomina w swojej odpowiedzi)


2

powinny przesłonić onOptionsItemSelected takiego:

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

0

i wklej odpowiedź może być pomocne dla innych osób: , gdy zestaw launcheMode z Androidem: launchMode = "singleTask" również nie mogę uzyskać wyniku,

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

oraz:

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

13

Jeśli chcesz ustawić jakiś zwyczaj RESULT_CODE w onBackPressed razie to trzeba najpierw ustawić result a następnie wywołać super.onBackPressed() a otrzymasz ten sam RESULT_CODE w działalność rozmówcy onActivityResult metoda

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