2012年4月4日水曜日

Activityの呼び出し(2)

アクティビティを呼び出すにはstartActivity()メソッドを使いました。これは単純にアクティビティを呼び出すだけのものでした。
呼び出した先のアクティビティが終了した状況、例えば一通りの処理が完了して終了したのか、キャンセルして終了したのかを知りたい時は、startActivityForResult()メソッドを使います。

ActivityTest2aActivity.java
package jp.co.triware.samples.ActivityTest2a;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class ActivityTest2aActivity extends Activity {
    private static final String TAG = "MainActivity";

    private static final int REQUEST_SUB_ACTIVITY = 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button btnOpen = (Button)findViewById(R.id.open_btn);
        btnOpen.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "OPEN button clicked!");
                Intent intent = new Intent();
                intent.setClass(getApplicationContext(), SubActivity.class);
                startActivityForResult(intent, REQUEST_SUB_ACTIVITY);
                Log.d(TAG, "after startActivityForResult()");
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_SUB_ACTIVITY) {
            String buf = "Unknown";
            switch (resultCode) {
            case RESULT_OK:
                buf = "OK";
                break;
            case RESULT_CANCELED:
                buf = "Cancel";
                break;
            default:
                break;
            }
            Log.d(TAG, "onActivityResult: " + buf);
            Toast.makeText(getApplicationContext(), buf, Toast.LENGTH_LONG).show();
        }
    }
}

onActivityResult()は、呼び出し先のアクティビティが終了すると呼び出されます。startActivityForResult()の第2引数で指定したリクエストコードがonActivityResult()の第1引数のrequestCodeに入っていますので、どのアクティビティから戻ってきたのか判別できます。そして第2引数のresultCodeに戻り値が入っています。第3引数についてはまた別の機会に。

前回のstartActivity()も同様なのですが、startActivity()やstartActivityForResult()は別アクティビティを呼び出して、それが終了するまで待つのではなく、そのまま次の処理に移ります。
ボタンをクリックして、"after startActivityForResult()"のログが出力されることを確認してみてください。

SubActivity.java
package jp.co.triware.samples.ActivityTest2a;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class SubActivity extends Activity {
    private static final String TAG = "SubActivity";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sub);

        Button btnOK = (Button)findViewById(R.id.ok_btn);
        btnOK.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "OK button clicked!");
                setResult(RESULT_OK);
                finish();
                Log.d(TAG, "OK: finished!");
            }
        });

        Button btnCancel = (Button)findViewById(R.id.cancel_btn);
        btnCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "Cancel button clicked!");
                setResult(RESULT_CANCELED);
                finish();
                Log.d(TAG, "Cancel: finished!");
            }
        });

        Button btnUndef = (Button)findViewById(R.id.undefine_btn);
        btnUndef.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d(TAG, "Undefine button clicked!");
                // setResult()を呼ばない
                finish();
                Log.d(TAG, "Undefine: finished!");
            }
        });
    }
}
SubActivityには、3種類のボタンを用意しました。「OK」ボタンは戻り値にRESULT_OKを、「Cancel」ボタンはRESULT_CANCELEDを、setResult()メソッドを使ってセットします。「Undefine」ボタンには戻り値をセットしない場合はどうなるかを確認するため、setResult()を呼び出していません。

RESULT_OKやRESULT_CANCELEDはActivityクラスで宣言されています。これら以外の戻り値を返したい場合は、RESULT_FIRST_USERから始まる数値を定義して使います。

(Activity.classより)
public static final int RESULT_CANCELED = 0;
public static final int RESULT_OK = -1;
public static final int RESULT_FIRST_USER = 1;

ところで、前回の記事では、finish()は「自アクティビティを終了するためのメソッド」としか説明しませんでしたが、実はfinish()を呼び出してもすぐにアクティビティが終了するわけではありません。「アクティビティ終了宣言!」のようなもので、プログラムの流れとしてはこのあとまだ処理は続きます。ボタンをクリックすると、finish()メソッドを呼び出した後の"finished!"のログが出てきますので、確認してみてください。

プロジェクトの設定とXMLレイアウトファイルは次の通りです。

Androidプロジェクトの設定
プロジェクト名:ActivityTest2a
アプリケーション名:ActivityTest2a
パッケージ名:jp.co.triware.samples.ActivityTest2a
アクティビティーの作成:ActivityTest2aActivity
ビルドターゲットや最小SDKバージョンは、お使いの開発環境に合わせて設定してください。

main.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"
    android:gravity="center"
    >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:text="Main Activity"
        />
    <Button
        android:id="@+id/open_btn"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:text="OPEN"
        />
</LinearLayout>

sub.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"
    android:gravity="center"
    >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:text="Sub Activity"
        />
    <Button
        android:id="@+id/ok_btn"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:text="OK"
        />
    <Button
        android:id="@+id/cancel_btn"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:text="Cancel"
        />
    <Button
        android:id="@+id/undefine_btn"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:text="Undefine"
        />
</LinearLayout>

忘れずにマニフェストファイルも変更します。

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="jp.co.triware.samples.ActivityTest2a"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="7" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".ActivityTest2aActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name=".SubActivity" />
    </application>

</manifest>

実行結果
「OPEN」でSubActivityを呼び出します。

まず、「OK」をクリックすると・・・

MainActivityに戻って、「OK」をトースト表示します。onActivityResult()で、ちゃんとRESULT_OKが認識できました。

このときのログは、
D/MainActivity(284): OPEN button clicked!
D/MainActivity(284): after startActivityForResult()
D/SubActivity(284): OK button clicked!
D/SubActivity(284): OK: finished!
D/MainActivity(284): onActivityResult: OK
finish()の後のログも出力されています。

次は「Cancel」です。
D/SubActivity(284): Cancel button clicked!
D/SubActivity(284): Cancel: finished!
D/MainActivity(284): onActivityResult: Cancel
onActivityResultで戻り値がRESULT_CANCELEDと認識できました。

最後はUndefineです。
D/SubActivity(284): Undefine button clicked!
D/SubActivity(284): Undefine: finished!
D/MainActivity(284): onActivityResult: Cancel
キャンセル扱いになりましたね。あと、Backキーを押すとどうなるかもぜひ試してみてください。


次回は、呼び出し先のアクティビティに値を渡すサンプルを作ります。

0 件のコメント:

コメントを投稿