2010-04-20 16 views
90

Sto tentando di impostareRisultato dopo aver premuto il pulsante BACK. Chiamo in OnDestroysetResult non funziona quando il pulsante BACK è premuto

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

Ma quando si tratta di

onActivityResult(int requestCode, int resultCode, Intent data) 

il resultCode è 0 (RESULT_CANCELED) e dati sono 'null'.

Quindi, come posso passare il risultato dell'attività interrotta dal pulsante BACK?

risposta

9

Ho rifattorizzato il mio codice. Inizialmente ho preparato alcuni dati e l'ho impostato come activity result in onDestroy (questo non ha funzionato). Ora ho impostato i dati activity ogni volta che i dati da restituire sono aggiornati e non contengono nulla in onDestroy.

+0

Questo non funziona per me dato che i miei dati sono aggiornamento in "onPause" – Bostone

+0

Se la tua attività viene ricreata dopo aver chiamato 'setResult()', i tuoi dati andranno persi. –

0

onDestroy è troppo tardi nella catena — invece ignorare e controllare isFinishing() per controllare se la vostra attività è alla fine del suo ciclo di vita.

+1

No, è troppo tardi. – alex2k8

+1

Oh, whoops .. :) –

+0

In realtà lo chiamo un bug: http://code.google.com/p/android/issues/detail?id=1671. In applicazioni complesse penso che a causa di questo ci sia solo un comportamento che non puoi programmare. – pjv

56

Activity il risultato deve essere impostato prima delfinish() viene chiamato. Facendo clic su Indietro chiama in realtà finish() sul activity, in modo da poter utilizzare il seguente frammento:

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

    super.finish(); 
} 

Se si chiama NavUtils.navigateUpFromSameTask(); in onOptionsItemSelected(), finish() si chiama, ma si otterrà il torto result code. Quindi devi chiamare finish() non navigateUpFromSameTask in onOptionsItemSelected(). wrong requestCode in onActivityResult

+0

Questo funziona nel caso degli OP, ma non in generale, giusto? Esistono più metodi di finish() che inducono la fine del ciclo di vita dell'app (tramite onPause() e onDestroy())? Vedi anche il mio commento all'altra risposta. – pjv

+0

E anche se non ce ne fossero, non lo sapresti quando verrà introdotto in un aggiornamento API. Non con la stessa facilità con cui si modificano i comportamenti di onPause() o onDestroy(). Questi sono i metodi che * dovresti * scavalcare. – pjv

+5

@pjv - Non capisco il tuo punto, cosa 'finish' ha a che fare con' onPause' e ​​'onDestroy'? Quelli sono totalmente non correlati eccetto che il 'finish' inizia il processo di terminazione a cui fanno parte' onPause' e ​​'onDestroy'. – JBM

3

consultare onActivityResult(int, int, Intent) doc

soluzione è di controllare il resultCode per valore Activity.RESULT_CENCELED. Se sì, significa che è stato premuto BACK o l'attività si è interrotta. Spero che funzioni per voi ragazzi, lavora per me :).

+0

Questa è la soluzione esatta .. Devi codice risultato .. Nessuno può impostare il risultato diverso da te nel codice. Quindi, se il risultato non è OK significa che viene premuto Indietro o 01. Crollato. – John

0

Prova sovrascrivendo onBackPressed (da Android livello 5 in su), o ignorare onKeyDown() e prendere KeyEvent.BUTTON_BACK (vedi Android Activity Results) Questo fa il trucco per me.

128

È necessario overide il metodo onBackPressed() e impostare il risultato prima della chiamata a superclasse, cioè

@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

Nota che se si utilizza questo approccio, il richiamo di super.onBackPressed() deve avvenire dopo la chiamata a setResult() come mostrato sopra o si avrà l'originale problema tutto da capo! – jengelsma

+1

Questa è la migliore risposta qui. Se sostituiamo onPause() o onDestroy(), onBackPressed() verrà chiamato per primo e imposterà il risultato su 0. Si prega di essere consapevoli di ciò! – Marek

+0

oppure è possibile impostare il risultato predefinito su onCreate. Qualsiasi posto prima della fine() va bene. –

0

non si basano su alcuna logica eseguita in onPause di un'attività quando si torna a quella iniziale uno. Secondo la documentazione:

Le implementazioni di questo metodo (onPause) deve essere molto veloce perché la prossima attività non riprenderà fino a quando questo metodo restituisce

Vedi http://goo.gl/8S2Y per i dettagli.

Il modo più sicuro è quello di impostare risultato dopo ogni operazione risultato alterazione è completo (come si parla nella sua risposta)

2

Si dovrebbe ignorare onOptionsItemSelected come questo:

@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

incollo la risposta potrebbe essere utile ad altre persone: quando un insieme launcheMode con android: launchMode = "singleTask" non riesco a ottenere il risultato, il documento dice:

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

e:

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

Se si desidera impostare un po 'personalizzato RESULT_CODE in onBackPressed evento, allora è necessario impostare prima il result e quindi chiamare il super.onBackPressed() e riceverai la stessa RESULT_CODE in di l'attività chiamante onActivityResult metodo

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