Renvoyer des données à l'activité principale dans Android

295

J'ai deux activités: l'activité principale et l'activité enfant.
Lorsque j'appuie sur un bouton de l'activité principale, l'activité enfant est lancée.

Maintenant, je veux renvoyer des données à l'écran principal. J'ai utilisé la classe Bundle, mais cela ne fonctionne pas. Il lève quelques exceptions d'exécution.

Existe-t-il une solution à ça?

Rajapandian
la source
Encore une astuce: définissez une ArrayList dans votre activité principale et rendez-la statique afin que vous puissiez y accéder dans la deuxième activité, puis y ajouter des données que vous souhaitez envoyer à l'activité principale, puis vous y accédez dans l'activité principale
Abhishek Yadav
Abhishek Yadav, que se passe-t-il si votre activité principale va détruire (rappel onDestroy ()). Je pense que ce n'est pas un très bon conseil.
Leontsev Anton

Réponses:

474

Il existe plusieurs façons de réaliser ce que vous voulez, selon les circonstances.

Le scénario le plus courant (à quoi ressemble le vôtre) est lorsqu'une activité enfant est utilisée pour obtenir une entrée utilisateur - comme choisir un contact dans une liste ou entrer des données dans une boîte de dialogue. Dans ce cas, vous devez utiliser startActivityForResultpour lancer votre activité enfant.

Cela fournit un pipeline pour renvoyer des données à l'activité principale en utilisant setResult. La méthode setResult prend une valeur de résultat int et une intention qui est renvoyée à l'activité appelante.

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

Pour accéder aux données renvoyées dans le remplacement d'activité appelant onActivityResult. Le requestCode correspond à l'entier transmis dans l' startActivityForResultappel, tandis que le resultCode et les données Intent sont renvoyés par l'activité enfant.

@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
la source
4
pour être complet, il faut mentionner quel est le meilleur endroit pour passer l'appel à finish ()? Cela peut être clair pour les experts, mais pour les débutants, il serait bon de savoir sans faire référence à des sources supplémentaires.
Tarif
1
@jelmoodjasser Cela m'a pris un peu de temps à comprendre, mais fondamentalement, lorsque vous démarrez la nouvelle activité avec Intention, vous devez utiliser la startActivityForResultfonction au lieu de simplement startActivity. Un exemple pourrait être startActivityForResult(myIntent, 2);où 2 est le code de résultat, qui peut prendre la place de MY_CHILD_ACTIVITYdans l'instruction switch ci-dessus.
Spotlight
lorsque la deuxième activité est terminée et revient à la première activité, puis comment définir requestCode dans la deuxième activité avant de la terminer .... pour l'utiliser sur onActivityResult in FirstActivity
Ahamadullah Saikat
L'intention est-elle obligatoire? Si je n'ai rien à renvoyer, ai-je besoin que l'intention vide soit renvoyée?
Bagus Aji Santoso
L'intention @BagusAjiSantoso est facultative, nécessaire uniquement si vous avez quelque chose à renvoyer.
Narendra Singh
186

L'activité 1 utilise startActivityForResult :

startActivityForResult(ActivityTwo, ActivityTwoRequestCode);

L'activité 2 est lancée et vous pouvez effectuer l'opération, pour fermer l'activité, procédez comme suit:

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

Activité 1 - le retour de l'activité précédente appellera 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);
    }
}

MISE À JOUR: réponse au commentaire de Seenu69, dans l'activité deux,

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

Puis dans l'activité un,

int result = data.getExtra(KEY_RESULT);
jimmithy
la source
Salut, je vous remercie d'avoir répondu à ma question.Ce code ne me suffit pas. Je souhaite que l'addition soit effectuée dans la deuxième activité elle-même et le résultat doit être renvoyé à MainActivity via la méthode onActivityResult. Par exemple, il n'y a qu'un bouton dans l'activité principale qui vous amène à une deuxième activité en cliquant dessus, deux nombres sont entrés via le widget editText, une logique d'addition est effectuée dans la deuxième activité elle-même et enfin le résultat est renvoyé à MainActivity. Je l'ai?
Seenu69
2
Dans ce cas, dans la deuxième activité, vous devez effectuer le calcul et stocker le résultat dans l'intention avec putExtra (). J'ai modifié ma réponse ci
jimmithy
68

Renvoyer des données

Cela m'aide à voir les choses dans leur contexte. Voici un projet simple et complet pour renvoyer des données. Plutôt que de fournir les fichiers de mise en page XML, voici une image.

entrez la description de l'image ici

Activité principale

  • Commencez la deuxième activité avec startActivityForResult, en lui fournissant un code de résultat arbitraire.
  • Remplacer onActivityResult. Ceci est appelé lorsque la deuxième activité se termine. Vous pouvez vous assurer qu'il s'agit bien de la deuxième activité en vérifiant le code de demande. (Ceci est utile lorsque vous lancez plusieurs activités différentes à partir de la même activité principale.)
  • Extrayez les données que vous avez obtenues du retour Intent. Les données sont extraites à l'aide d'une paire clé-valeur.

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

Deuxième activité

  • Mettez les données que vous souhaitez renvoyer à l'activité précédente dans un fichier Intent. Les données sont stockées dans à l' Intentaide d'une paire clé-valeur.
  • Définissez le résultat RESULT_OKet ajoutez l'intention de conserver vos données.
  • Appelez finish()pour fermer la deuxième activité.

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

Autres notes

  • Si vous êtes dans un fragment, il ne connaîtra pas la signification de RESULT_OK. Il suffit d' utiliser le nom complet: Activity.RESULT_OK.

Voir également

Suragch
la source
C'est une explication très bien écrite. Bien joué!
Kingsley Ijike
29

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

Sur SecondActivity, appelez setResult () aux événements onClick ou onBackPressed ()

Intent intent=new Intent();
intent.putExtra("MESSAGE",message);
setResult(Activity.RESULT_OK, intent);
Vijay
la source
Est-ce resultCode de requestCode?
Engr Syed Rowshan Ali
15

Appelez l'activité enfant Intent à l'aide de l'appel de méthode startActivityForResult ()

Il y a un exemple de ceci ici: http://developer.android.com/training/notepad/notepad-ex2.html

et dans le "Retour d'un résultat à partir d'un écran" de ceci: http://developer.android.com/guide/faq/commontasks.html#opennewscreen

Intrications
la source
Oui, je suis d'accord avec cbrulak, le lien vers les documents était bien plus utile que la réponse.
george_h
Les liens montrent maintenant des choses générales. Le contenu peut être modifié, veuillez le mettre à jour ou supprimer la réponse pour la communauté
Manoranjan
7

J'ai créé une classe de démonstration simple pour votre meilleure référence.

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

    }
}

Et voici 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
la source
3
bien expliqué!
Radhey
5

Dans la première activité, vous pouvez envoyer l'intention en utilisant startActivityForResult(), puis obtenir le résultat de la deuxième activité après avoir terminé l'utilisation 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
la source
1

Toutes ces réponses expliquent que le scénario de votre deuxième activité doit être terminé après l'envoi des données.

Mais si vous ne souhaitez pas terminer la deuxième activité et que vous souhaitez renvoyer les données en premier, vous pouvez utiliser BroadCastReceiver.

Dans la deuxième activité -

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

Dans la première activité-

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

Enregistrez le récepteur dans onCreate () -

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

Désinscrivez-le dans onDestroy ()

Shivam Yadav
la source
0

Une autre façon d'atteindre le résultat souhaité qui peut être meilleur selon votre situation est de créer une interface d'écoute.

En faisant écouter l'activité parent à une interface déclenchée par l'activité enfant tout en transmettant les données requises en tant que paramètre, vous pouvez créer un ensemble de circonstances similaire

Lenos
la source
-1

Il y a plusieurs façons de procéder. 1. en utilisant startActivityForResult () qui est très bien expliqué dans les réponses ci-dessus.

  1. en créant les variables statiques dans votre classe "Utils" ou toute autre classe de votre choix. Par exemple, je veux passer studentId de ActivityB à ActivityA. Tout d'abord, mon ActivityA appelle ActivityB. Ensuite, dans ActivityB, définissez studentId (qui est un champ statique dans Utils.class). Comme ceci Utils.STUDENT_ID = "1234"; puis en revenant à l'ActivitéA, utilisez le studentId qui est stocké dans Utils.STUDENT_ID.

  2. en créant une méthode getter et setter dans votre classe d'application.

comme ça:

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

vous avez donc terminé. définissez simplement les données à l'intérieur lorsque vous êtes dans ActivityB et après être revenu à ActivityA, récupérez les données.

swetabh suman
la source
-1

Juste un petit détail qui, je pense, manque dans les réponses ci-dessus.

Si votre activité enfant peut être ouverte à partir de plusieurs activités parentales, vous pouvez vérifier si vous devez le faire setResultou non, selon que votre activité a été ouverte par startActivityou startActivityForResult. Vous pouvez y parvenir en utilisant getCallingActivity(). Plus d'infos ici .

Dhruv Jagetiya
la source
-2

Utilisez sharedPreferences et enregistrez vos données et accédez-y depuis n'importe où dans l'application

enregistrer la date comme ça

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

Et recevoir des données comme celle-ci

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    String savedPref = sharedPreferences.getString(key, "");
    mOutputView.setText(savedPref);
Développeur hybride
la source
6
Cela serait plus approprié si la deuxième activité consistait à définir un changement / paramètre permanent dans l'application.
elimirks
Est-ce que cela fonctionnera si je veux partager des données entre 2 applications Android différentes? Une appelée bibliothèque?
joey rohan
21
Il s'agit d'un abus de SharedPreferences.
Eran Goldin
1
Utiliser cette méthode pour simplement transmettre des données entre deux activités (question d'origine de OP) revient à abuser de SharedPreferences. Il n'est pas destiné à cela et le système doit faire trop de travail (écrire du xml sur le stockage et le relire) pour une tâche simple comme passer des données entre deux activités.
Sudara