marunomaruno-memo

marunomaruno-memo

[Android] インテント (2) - アクティビティからの結果の受け取り

2012年03月09日 | Android
[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>
---

                                                                            以上