Invio di dati all'attività principale su Android


295

Ho due attività: attività principale e attività figlio.
Quando premo un pulsante nell'attività principale, viene avviata l'attività figlio.

Ora voglio inviare alcuni dati alla schermata principale. Ho usato la classe Bundle, ma non funziona. Genera alcune eccezioni di runtime.

C'è qualche soluzione per questo?



Un altro trucco definisce un ArrayList nella tua attività principale e rendilo statico in modo che tu possa accedervi nella seconda attività, quindi aggiungere i dati in esso che desideri inviare all'attività principale e accedervi nell'attività principale
Abhishek Yadav

Abhishek Yadav, cosa succede se la tua attività principale sta per distruggere (onDestroy () callback). Penso che non sia un ottimo consiglio.
Leontsev Anton,

Risposte:


473

Ci sono un paio di modi per ottenere ciò che vuoi, a seconda delle circostanze.

Lo scenario più comune (che sembra il tuo) è quando un'attività figlio viene utilizzata per ottenere l'input dell'utente, come la scelta di un contatto da un elenco o l'inserimento di dati in una finestra di dialogo. In questo caso dovresti usare startActivityForResultper avviare la tua attività figlio.

Ciò fornisce una pipeline per l'invio dei dati all'attività principale mediante setResult. Il metodo setResult accetta un valore di risultato int e un Intento che viene restituito all'attività chiamante.

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

Per accedere ai dati restituiti nell'override dell'attività chiamante onActivityResult. RequestCode corrisponde all'intero passato nella startActivityForResultchiamata, mentre resultCode e Data Intent vengono restituiti dall'attività figlio.

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

4
per completezza si dovrebbe menzionare qual è il posto migliore dove effettuare la chiamata per finire ()? Forse è chiaro agli esperti, ma per i principianti sarebbe bene sapere senza fare riferimento a fonti aggiuntive.
Califf

1
@jelmoodjasser Mi ci è voluto un po 'per capire, ma fondamentalmente quando inizi la nuova attività con Intent devi usare la startActivityForResultfunzione invece che semplicemente startActivity. Un esempio potrebbe essere quello in startActivityForResult(myIntent, 2);cui 2 è il codice risultato, che può prendere il posto MY_CHILD_ACTIVITYdell'istruzione switch precedente.
Spotlight

quando la seconda attività è terminata e torna alla prima attività, allora come impostare requestCodifica nella seconda attività prima di finirla .... per usarla su onActivityResult in FirstActivity
Ahamadullah Saikat

L'intenzione è obbligatoria? Se non ho nulla da rispedire, ho bisogno dell'intenzione vuota di rispedirmi?
Bagus Aji Santoso

L'intento di @BagusAjiSantoso è facoltativo, necessario solo se hai qualcosa da inviare.
Narendra Singh,

186

L'attività 1 utilizza startActivityForResult :

startActivityForResult(ActivityTwo, ActivityTwoRequestCode);

Viene avviata l'attività 2 ed è possibile eseguire l'operazione, per chiudere l'attività fare questo:

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

Attività 1 - il ritorno dall'attività precedente chiamerà onActivityResult :

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

AGGIORNAMENTO: risposta al commento di Seenu69, nell'attività due,

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

Quindi nell'attività uno,

int result = data.getExtra(KEY_RESULT);

Ciao, ti apprezzo per aver risposto alla mia domanda. Questo codice non è abbastanza per me. Voglio che l'aggiunta venga eseguita nella seconda attività stessa e il risultato dovrebbe essere restituito a MainActivity tramite il metodo onActivityResult. Ad esempio, c'è solo un pulsante nell'attività principale che ti porta alla seconda attività facendo clic su di esso, lì vengono immessi due numeri attraverso il widget editText, la logica di aggiunta viene eseguita nella seconda attività stessa e infine il risultato viene restituito a MainActivity. Fatto?
Seenu69,

2
In tal caso, nella seconda attività, eseguire il calcolo e memorizzare il risultato nell'intento con putExtra (). Ho modificato la mia risposta sopra
jimmithy il

68

Invio di dati indietro

Mi aiuta a vedere le cose nel contesto. Ecco un semplice progetto completo per la restituzione dei dati. Invece di fornire i file di layout XML, ecco un'immagine.

inserisci qui la descrizione dell'immagine

Attività principale

  • Inizia la seconda attività con startActivityForResult, fornendo un codice risultato arbitrario.
  • Ignora onActivityResult. Questo viene chiamato al termine della Seconda attività. Puoi assicurarti che sia effettivamente la seconda attività controllando il codice di richiesta. (Ciò è utile quando si avviano più attività diverse dalla stessa attività principale.)
  • Estrai i dati che hai ricevuto dal reso Intent. I dati vengono estratti utilizzando una coppia chiave-valore.

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

Seconda attività

  • Inserire i dati che si desidera rinviare all'attività precedente in un Intent. I dati vengono archiviati in Intentusando una coppia chiave-valore.
  • Imposta il risultato su RESULT_OKe aggiungi l'intento che contiene i tuoi dati.
  • Chiama finish()per chiudere la seconda attività.

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

Altre note

  • Se sei in un frammento, non ne conoscerà il significato RESULT_OK. Basta usare il nome completo: Activity.RESULT_OK.

Guarda anche


Questa è una spiegazione esplicita ben scritta. Molto bene!
Kingsley Ijike,

29

FirstActivity utilizza 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");
    }
}

Su SecondActivity chiama setResult () eventi onClick o onBackPressed ()

Intent intent=new Intent();
intent.putExtra("MESSAGE",message);
setResult(Activity.RESULT_OK, intent);

È resultCode di requestCode?
Engr Syed Rowshan Ali,

15

Chiamare l'intento dell'attività figlio utilizzando la chiamata del metodo startActivityForResult ()

C'è un esempio di questo qui: http://developer.android.com/training/notepad/notepad-ex2.html

e in "Restituzione di un risultato da una schermata" di questo: http://developer.android.com/guide/faq/commontasks.html#opennewscreen


Sì, concordo con cbrulak, il collegamento ai documenti è stato molto più utile della risposta.
george_h,

I collegamenti stanno mostrando alcune cose generali ora. Il contenuto potrebbe essere modificato, aggiornalo o rimuovi la risposta per la comunità
Manoranjan,

7

Ho creato una semplice classe demo per un migliore riferimento.

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

    }
}

Ed ecco 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();

            }
        });

    }
}

3
ben spiegato!
Radhey,

5

Nella prima attività è possibile inviare l'intento utilizzando startActivityForResult()e quindi ottenere il risultato dalla seconda attività dopo aver terminato l'utilizzo 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();
    }
}

1

Tutte queste risposte spiegano che lo scenario della tua seconda attività deve essere terminato dopo l'invio dei dati.

Ma nel caso in cui non si desideri terminare la seconda attività e si desideri rinviare i dati per primi, è possibile utilizzare BroadCastReceiver.

In Second Activity -

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

In prima attività

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

Registrare il ricevitore in onCreate () -

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

Annulla la registrazione in onDestroy ()


0

Un altro modo per ottenere il risultato desiderato che può essere migliore a seconda della situazione è creare un'interfaccia di ascolto.

Facendo in modo che l'attività padre ascolti un'interfaccia che viene attivata dall'attività figlio mentre si passano i dati richiesti come parametro, è possibile creare un insieme simile di circostanze


-1

Ci sono alcuni modi per farlo. 1. usando startActivityForResult () che è molto ben spiegato nelle risposte sopra.

  1. creando le variabili statiche nella tua classe "Utils" o in qualsiasi altra tua classe. Ad esempio, voglio passare studentId da ActivityB ad ActivityA. Prima la mia ActivityA sta chiamando ActivityB. Quindi all'interno di ActivityB imposta studentId (che è un campo statico in Utils.class). In questo modo Utils.STUDENT_ID = "1234"; quindi, quando torni all'AttivitàA, usa studentId che è memorizzato in Utils.STUDENT_ID.

  2. creando un metodo getter e setter nella tua classe di applicazione.

come questo:

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

quindi hai finito. basta impostare i dati all'interno quando ci si trova in ActivityB e dopo essere tornati ad ActivityA, ottenere i dati.


-1

Solo un piccolo dettaglio che penso manchi nelle risposte sopra.

Se la tua attività figlio può essere aperta da più attività padre, puoi verificare se è necessario setResulto meno, in base al fatto se l'attività è stata aperta da startActivityo startActivityForResult. Puoi farlo usando getCallingActivity(). Maggiori informazioni qui .


-2

Usa le preferenze condivise e salva i tuoi dati e accedi ad essi da qualsiasi parte dell'applicazione

salva la data in questo modo

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

E ricevi dati come questo

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    String savedPref = sharedPreferences.getString(key, "");
    mOutputView.setText(savedPref);

6
Ciò sarebbe più appropriato se la seconda attività stesse impostando una modifica / impostazione permanente nell'applicazione.
elimirks,

Funzionerà se voglio condividere dati tra 2 diverse app Android? Una definita libreria?
Joey Rohan,

21
Questo è un abuso di SharedPreferences.
Eran Goldin,

1
L'uso di questo metodo per il solo passaggio di dati tra due attività (la domanda originale di OP) è come abusare di SharedPreferences. Non è pensato per questo e il sistema deve fare troppo lavoro (scrivere xml su memoria e leggerlo di nuovo) per un compito semplice come passare i dati tra due attività.
Sudara,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.