X

Intentで情報を伝える

AndroidではIntentを使ってさまざまな情報をActivityに伝えることができます。ここではMainActivityからSubActivityへ文字列(”TechBooster”)を送ってみましょう。一時的な情報であればアプリケーション全体で共有するような不容易なシングルトンを利用する必要はありません。Intentでシンプルに伝えることができます。


この記事で紹介しているサンプルコードのリポジトリは次のとおりです。

  • https://github.com/TechBooster/AndroidSamples

Intentに設定できるデータ形式のリストなど詳細な解説は続きからどうぞ。


はじめにアクティビティを追加するためAndroidManifest.xmlにMainActivity、SubActivityの2つを登録します。

■AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.techbooster.sample.intentactivity">
    <application android:allowBackup="true" android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".SubActivity"
            android:theme="@style/AppTheme.NoActionBar">
        </activity>
    </application>
</manifest>

MainActivity、SubActivity、2つのActivity要素がマニフェストに登録されていることを確認します。どちらもname属性の先頭にドット”.”が付いていることに注意してください。。

MainActivityからIntentを送る

■src/MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, SubActivity.class);
                intent.putExtra("Name","TechBooster");
                startActivity(intent);
            }
        });
    }
}

Intentは第1引数に呼び出し元のコンテキスト、第2引数に呼び出し先のクラス(SubActivity)を指定します。
サンプルではputExtraメソッドを使い、文字列を格納しています。startActivityメソッドを実行することで、SubActivityを呼び出します。

SubActivityでIntentを受け取る

■src/SubActivity.java

public class SubActivity extends AppCompatActivity {
    ...省略...
    @Override
    protected void onResume() {
        super.onResume();

        TextView tv = (TextView) findViewById(R.id.text);
        Intent i = getIntent();
        String name = i.getStringExtra("Name");
        tv.setText("Welcome " + name);
    }
}

getIntentメソッドでIntentを受け取り、getStringExtraメソッドを利用して文字列を取り出します。ここでは、TextViewをつかい、画面に表示しています。

次のテーブルは、putExtra/getXxxxExtraメソッドで利用できるデータ形式の一覧です。

Intentで送受信できるデータ形式

データ種類 メソッド名
boolean getBooleanExtra(String name, boolean defaultValue)
boolean[] getBooleanArrayExtra(String name)
byte getByteExtra(String name, byte defaultValue)
byte[] getByteArrayExtra(String name)
char getCharExtra(String name, char defaultValue)
char[] getCharArrayExtra(String name)
CharSequence getCharSequenceExtra(String name)
CharSequence[] getCharSequenceArrayExtra(String name)
ArrayList getCharSequenceArrayListExtra(String name)
double getDoubleExtra(String name, double defaultValue)
double[] getDoubleArrayExtra(String name)
Bandle getBundleExtra(String name)
float getFloatExtra(String name, float defaultValue)
float[] getFloatArrayExtra(String name)
int getIntExtra(String name, int defaultValue)
int[] getIntArrayExtra(String name)
ArrayList getIntegerArrayListExtra(String name)
long getLongExtra(String name, long defaultValue)
long[] getLongArrayExtra(String name)
T getParcelableExtra(String name)
Parcelable[] getParcelableArrayExtra(String name)
ArrayList getParcelableArrayListExtra(String name)
Serializable getSerializableExtra(String name)
short getShortExtra(String name, short defaultValue)
short[] getShortArrayExtra(String name)
String getStringExtra(String name)
String[] getStringArrayExtra(String name)
ArrayList getStringArrayListExtra(String name)

多くのデータ形式をサポートしていますが、BundleやSerializeなど汎用的な形式もあり、複雑なデータであっても送受信が可能です。シリアライズの送受信についてはこちらでも解説していますが、オブジェクトのフィールドはプリミティブ型(intやboolean)か、もしくはシリアライズ可能なクラスであることがシリアライズの条件です。

実際にIntentを使う場合は、Intentのデータの有無や利用済みのKeyを削除するなど細かいエラー制御も必要になってきますが、ここでは簡単な例を紹介します。

    @Override
    protected void onResume() {
        super.onResume();
        TextView tv = (TextView) findViewById(R.id.text);
        Intent i = getIntent();

        if (i != null) {
            String name = i.getStringExtra("Name");
            tv.setText("Welcome " + name);

            i.removeExtra("Name");

            // 一覧の取得例
            Set<String> keys = i.getExtras().keySet();
            for (String key : keys) {
                // key list
            }
        }
    }

このサンプルでは利用済みのNameを削除して、何度も同じIntentを利用しないようにしています。ちょっとしたことですが次回遷移時にIntentが残っている場合もあるので2重で処理をしたくない場合は処理後に削除しておくことをおすすめします。
またIntentクラスのgetExtrasメソッドを使えばKeyの一覧も取り出せます。入っているデータの確認に利用できます。

以上、おつかれさまでした。

mhidaka: Software Engineerだよ。DroidKaigi Organizer / Androidと組込とRe:VIEW。techbooster主宰。mhidaka's writings http://booklog.jp/users/mhidaka 技術書典! http://techbookfest.org
Related Post