Androidのメインアクティビティにデータを送り返す


295

私には2つの活動があります。メインの活動と子供の活動です。
メインアクティビティのボタンを押すと、子アクティビティが起動します。

次に、データをメイン画面に送り返します。Bundleクラスを使用しましたが、機能しません。いくつかの実行時例外がスローされます。

これに対する解決策はありますか?



もう1つのトリックは、メインアクティビティでArrayListを定義し、それを静的にして、2番目のアクティビティでそれにアクセスし、メインアクティビティに送信するデータを追加して、メインアクティビティでそれにアクセスできるようにする
Abhishek Yadav

Abhishek Yadav、メインアクティビティがdestroy(onDestroy()コールバック)になる場合はどうでしょうか。あまり良いアドバイスではないと思います。
Leontsev Anton

回答:


473

状況に応じて、目的を達成する方法はいくつかあります。

最も一般的なシナリオ(これはあなたの音です)は、子アクティビティを使用してユーザー入力を取得する場合です(リストから連絡先を選択する、ダイアログボックスにデータを入力するなど)。この場合は、を使用startActivityForResultして子アクティビティを起動する必要があります。

これは、を使用してデータをメインアクティビティに送り返すためのパイプラインを提供しsetResultます。setResultメソッドは、intの結果値と、呼び出し元のアクティビティに渡されるインテントを受け取ります。

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

呼び出しアクティビティで返されたデータにアクセスするには、オーバーライドしますonActivityResult。requestCodeはstartActivityForResult呼び出しで渡された整数に対応し、resultCodeとdata Intentは子アクティビティから返されます。

@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
完全を期すために、finish()の呼び出しを配置するのに最適な場所は何ですか?それは専門家にはおそらく明らかですが、初心者にとっては、追加のソースを参照せずに知っておくとよいでしょう。
カリフ

1
@jelmoodjasser理解するには少し時間がかかりましたが、基本的には、Intentで新しいアクティビティを開始するときstartActivityForResultは、単にではなく関数を使用する必要がありますstartActivity。たとえばstartActivityForResult(myIntent, 2);、2が結果コードで、MY_CHILD_ACTIVITY上記のswitchステートメントの代わりになる場合があります。
スポットライト

第二の活性が完了する前に、第二の活性に次にどのセットrequestCodeに終了し、最初のアクティビティに戻るとき、それ.... FirstActivityでonActivityResultに使用をするため
Ahamadullah Saikat

インテントは必須ですか?返送するものがない場合、空のインテントを返送する必要がありますか?
Bagus Aji Santoso

@BagusAjiSantosoインテントはオプションであり、返送するものがある場合にのみ必要です。
Narendra Singh

186

アクティビティ1はstartActivityForResultを使用します

startActivityForResult(ActivityTwo, ActivityTwoRequestCode);

アクティビティ2が起動し、操作を実行して、アクティビティを閉じることができます。

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

アクティビティ1-前のアクティビティから戻ると、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);
    }
}

更新:Seenu69のコメントへの回答、アクティビティ2では、

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

次に、アクティビティ1では

int result = data.getExtra(KEY_RESULT);

こんにちは。質問に答えてくれてありがとう。このコードでは十分ではありません。追加を2番目のアクティビティ自体で実行し、結果をonActivityResultメソッドを介してMainActivityに返す必要があります。たとえば、メインアクティビティにはボタンをクリックして、クリックすると2番目のアクティビティに移動します。editTextウィジェットから2つの数値が入力され、2番目のアクティビティ自体で追加ロジックが実行され、最後に結果がMainActivityに返されます。とった?
Seenu69 '13 / 11/12

2
その場合、2番目のアクティビティでは、計算を実行し、結果をputExtra()を使用してインテントに格納します。私は上記の回答を編集しました
jimmithy

68

データの返送

状況を把握するのに役立ちます。これは、データを送り返すための完全でシンプルなプロジェクトです。ここでは、xmlレイアウトファイルを提供するのではなく、画像を示します。

ここに画像の説明を入力してください

主な活動

  • startActivityForResult任意の結果コードを指定して、2番目のアクティビティをで開始します。
  • 上書きするonActivityResult。これは、2番目のアクティビティが終了したときに呼び出されます。リクエストコードを確認することで、それが実際に2番目のアクティビティであることを確認できます。(これは、同じメインアクティビティから複数の異なるアクティビティを開始するときに便利です。)
  • 戻りから得たデータを抽出しますIntent。データは、キーと値のペアを使用して抽出されます。

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

2番目のアクティビティ

  • 前のアクティビティに送り返すデータをに入れますIntent。データはIntent、キーと値のペアを使用してに格納されます。
  • 結果を RESULT_OKデータを保持するインテントを追加します。
  • コール finish()2番目のアクティビティを閉じるためにます。

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

その他の注意事項

  • フラグメントにいる場合は、の意味がわかりませんRESULT_OK。完全な名前を使用してください:Activity.RESULT_OK

こちらもご覧ください


それは非常によく書かれた明確な説明です。よくやった!
Kingsley Ijike

29

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

SecondActivityでsetResult()onClickイベントまたはonBackPressed()を呼び出します

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

requestCodeのresultCodeですか?
Engr Syed Rowshan Ali

15

startActivityForResult()メソッド呼び出しを使用して、子アクティビティIntentを呼び出します

これの例はここにあります:http : //developer.android.com/training/notepad/notepad-ex2.html

これの「画面から結果を返す」:http : //developer.android.com/guide/faq/commontasks.html#opennewscreen


はい、私はcbrulakに同意します。ドキュメントへのリンクは、回答よりもはるかに役に立ちました。
george_h 2013

リンクは現在いくつかの一般的なことを示しています。コンテンツは変更される可能性があります。更新するか、コミュニティの回答を削除してください
Manoranjan

7

参考のために、簡単なデモクラスを作成しました。

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

    }
}

そしてここに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
よく説明されました!
Radhey、

5

最初のアクティビティでは、uはインテントを使用startActivityForResult()して送信し、2番目のアクティビティがの使用を終了した後に結果を取得できます 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

これらのすべての回答は、データを送信した後に完了する必要がある2番目のアクティビティのシナリオを説明しています。

ただし、2番目のアクティビティを終了せずに、最初にデータを送り返す場合は、BroadCastReceiverを使用できます。

2番目のアクティビティ-

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

最初のアクティビティ-

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

onCreate()にレシーバーを登録します

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

onDestroy()で登録を解除する


0

状況に応じてより適切な結果が得られる別の方法は、リスナーインターフェイスを作成することです。

親アクティビティに、必要なデータをパラメーターとして渡しながら子アクティビティによってトリガーされるインターフェースをリッスンさせることで、同様の状況のセットを作成できます。


-1

これにはいくつかの方法があります。1.上記の回答で非常によく説明されているstartActivityForResult()を使用する。

  1. "Utils"クラスまたは他の独自のクラスに静的変数を作成する。たとえば、ActivityBからActivityIdにstudentIdを渡したいと思います。最初に、私のActivityAがActivityBを呼び出しています。次に、ActivityB内でstudentId(Utils.classの静的フィールド)を設定します。このようにUtils.STUDENT_ID = "1234"; 次に、ActivityAに戻って、Utils.STUDENT_IDに保存されているstudentIdを使用します。

  2. アプリケーションクラスにゲッターメソッドとセッターメソッドを作成します。

このような:

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

これで完了です。uがActivityBにあるときにデータを内部に設定し、ActivityAに戻ってデータを取得します。


-1

上記の回答で欠けていると思う細部。

子アクティビティを複数の親アクティビティから開くことができる場合setResultは、startActivityまたはによってアクティビティが開かれたかどうかに基づいて、行う必要があるかどうかを確認できますstartActivityForResult。これは、を使用して実現できgetCallingActivity()ます。詳細はこちら


-2

sharedPreferencesを使用するをてデータを保存し、アプリケーションのどこからでもアクセスできます

このように日付を保存

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

そして、このようなデータを受け取ります

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

6
2番目のアクティビティがアプリケーションに永続的な変更/設定を設定していた場合、これはより適切です。
elimirks 2013

2つの異なるAndroidアプリ間でデータを共有する場合、これは機能しますか?1つはライブラリと呼ばれますか?
ジョーイ・ロハン、2014年

21
これはSharedPreferencesの乱用です。
Eran Goldin 2014

1
2つのアクティビティ(OPの元の質問)間でデータを渡すだけにこのメソッドを使用することは、SharedPreferencesを悪用することに似ています。2つのアクティビティ間でデータを渡すなどの単純なタスクでは、システムが大量の作業(ストレージでのxmlの書き込みと再度の読み取り)を行わなければなりません。
Sudara、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.