[Android] インテント (2) - アクティビティからの結果の受け取り ================================================================================ インテントを使って呼び出したアクティビティから、結果を受け取ることができる。 呼び出す側: ・startActivityForResult() メソッドを使ってアクティビティを起動する ・onActivityResult() メソッドをオーバーライドして、結果を受け取ったときの処理を記述する 呼び出された側: ・必要に応じて、結果を戻すためのインテント・オブジェクトを生成して、データを設定する ・setResult() メソッドで、結果コードや戻すデータを設定する ・finish() メソッドで、アクティビティを終了する ■ 呼び出す側 ▲ アクティビティ インテント起動ボタンを押下したら、startActivityForResult() メソッドを使ってアクティビティを起動する。 onActivityResult() メソッドをオーバーライドして、結果を受け取ったときの処理を記述する。このとき、単語が指定されていれば、この単語を逆順にした文字列を表示する。 単語が指定されていなければ、その旨のメッセージを表示する。 □ Intent02Activity.java --- package jp.marunomaruno.android.intent; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.EditText; import android.widget.TextView; public class Intent02Activity extends Activity { private static final int REQUEST_REVERSE_ACTIVITY = 1; // (1) /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } /** * 暗黙的にインテントを起動する。 * * @param view */ public void onClickImplisitButton(View view) { EditText edit1 = (EditText) findViewById(R.id.editText1); Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra("message", edit1.getText()); startActivityForResult(intent, REQUEST_REVERSE_ACTIVITY); // (2) } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // (3) super.onActivityResult(requestCode, resultCode, data); // (4) TextView text1 = (TextView) findViewById(R.id.text1); switch (requestCode) { // (5) case REQUEST_REVERSE_ACTIVITY: // (6) switch (resultCode) { // (7) case Activity.RESULT_OK: // (8) String reverse = data.getStringExtra("reverse"); text1.setText(reverse); break; case RESULT_FIRST_USER + OtherActivity.NO_WORDS: // (9) text1.setText(R.string.noWordsMessage); break; default: text1.setText(String.format("onActivityResult() resultCode=%d", resultCode)); break; } break; default: text1.setText(String.format("onActivityResult() requestCode=%d", requestCode)); break; } } } --- (1) 逆順文字列作成のためのインテント要求コードを定義する private static final int REQUEST_REVERSE_ACTIVITY = 1; // (1) これは、startActivityForResult() メソッドで指定する。これによって、アクティビティから結果が戻ってきたら、この値を確認することで、どのインテントを使ってアクティビティを呼び出したかがわかる。 (2) 結果を受け取るためのインテントを起動する 要求コードを指定する。 startActivityForResult(intent, REQUEST_REVERSE_ACTIVITY); // (2) (3)(4) インテントの結果を受け取る Activity クラスのこのメソッドをオーバーライドする。 protected void onActivityResult(int requestCode, int resultCode, Intent data) { // (3) requestCode: startActivityForResult() で指定した要求コード resultCode: 戻りコード data: データ スーパークラスの同メソッドを呼び出す。 super.onActivityResult(requestCode, resultCode, data); // (4) (5) 要求コードによって処理を切り分ける switch (requestCode) { // (5) (6) 逆順文字列作成の要求コード case REQUEST_REVERSE_ACTIVITY: // (6) (7) 結果の戻りコードによって処理を切り分ける switch (resultCode) { // (7) Activity クラスで定義している結果コードは次の 3 つ。 --- int RESULT_CANCELED 0 キャンセルされた int RESULT_FIRST_USER 1 自分で定義する結果コードの最初の値 int RESULT_OK -1 結果成功 --- したがって、自分で定義する結果コードは 1 から順番に振る方がよい。 (8) 結果が OK のときの処理 case RESULT_OK: // (8) (9) 単語が指定していなかったときの処理 case RESULT_FIRST_USER + OtherActivity.NO_WORDS: // (9) 値としては、RESULT_FIRST_USER は 1 で、OtherActivity.NO_WORDS は 1 にしているので、2 となっている。 (RESULT_FIRST_USER は加えなくても大丈夫) ▲ レイアウト □ res/layout/main.xml ※前回のプロジェクトと同じ ■ 呼び出される側 ▲ アクティビティ 受け取った文字列の逆順文字列を送る。 受け取った文字列が空でなければ、逆順文字列を作る。そのときの結果コードは RESULT_OK (値は -1)。 文字列が空だったら、結果コードとして、2 (= RESULT_FIRST_USER + NO_WORDS) を設定して返す。 □ OtherActivity.java --- package jp.marunomaruno.android.intent; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.TextView; public class OtherActivity extends Activity { public static final int NO_WORDS = 1; // (1) private String message; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.other); Intent intent = getIntent(); TextView text1 = (TextView) findViewById(R.id.otherTextView1); message = intent.getCharSequenceExtra("message").toString(); text1.setText(message); } public void onClickBackButton(View view) { Intent returnIntent = new Intent(); // (2) returnIntent.putExtra("reverse", reverse(message)); // (3) if (message.length() > 0) { setResult(RESULT_OK, returnIntent); // (4) } else { setResult(RESULT_FIRST_USER + NO_WORDS, returnIntent); // (5) } finish(); // (6) } /** * 文字列を逆並び順にした文字列を返す。 * @param s 文字列 * @return 逆並び順にした文字列 */ private String reverse(String s) { return new StringBuilder(s).reverse().toString(); } } --- (1) 文字列が空のときの結果コード public static final int NO_WORDS = 0; // (1) (2)(3) 戻すためのデータを設定する そのためのインテント・オブジェクトを生成する。 Intent returnIntent = new Intent(); // (2) インテントにデータを設定する。このとき、逆並び順の文字列を作る。 returnIntent.putExtra("reverse", reverse(message)); // (3) (4) 空の文字列でなければ、結果コード RESULT_OK とする setResult(RESULT_OK, returnIntent); // (4) (5) 空の文字列のとき、その旨の結果コードを指定する setResult(RESULT_FIRST_USER + NO_WORDS, returnIntent); // (5) (6) アクティビティを終わる finish(); // (6) ▲ レイアウト 呼び出し元のアクティビティに戻るボタンをつけた。 □ res/layout/other.xml --- <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/otherTextView1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" android:textAppearance="?android:attr/textAppearanceLarge" /> <Button android:id="@+id/backButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="onClickBackButton" android:text="@string/backButtonLabel" /> </LinearLayout> --- ■ マニュフェスト ※前回のプロジェクトと同じ ■ リソース □ res/values/strings.xml --- <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Intent02</string> <string name="implicitButtonLabel">逆並び順文字列を作る</string> <string name="backButtonLabel">確認</string> <string name="noWordsMessage">単語が指定されていません。</string> </resources> --- 以上