Senden von Daten an die Hauptaktivität in Android zurück

295

Ich habe zwei Aktivitäten: Hauptaktivität und Kinderaktivität.
Wenn ich in der Hauptaktivität eine Taste drücke, wird die untergeordnete Aktivität gestartet.

Jetzt möchte ich einige Daten an den Hauptbildschirm zurücksenden. Ich habe die Bundle-Klasse verwendet, aber sie funktioniert nicht. Es werden einige Laufzeitausnahmen ausgelöst.

Gibt es dafür eine Lösung?

Rajapandian
quelle
Ein weiterer Trick definiert eine ArrayList in Ihrer Hauptaktivität und macht sie statisch, damit Sie in der zweiten Aktivität darauf zugreifen können. Fügen Sie dann Daten hinzu, die Sie an die Hauptaktivität senden möchten, und greifen Sie dann in der Hauptaktivität darauf zu
Abhishek Yadav
Abhishek Yadav, was ist, wenn Ihre Hauptaktivität zerstört wird (onDestroy () Rückruf). Ich denke, es ist kein sehr guter Rat.
Leontsev Anton

Antworten:

473

Abhängig von den Umständen gibt es verschiedene Möglichkeiten, um das zu erreichen, was Sie wollen.

Das häufigste Szenario (wie es sich bei Ihnen anhört) ist, wenn eine untergeordnete Aktivität verwendet wird, um Benutzereingaben abzurufen - z. B. die Auswahl eines Kontakts aus einer Liste oder die Eingabe von Daten in ein Dialogfeld. In diesem Fall sollten startActivityForResultSie die Aktivität Ihres Kindes starten.

Dies bietet eine Pipeline zum Zurücksenden von Daten an die Hauptaktivität mithilfe von setResult. Die setResult-Methode verwendet einen int-Ergebniswert und eine Absicht, die an die aufrufende Aktivität zurückgegeben wird.

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

Um auf die zurückgegebenen Daten in der aufrufenden Aktivität zuzugreifen, überschreiben Sie diese onActivityResult. Der requestCode entspricht der im startActivityForResultAufruf übergebenen Ganzzahl , während der resultCode und die Datenabsicht von der untergeordneten Aktivität zurückgegeben werden.

@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
quelle
4
der Vollständigkeit halber sollte man erwähnen, wo man den Aufruf zum Beenden am besten platzieren kann ()? Für Experten ist das vielleicht klar, aber für Anfänger wäre es gut zu wissen, ohne auf zusätzliche Quellen zu verweisen.
Califf
1
@jelmoodjasser Ich habe ein bisschen gebraucht, um das herauszufinden, aber wenn Sie die neue Aktivität mit Intent starten, müssen Sie die startActivityForResultFunktion anstelle von nur verwenden startActivity. Ein Beispiel könnte sein, startActivityForResult(myIntent, 2);dass 2 der Ergebniscode ist, der den Platz MY_CHILD_ACTIVITYin der obigen switch-Anweisung einnehmen kann .
Spotlight
Wenn die zweite Aktivität beendet ist und zur ersten Aktivität zurückkehrt, wie man requestCode in die zweite Aktivität setzt, bevor man sie beendet ... für die Verwendung als onActivityResult in FirstActivity
Ahamadullah Saikat
Ist Absicht obligatorisch? Wenn ich nichts zurückschicken kann, brauche ich die leere Absicht, um zurückzusenden?
Bagus Aji Santoso
Die Absicht @BagusAjiSantoso ist optional und wird nur benötigt, wenn Sie etwas zurücksenden müssen.
Narendra Singh
186

Aktivität 1 verwendet startActivityForResult :

startActivityForResult(ActivityTwo, ActivityTwoRequestCode);

Aktivität 2 wird gestartet und Sie können den Vorgang ausführen, um die Aktivität zu schließen. Gehen Sie folgendermaßen vor:

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

Aktivität 1 - Wenn Sie von der vorherigen Aktivität zurückkehren, wird onActivityResult aufgerufen :

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

UPDATE: Antwort auf den Kommentar von Seenu69, In ​​Aktivität zwei,

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

Dann in Aktivität eins,

int result = data.getExtra(KEY_RESULT);
jimmithy
quelle
Hallo, ich schätze dich für die Beantwortung meiner Frage. Dieser Code reicht mir nicht. Ich möchte, dass die Addition in der zweiten Aktivität selbst durchgeführt wird und das Ergebnis über die onActivityResult-Methode an MainActivity zurückgegeben wird. Zum Beispiel gibt es in der Hauptaktivität nur eine Schaltfläche, die Sie beim Klicken zur zweiten Aktivität führt. Dort werden zwei Zahlen über das Widget editText eingegeben, die Additionslogik wird in der zweiten Aktivität selbst ausgeführt und schließlich wird das Ergebnis an MainActivity zurückgegeben. Verstanden?
Seenu69
2
In diesem Fall würden Sie in der zweiten Aktivität die Berechnung durchführen und das Ergebnis in der Absicht mit putExtra () speichern. Ich habe meine Antwort oben bearbeitet
jimmithy
68

Daten zurücksenden

Es hilft mir, die Dinge im Kontext zu sehen. Hier ist ein komplettes einfaches Projekt zum Zurücksenden von Daten. Anstatt die XML-Layoutdateien bereitzustellen, ist hier ein Bild.

Geben Sie hier die Bildbeschreibung ein

Hauptaktivität

  • Beginnen Sie die zweite Aktivität mit startActivityForResultund geben Sie einen beliebigen Ergebniscode ein.
  • Überschreiben onActivityResult. Dies wird aufgerufen, wenn die zweite Aktivität beendet ist. Sie können sicherstellen, dass es sich tatsächlich um die zweite Aktivität handelt, indem Sie den Anforderungscode überprüfen. (Dies ist nützlich, wenn Sie mehrere verschiedene Aktivitäten von derselben Hauptaktivität aus starten.)
  • Extrahieren Sie die Daten, die Sie aus der Rücksendung erhalten haben Intent. Die Daten werden mit einem Schlüssel-Wert-Paar extrahiert.

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

Zweite Aktivität

  • Fügen Sie die Daten, die Sie an die vorherige Aktivität zurücksenden möchten, in eine ein Intent. Die Daten werden unter IntentVerwendung eines Schlüssel-Wert-Paares im gespeichert .
  • Setzen Sie das Ergebnis auf RESULT_OKund fügen Sie die Absicht hinzu, die Ihre Daten enthält.
  • Rufen Sie finish()an, um die zweite Aktivität zu schließen.

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

Weitere Hinweise

  • Wenn Sie sich in einem Fragment befinden, weiß es nicht, was es bedeutet RESULT_OK. Verwenden Sie einfach den vollständigen Namen : Activity.RESULT_OK.

Siehe auch

Suragch
quelle
Das ist eine sehr gut geschriebene explizite Erklärung. Gut gemacht!
Kingsley Ijike
29

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

Rufen Sie bei SecondActivity setResult () onClick-Ereignisse oder onBackPressed () auf.

Intent intent=new Intent();
intent.putExtra("MESSAGE",message);
setResult(Activity.RESULT_OK, intent);
Vijay
quelle
Ist es resultCode von requestCode?
Engr Syed Rowshan Ali
15

Rufen Sie die untergeordnete Aktivität Intent mit dem Methodenaufruf startActivityForResult () auf

Ein Beispiel hierfür finden Sie hier: http://developer.android.com/training/notepad/notepad-ex2.html

und im Abschnitt "Zurückgeben eines Ergebnisses von einem Bildschirm": http://developer.android.com/guide/faq/commontasks.html#opennewscreen

Komplikationen
quelle
Ja, ich stimme cbrulak zu, der Link zu den Dokumenten war viel hilfreicher als die Antwort.
George_h
Die Links zeigen jetzt einige allgemeine Dinge. Der Inhalt könnte geändert werden, bitte aktualisieren Sie ihn oder entfernen Sie die Antwort für die Community
Manoranjan
7

Ich habe eine einfache Demo-Klasse für Ihre bessere Referenz erstellt.

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

    }
}

Und hier ist 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
quelle
3
gut erklärt!
Radhey
5

In der ersten Aktivität können Sie die Absicht mit senden startActivityForResult()und dann das Ergebnis der zweiten Aktivität abrufen, nachdem die Verwendung beendet wurde 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
quelle
1

Alle diese Antworten erklären, dass das Szenario Ihrer zweiten Aktivität nach dem Senden der Daten abgeschlossen sein muss.

Wenn Sie jedoch die zweite Aktivität nicht beenden und die Daten zuerst an senden möchten, können Sie BroadCastReceiver verwenden.

In der zweiten Aktivität -

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

In der ersten Aktivität-

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

Registrieren Sie den Empfänger in onCreate () -

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

Heben Sie die Registrierung in onDestroy () auf

Shivam Yadav
quelle
0

Eine andere Möglichkeit, das gewünschte Ergebnis zu erzielen, das je nach Situation möglicherweise besser ist, besteht darin, eine Listener-Oberfläche zu erstellen.

Indem die übergeordnete Aktivität eine Schnittstelle abhört, die von der untergeordneten Aktivität ausgelöst wird, während die erforderlichen Daten als Parameter übergeben werden, kann dies zu ähnlichen Umständen führen

Lenos
quelle
-1

Es gibt einige Möglichkeiten, dies zu tun. 1. Verwenden Sie das startActivityForResult (), das in den obigen Antworten sehr gut erklärt wird.

  1. indem Sie die statischen Variablen in Ihrer "Utils" -Klasse oder einer anderen eigenen Klasse erstellen. Zum Beispiel möchte ich studentId von ActivityB an ActivityA übergeben. Zuerst ruft meine ActivityA die ActivityB auf. Legen Sie dann in ActivityB die studentId fest (ein statisches Feld in Utils.class). Gefällt mir Utils.STUDENT_ID = "1234"; Verwenden Sie dann beim Zurückkehren zur AktivitätA die studentId, die in Utils.STUDENT_ID gespeichert ist.

  2. indem Sie eine Getter- und Setter-Methode in Ihrer Anwendungsklasse erstellen.

so was:

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

Also bist du fertig. Legen Sie einfach die Daten fest, wenn Sie sich in Aktivität B befinden, und rufen Sie die Daten ab, nachdem Sie zu Aktivität A zurückgekehrt sind.

Swetabh Suman
quelle
-1

Nur ein kleines Detail, von dem ich denke, dass es in den obigen Antworten fehlt.

Wenn Ihre untergeordnete Aktivität über mehrere übergeordnete Aktivitäten geöffnet werden kann, können Sie überprüfen, ob Sie dies tun müssen setResultoder nicht, basierend darauf, ob Ihre Aktivität von startActivityoder geöffnet wurde startActivityForResult. Sie können dies erreichen, indem Sie verwenden getCallingActivity(). Mehr Infos hier .

Dhruv Jagetiya
quelle
-2

Verwenden Sie sharedPreferences, speichern Sie Ihre Daten und greifen Sie von überall in der Anwendung darauf zu

Speichern Sie das Datum so

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

Und solche Daten erhalten

SharedPreferences sharedPreferences = getPreferences(MODE_PRIVATE);
    String savedPref = sharedPreferences.getString(key, "");
    mOutputView.setText(savedPref);
Hybrid-Entwickler
quelle
6
Dies wäre angemessener, wenn die zweite Aktivität eine permanente Änderung / Einstellung in der Anwendung festlegen würde.
Elimirks
Funktioniert dies, wenn ich Daten zwischen zwei verschiedenen Android-Apps teilen möchte? Eine wird als Bibliothek bezeichnet?
Joey Rohan
21
Dies ist Missbrauch von SharedPreferences.
Eran Goldin
1
Die Verwendung dieser Methode zum einfachen Übergeben von Daten zwischen zwei Aktivitäten (die ursprüngliche Frage von OP) entspricht dem Missbrauch von SharedPreferences. Es ist nicht dafür gedacht und das System muss zu viel Arbeit (Schreiben von XML im Speicher und erneutes Lesen) für eine einfache Aufgabe wie das Übergeben von Daten zwischen zwei Aktivitäten leisten.
Sudara