2010-04-20 14 views
90

Estoy intentando configurarResult después de presionar el botón BACK. Me llamo en OnDestroysetResult no funciona cuando se presiona el botón ATRÁS

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

Pero cuando se trata de

onActivityResult(int requestCode, int resultCode, Intent data) 

la resultCode es 0 (RESULT_CANCELED) y estos datos son 'nulo'.

Entonces, ¿cómo puedo pasar el resultado de la actividad terminada por el botón ATRÁS?

Respuesta

9

Reformé mi código. Inicialmente preparé algunos datos y lo configuré como activity result en onDestroy (esto no funcionó). Ahora configuro activity datos cada vez que se actualizan los datos que se van a devolver, y no tengo nada en onDestroy.

+0

Esto no funciona para mí ya que mis datos son actualización en "onPause" – Bostone

+0

Si su actividad se vuelve a crear después de llamar a 'setResult()', sus datos se perderán. –

0

onDestroy es demasiado tarde en la cadena — lugar anular y comprobar isFinishing() para comprobar si su actividad se encuentra al final de su ciclo de vida.

+1

No, esto es demasiado tarde también. – alex2k8

+1

Oh, whoops ... :) –

+0

Realmente llamo a esto un error: http://code.google.com/p/android/issues/detail?id=1671. En aplicaciones complejas, creo que debido a esto, solo hay un comportamiento que no puede programar. – pjv

56

Activity resultado debe configurarse antes de llamar alfinish(). Al hacer clic en VOLVER realidad llama finish() en su activity, por lo que puede utilizar el siguiente fragmento:

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

    super.finish(); 
} 

Si llama NavUtils.navigateUpFromSameTask(); en onOptionsItemSelected(), finish() se llama, pero obtendrá el mal result code. Por lo tanto, debe llamar al finish() y no al navigateUpFromSameTask en onOptionsItemSelected(). wrong requestCode in onActivityResult

+0

Esto funciona en el caso OPs, pero no en general, ¿verdad? Hay más métodos que finish() que inducen el final del ciclo de vida de la aplicación (a través de onPause() y onDestroy())? También vea mi comentario en la otra respuesta. – pjv

+0

E incluso si no hubiera, no lo sabría cuando se introduciría en una actualización de API. No tan fácilmente como lo haría cuando cambia el comportamiento de onPause() o onDestroy(). Esos son los métodos que * supuestamente * debes anular. – pjv

+5

@pjv - No entiendo tu punto, ¿qué 'acabado' tiene que ver con' onPause' y 'onDestroy'? Esos no están totalmente relacionados, excepto por ese 'acabado 'que inicia el proceso de terminación del cual' onPause' y 'onDestroy' son parte de. – JBM

3

Consulte onActivityResult(int, int, Intent) doc

solución es comprobar la resultCode para el valor Activity.RESULT_CENCELED. Si es así, significa que se presionó BACK o la actividad se bloqueó. Espero que funcione para ustedes, funciona para mí :).

+0

Esta es la solución exacta. Tiene que Código de resultado. Nadie puede establecer el resultado que no sea usted en el código. Por lo tanto, si el resultado no es correcto significa que se presiona o se colgó. – John

0

Trate anulando onBackPressed (de 5 androide nivel hacia arriba), o anular onKeyDown() y coger KeyEvent.BUTTON_BACK (ver Android Activity Results) Esto hace el truco para mí.

128

Necesitas overide el método onBackPressed() y poner el resultado antes de la llamada a la superclase, es decir

@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

Tenga en cuenta que si usa este enfoque, la invocación a super.onBackPressed() debe ocurrir después de la llamada a setResult() como se muestra arriba o tendrá el original problema de nuevo! – jengelsma

+1

Esa es la mejor respuesta aquí. Si anulamos OnPause() o onDestroy(), se llamará primero a onBackPressed() y se establecerá el resultado en 0. ¡Tenga en cuenta eso! – Marek

+0

o puede establecer el resultado predeterminado en onCreate. Cualquier lugar antes de terminar() está bien. –

0

No confíe en cualquier lógica ejecutada en onPause de una actividad cuando regrese a la inicial uno. De acuerdo con los documentos:

Las implementaciones de este método (onPause) debe ser muy rápido porque la siguiente actividad no se reanudará hasta que este método devuelve

Ver http://goo.gl/8S2Y para más detalles.

La forma más segura es configurar resultado después de cada operación resultado alteración es completa (como se menciona en su respuesta)

2

Debe anular onOptionsItemSelected así:

@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

pego la respuesta puede ser útil para otras personas: cuando se establece un launcheMode con android: launchMode = "singleTask" tampoco puedo obtener el resultado, el 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. 
*/ 

y:

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

Si desea establecer alguna costumbre RESULT_CODE en onBackPressed caso, entonces tienes que establece por primera vez la result y luego llamar al super.onBackPressed() y recibirá el mismo RESULT_CODE en la actividad de la persona que llama onActivityResult método

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