Enviar datos a la actividad principal en Android

295

Tengo dos actividades: actividad principal y actividad infantil.
Cuando presiono un botón en la actividad principal, se inicia la actividad secundaria.

Ahora quiero enviar algunos datos a la pantalla principal. Usé la clase Bundle, pero no funciona. Lanza algunas excepciones de tiempo de ejecución.

¿Hay alguna solución para esto?

Rajapandian
fuente
Un truco más define una ArrayList en su actividad principal y la hace estática para que pueda acceder a ella en la segunda actividad y luego agregue datos que desee enviar a la actividad principal y luego acceda a ella en la actividad principal
Abhishek Yadav
Abhishek Yadav, ¿qué pasa si su actividad principal va a destruir (devolución de llamada onDestroy ()). Creo que no es un muy buen consejo.
Leontsev Anton

Respuestas:

474

Hay un par de formas de lograr lo que desea, según las circunstancias.

El escenario más común (que es como suena el suyo) es cuando se utiliza una Actividad secundaria para obtener la entrada del usuario, como elegir un contacto de una lista o ingresar datos en un cuadro de diálogo. En este caso, debe utilizar startActivityForResultpara iniciar su actividad infantil.

Esto proporciona una canalización para enviar datos de vuelta a la Actividad principal usando setResult. El método setResult toma un valor de resultado int y un Intent que se devuelve a la Actividad de llamada.

Intent resultIntent = new Intent();
// TODO Add extras or a data URI to this intent as appropriate.
resultIntent.putExtra("some_key", "String data"); 
setResult(Activity.RESULT_OK, resultIntent);
finish();

Para acceder a los datos devueltos en la anulación de la Actividad que realiza la llamada onActivityResult. RequestCode corresponde al número entero pasado en la startActivityForResultllamada, mientras que resultCode y data Intent se devuelven de la actividad secundaria.

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  switch(requestCode) {
    case (MY_CHILD_ACTIVITY) : {
      if (resultCode == Activity.RESULT_OK) {
        // TODO Extract the data returned from the child Activity.
        String returnValue = data.getStringExtra("some_key");
      }
      break;
    } 
  }
}
Reto Meier
fuente
44
para completar, uno debe mencionar cuál es el mejor lugar para realizar la llamada para finalizar ()? Tal vez sea claro para los expertos, pero para los principiantes sería bueno saberlo sin hacer referencia a fuentes adicionales.
Califf
1
@jelmoodjasser Me tomó un tiempo darme cuenta, pero básicamente cuando comienzas la nueva actividad con Intent, necesitas usar la startActivityForResultfunción en lugar de solo startActivity. Un ejemplo podría ser startActivityForResult(myIntent, 2);donde 2 es el código de resultado, que puede ocupar el lugar MY_CHILD_ACTIVITYen la declaración de cambio anterior.
Spotlight
cuando la segunda actividad finaliza y vuelve a la primera actividad, entonces, cómo configurar requestCode en la segunda actividad antes de finalizarla ... para usarlo en onActivityResult en FirstActivity
Ahamadullah Saikat
¿Es obligatorio el intento? Si no tengo nada que devolver, ¿necesito la intención vacía de devolver?
Bagus Aji Santoso
La intención de @BagusAjiSantoso es opcional, solo es necesaria si tiene algo que devolver.
Narendra Singh
186

La Actividad 1 usa startActivityForResult :

startActivityForResult(ActivityTwo, ActivityTwoRequestCode);

La Actividad 2 se inicia y puede realizar la operación, para cerrar la Actividad haga esto:

Intent output = new Intent();
output.putExtra(ActivityOne.Number1Code, num1);
output.putExtra(ActivityOne.Number2Code, num2);
setResult(RESULT_OK, output);
finish();

Actividad 1: al regresar de la actividad anterior, se llamará aActivityResult :

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == ActivityTwoRequestCode && resultCode == RESULT_OK && data != null) {
        num1 = data.getIntExtra(Number1Code);
        num2 = data.getIntExtra(Number2Code);
    }
}

ACTUALIZACIÓN: respuesta al comentario de Seenu69, en la actividad dos,

int result = Integer.parse(EditText1.getText().toString()) 
           + Integer.parse(EditText2.getText().toString());
output.putExtra(ActivityOne.KEY_RESULT, result);

Luego, en la actividad uno,

int result = data.getExtra(KEY_RESULT);
jimmithy
fuente
Hola, te agradezco que hayas respondido mi pregunta. Este código no es suficiente para mí. Quiero que se realice la adición en la segunda actividad en sí y el resultado debe devolverse a MainActivity a través del método onActivityResult. Por ejemplo, solo hay un botón en la Actividad principal que lo lleva a la segunda actividad al hacer clic en él, allí se ingresan dos números a través del widget editText, la lógica de suma se realiza en la segunda actividad y finalmente el resultado se devuelve a MainActivity. ¿Entendido?
Seenu69
2
En ese caso, en la segunda actividad, realizaría el cálculo y almacenaría el resultado en la intención con putExtra (). He editado mi respuesta anterior
jimmithy
68

Enviar datos de vuelta

Me ayuda a ver las cosas en contexto. Aquí hay un proyecto simple y completo para enviar datos de vuelta. En lugar de proporcionar los archivos de diseño xml, aquí hay una imagen.

ingrese la descripción de la imagen aquí

Actividad principal

  • Inicie la segunda actividad con startActivityForResult, proporcionándole un código de resultado arbitrario.
  • Anular onActivityResult. Esto se llama cuando termina la segunda actividad. Puede asegurarse de que realmente sea la segunda actividad al verificar el código de solicitud. (Esto es útil cuando está iniciando múltiples actividades diferentes desde la misma actividad principal).
  • Extraiga los datos que obtuvo de la declaración Intent. Los datos se extraen utilizando un par clave-valor.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private static final int SECOND_ACTIVITY_REQUEST_CODE = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // "Go to Second Activity" button click
    public void onButtonClick(View view) {

        // Start the SecondActivity
        Intent intent = new Intent(this, SecondActivity.class);
        startActivityForResult(intent, SECOND_ACTIVITY_REQUEST_CODE);
    }

    // This method is called when the second activity finishes
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Check that it is the SecondActivity with an OK result
        if (requestCode == SECOND_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {

                // Get String data from Intent
                String returnString = data.getStringExtra("keyName");

                // Set text view with string
                TextView textView = (TextView) findViewById(R.id.textView);
                textView.setText(returnString);
            }
        }
    }
}

Segunda actividad

  • Ponga los datos que desea enviar de vuelta a la actividad anterior en un Intent. Los datos se almacenan Intentutilizando un par clave-valor.
  • Establezca el resultado RESULT_OKy agregue la intención que contiene sus datos.
  • Llame finish()para cerrar la segunda actividad.

SecondActivity.java

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }

    // "Send text back" button click
    public void onButtonClick(View view) {

        // Get the text from the EditText
        EditText editText = (EditText) findViewById(R.id.editText);
        String stringToPassBack = editText.getText().toString();

        // Put the String to pass back into an Intent and close this activity
        Intent intent = new Intent();
        intent.putExtra("keyName", stringToPassBack);
        setResult(RESULT_OK, intent);
        finish();
    }
}

Otras notas

  • Si estás en un Fragmento, no sabrá el significado de RESULT_OK. Sólo tiene que utilizar el nombre completo: Activity.RESULT_OK.

Ver también

Suragch
fuente
Esa es una explicación explícita muy bien escrita. ¡Bien hecho!
Kingsley Ijike
29

FirstActivity usa startActivityForResult:

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
startActivityForResult(intent, int requestCode); // suppose requestCode == 2

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == 2)
    {
        String message=data.getStringExtra("MESSAGE");
    }
}

En SecondActivity llame a setResult () onClick events o onBackPressed ()

Intent intent=new Intent();
intent.putExtra("MESSAGE",message);
setResult(Activity.RESULT_OK, intent);
Vijay
fuente
¿Es resultCode de requestCode?
Engr Syed Rowshan Ali
15

Llame a la actividad secundaria Intención utilizando la llamada al método startActivityForResult ()

Hay un ejemplo de esto aquí: http://developer.android.com/training/notepad/notepad-ex2.html

y en "Devolver un resultado de una pantalla" de esto: http://developer.android.com/guide/faq/commontasks.html#opennewscreen

Intrincaciones
fuente
Sí, estoy de acuerdo con cbrulak, el enlace a los documentos fue mucho más útil que la respuesta.
george_h
Los enlaces muestran algunas cosas generales ahora. El contenido puede cambiar, actualícelo o elimine la respuesta para la comunidad
Manoranjan
7

He creado una clase de demostración simple para su mejor referencia.

FirstActivity.java

 public class FirstActivity extends AppCompatActivity {

    private static final String TAG = FirstActivity.class.getSimpleName();
    private static final int REQUEST_CODE = 101;
    private Button btnMoveToNextScreen;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnMoveToNextScreen = (Button) findViewById(R.id.btnMoveToNext);
        btnMoveToNextScreen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent mIntent = new Intent(FirstActivity.this, SecondActivity.class);
                startActivityForResult(mIntent, REQUEST_CODE);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(resultCode == RESULT_OK){
            if(requestCode == REQUEST_CODE && data !=null) {
                String strMessage = data.getStringExtra("keyName");
                Log.i(TAG, "onActivityResult: message >>" + strMessage);
            }
        }

    }
}

Y aquí está SecondActivity.java

public class SecondActivity extends AppCompatActivity {

    private static final String TAG = SecondActivity.class.getSimpleName();
    private Button btnMoveToPrevious;
    private EditText editText;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        editText = (EditText) findViewById(R.id.editText);

        btnMoveToPrevious = (Button) findViewById(R.id.btnMoveToPrevious);
        btnMoveToPrevious.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String message = editText.getEditableText().toString();

                Intent mIntent = new Intent();
                mIntent.putExtra("keyName", message);
                setResult(RESULT_OK, mIntent);
                finish();

            }
        });

    }
}
Kuls
fuente
3
¡Bien explicado!
Radhey
5

En la primera actividad, puede enviar la intención usando startActivityForResult()y luego obtener el resultado de la segunda actividad después de que termine de usar setResult.

MainActivity.class

public class MainActivity extends AppCompatActivity {

    private static final int SECOND_ACTIVITY_RESULT_CODE = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // "Go to Second Activity" button click
    public void onButtonClick(View view) {

        // Start the SecondActivity
        Intent intent = new Intent(this, SecondActivity.class);
        // send intent for result 
        startActivityForResult(intent, SECOND_ACTIVITY_RESULT_CODE);
    }

    // This method is called when the second activity finishes
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // check that it is the SecondActivity with an OK result
        if (requestCode == SECOND_ACTIVITY_RESULT_CODE) {
            if (resultCode == RESULT_OK) {

                // get String data from Intent
                String returnString = data.getStringExtra("keyName");

                // set text view with string
                TextView textView = (TextView) findViewById(R.id.textView);
                textView.setText(returnString);
            }
        }
    }
}

SecondActivity.class

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }

    // "Send text back" button click
    public void onButtonClick(View view) {

        // get the text from the EditText
        EditText editText = (EditText) findViewById(R.id.editText);
        String stringToPassBack = editText.getText().toString();

        // put the String to pass back into an Intent and close this activity
        Intent intent = new Intent();
        intent.putExtra("keyName", stringToPassBack);
        setResult(RESULT_OK, intent);
        finish();
    }
}
Yogesh Adhe
fuente
1

Todas estas respuestas explican que el escenario de su segunda actividad debe finalizar después de enviar los datos.

Pero en caso de que no desee finalizar la segunda actividad y enviar los datos nuevamente al primero, para eso puede usar BroadCastReceiver.

En segunda actividad

Intent intent = new Intent("data");
intent.putExtra("some_data", true);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

En primera actividad

private BroadcastReceiver tempReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // do some action
    }
};

Registre el receptor en onCreate () -

 LocalBroadcastManager.getInstance(this).registerReceiver(tempReceiver,new IntentFilter("data"));

Anular el registro en onDestroy ()

Shivam Yadav
fuente
0

Otra forma de lograr el resultado deseado que puede ser mejor dependiendo de su situación es crear una interfaz de escucha.

Al hacer que la actividad principal escuche una interfaz que se activa por la actividad secundaria mientras pasa los datos requeridos como parámetro, puede crear un conjunto similar de circunstancias

Lenos
fuente
-1

Hay algunas formas de hacer esto. 1. utilizando startActivityForResult (), que se explica muy bien en las respuestas anteriores.

  1. creando las variables estáticas en su clase "Utils" o en cualquier otra clase propia. Por ejemplo, quiero pasar studentId de ActivityB a ActivityA. Primero, mi ActivityA está llamando a ActivityB. Luego, dentro de ActivityB, configure el studentId (que es un campo estático en Utils.class). Me gusta esto. Utilidades. luego, mientras regresa a la Actividad A, use el studentId que está almacenado en Utils.STUDENT_ID.

  2. creando un método getter y setter en su clase de aplicación.

Me gusta esto:

public class MyApplication extends Application {

    private static MyApplication instance = null;
    private String studentId="";

    public static MyApplication getInstance() {
        return instance;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
    }

    public void setStudentId(String studentID){
        this.studentId=studentID;
    }

    public String getStudentId(){
        return this.studentId;
    }
}

entonces ya terminaste. simplemente configure los datos dentro cuando esté en ActivityB y luego de regresar a ActivityA, obtenga los datos.

swetabh suman
fuente
-1

Solo un pequeño detalle que creo que falta en las respuestas anteriores.

Si la actividad de su hijo se puede abrir desde múltiples actividades para padres, entonces puede verificar si necesita hacerlo setResulto no, en función de si su actividad fue abierta por startActivityo startActivityForResult. Puede lograr esto usando getCallingActivity(). Más información aquí .

Dhruv Jagetiya
fuente
-2

Use sharedPreferences y guarde sus datos y acceda a ellos desde cualquier lugar de la aplicación

guardar fecha como esta

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString(key, value);
    editor.commit();

Y recibir datos como este

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    String savedPref = sharedPreferences.getString(key, "");
    mOutputView.setText(savedPref);
Desarrollador Híbrido
fuente
66
Esto sería más apropiado si la segunda actividad estableciera un cambio / configuración permanente en la aplicación.
Elimirks
¿Funcionará esto si quiero compartir datos entre 2 aplicaciones de Android diferentes? ¿Una denominada biblioteca?
Joey Rohan
21
Esto es abuso de SharedPreferences.
Eran Goldin
1
Usar este método para pasar datos entre dos actividades (la pregunta original de OP) es como abusar de SharedPreferences. No es para esto y el sistema tiene que hacer demasiado trabajo (escribir xml en el almacenamiento y leerlo nuevamente) para una tarea simple como pasar datos entre dos actividades.
Sudara