🍎

【Android開発】 明示的インテントを使っての画面遷移とActivity間のデータ転送

2021/01/04に公開

今回作るアプリ

明示的インテントを使って画面遷移を行います。
また遷移するときにデータの受け渡しをします。

サンプルアプリの構成は下記になります。
MainActtivityとSecondActivity、2つのActivityを含むアプリを作成します。
MainActtivityには編集テキストと送信ボタンが含まれています。
ユーザーはメッセージを入力して送信ボタンをクリックします。
MainActtivityはインテントを使用してSecondActivityを開始し、MainActtivityで入力したメッセージをSecondActivityに送信します。
SecondActivityでは受信したメッセージが表示されます。

動作環境

Android Studio4.1
windows10

実装手順

プロジェクト構成

以下の内容でプロジェクトを作ります。
名前:IntentActivity
言語:Java
最小SDK:API19

サンプルコード

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/editText_main"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginEnd="16dp"
        android:ems="10"
        android:inputType="text"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/btn_main"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:onClick="goSecondActivity"
        android:text="Go Second"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/editText_main"
        app:layout_constraintTop_toTopOf="@+id/editText_main" />

</androidx.constraintlayout.widget.ConstraintLayout>

Button#onClick属性のgoSecondActivity()メソッドはまだ実装していないため、赤の下線が引かれています。
「goSecondActivity」をクリックしてAlt+Enterを押し、「作成 'goSecondActivity(View)' in 'MainActivity'」を選択します。
MainActivity.javaにgoSecondActivity()メソッドが生成します。

SecondActivityを作成します。
プロジェクトのアプリフォルダをクリックし、ファイル > 新規作成 > アクティビティ > 空のアクティビティを選択します。
アクティビティ名を「SecondActivity」にしてGenerate a Layout Fileのチェックを入れた状態で完了をクリックします。
「SecondActivity.java」と「activity_second.xml」が生成されます。

またAndroidManifest.xmlにSecondActivityが追加されていることを確認します。

AndroidManifest.xml
<activity android:name=".SecondActivity"></activity>

SecondActivityのレイアウトを作ります。

activity_second.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondActivity">

    <TextView
        android:id="@+id/title_second_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:text="Message from Main Activity"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/message_from_main_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/title_second_activity" />

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivityに明示的インテントを追加します。
このインテントはボタンをクリックしたときにSecondActivityに遷移します。
以下のようにMainActivity.javaに明示的インテントを追加します。

MainActivity.java
public class MainActivity extends AppCompatActivity {

    // インテントエクストラの公開キー
    // 接頭辞としてアプリのパッケージ名を含める
    public static final String EXTRA_MAIN_MESSAGE =
        "com.example.intentactivity.EXTRA_MAIN_MESSAGE";

    private EditText mEditText_main;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mEditText_main = findViewById(R.id.editText_main);
    }


    public void goSecondActivity(View view) {

        // 入力した文字列を取得
        String message = mEditText_main.getText().toString();

        /*
          インテントコンストラクタ
          第1引数 呼び出し元のコンテキスト
          第2引数 呼び出し先のクラスを指定
         */
        Intent intent = new Intent(this, SecondActivity.class);

        // データを渡す設定
        intent.putExtra(EXTRA_MAIN_MESSAGE, message);

        // SecondActivityを呼び出す
        startActivity(intent);
    }
}

SecondActivityでインテントを受け取り、受け取ったデータを画面に表示します。

SecondActivity.java

private TextView mMessageFromMainActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_second);

    // メインアクティビティからのインテントを受け取る
    Intent intent = getIntent();

    // メインアクティビティからのメッセージを取得
    String message = intent.getStringExtra(MainActivity.EXTRA_MAIN_MESSAGE);

    mMessageFromMainActivity = findViewById(R.id.message_from_main_activity);

    mMessageFromMainActivity.setText(message);
}

アプリを実行します。MainActivityにメッセージを入力してボタンをクリックすると、SecondActivityが起動してメッセージが表示されます。

SecondActivityからMainActivityへデータを渡す

最後にSecondActivityからMainActivityへデータを渡すようにアプリを変更します。

最初に使用する文字列をstrings.xmlに定義しておきましょう。

strings.xml
<resources>
    <string name="app_name">IntentActivity</string>
    <string name="message_from_second_activity">Message from Second Activity</string>
    <string name="message_from_main_activity">Message from Main Activity</string>
    <string name="go_main">Go Main</string>
    <string name="go_second">Go Second</string>
</resources>

activity_second.xmlにEditTextとButton要素を追加して以下のように変更します。

activity_second.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SecondActivity">

    <TextView
        android:id="@+id/title_second_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:text="@string/message_from_main_activity"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/message_from_main_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/title_second_activity" />

    <EditText
        android:id="@+id/editText_second"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="64dp"
        android:layout_marginEnd="16dp"
        android:ems="10"
        android:inputType="text"
        app:layout_constraintEnd_toStartOf="@id/btn_main"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/message_from_main_activity" />

    <Button
        android:id="@+id/btn_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:onClick="goMainActivity"
        android:text="@string/go_main"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/editText_second"
        app:layout_constraintTop_toTopOf="@+id/editText_second" />

</androidx.constraintlayout.widget.ConstraintLayout>

Button#onClick属性のgoMainActivity()メソッドはまだ実装していないため、赤の下線が引かれています。
「goMainActivity」をクリックしてAlt+Enterを押し、「作成 'goMainActivity(View)' in 'SecondActivity'」を選択します。
SecondActivity.javaにgoMainActivity()メソッドが生成します。

SecondActivity.javaを以下のように変更します。

SecondActivity.java
public class SecondActivity extends AppCompatActivity {

    // インテントエクストラの公開キー
    // 接頭辞としてアプリのパッケージ名を含める
    public static final String EXTRA_SECOND_MESSAGE =
        "com.example.intent.EXTRA_SECOND_MESSAGE";

    private TextView mMessageFromMainActivity;

    private EditText mEditTextSecond;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        mEditTextSecond = findViewById(R.id.editText_second);

        // メインアクティビティからのインテントを受け取る
        Intent intent = getIntent();

        // メインアクティビティからのメッセージを取得
        String message = intent.getStringExtra(MainActivity.EXTRA_MAIN_MESSAGE);

        mMessageFromMainActivity = findViewById(R.id.message_from_main_activity);

        mMessageFromMainActivity.setText(message);
    }

    public void goMainActivity(View view) {
        String message = mEditTextSecond.getText().toString();

        // レスポンス用の新しいインテントを作成する
        Intent intent = new Intent();

        // EditTextから取得したデータをエクストラとしてインテントに追加
        // キーと値のペアを指定する
        intent.putExtra(EXTRA_SECOND_MESSAGE, message);

        // 結果コードとデータをセットする
        setResult(RESULT_OK, intent);

        // アクティビティを閉じてMainActivityに戻る
        finish();
    }
}

MainActivityをSecondActivityから渡されたデータを受け取れるように変更します。
activity_main.xmlを以下のように変更します。

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/title_main_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:text="@string/message_from_second_activity"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        android:textStyle="bold"
        android:visibility="invisible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/message_from_second_activity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:visibility="invisible"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/title_main_activity" />

    <EditText
        android:id="@+id/editText_main"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginTop="64dp"
        android:layout_marginEnd="16dp"
        android:ems="10"
        android:inputType="text"
        app:layout_constraintEnd_toStartOf="@id/btn_main"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/message_from_second_activity" />

    <Button
        android:id="@+id/btn_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="16dp"
        android:onClick="goSecondActivity"
        android:text="@string/go_second"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/editText_main"
        app:layout_constraintTop_toTopOf="@+id/editText_main" />

</androidx.constraintlayout.widget.ConstraintLayout>

追加したTextViewにはandroid:visibility属性を追加して、最初は見えないようにします。
起動直後は何も表示しないためです。これらの要素はSecondActivityからデータを渡された後に表示します。
TextViewは不可視に設定しているため画面には表示されません。

MainActivity.javaを以下のように変更します。

MainActivity.java
public class MainActivity extends AppCompatActivity {

    // インテントエクストラの公開キー
    // 接頭辞としてアプリのパッケージ名を含める
    public static final String EXTRA_MAIN_MESSAGE =
        "com.example.intentactivity.EXTRA_MAIN_MESSAGE";

    // 遷移先のアクティビティを判別するための要求コード
    // 任意の整数で指定
    private static final int REQUEST_CODE = 1;

    private TextView mTitleMainActivity;
    private TextView mMessageFromSecondActivity;

    private EditText mEditText_main;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mEditText_main = findViewById(R.id.editText_main);
        mTitleMainActivity = findViewById(R.id.title_main_activity);
        mMessageFromSecondActivity = findViewById(R.id.message_from_second_activity);
    }


    public void goSecondActivity(View view) {

        // 入力した文字列を取得
        String message = mEditText_main.getText().toString();

        /*
          インテントコンストラクタ
          第1引数 呼び出し元のコンテキスト
          第2引数 呼び出し先のクラスを指定
         */
        Intent intent = new Intent(this, SecondActivity.class);

        // データを渡す設定
        intent.putExtra(EXTRA_MAIN_MESSAGE, message);

        // 遷移先のアクティビティから結果を受け取るため、startActivity()からstartActivityForResult()に変更
        startActivityForResult(intent, REQUEST_CODE);
    }

    /**
     * startActivityForResultメソッドで起動された Activity が終了すると、
     * onActivityResultメソッドが呼び出されます。
     *
     * @param requestCode
     *  startActivityForResult()で指定した要求コード。どこのアクティビティから戻ってきたのかを判別する
     *
     * @param resultCode
     *  呼び出し元のアクティビティに戻ってくる前にどのような処理が行われたのか判別する
     *
     * @param data
     *  呼び出し元のIntentデータ
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE) {
            // SecondActivityから戻ってきた処理
            if (resultCode == RESULT_OK) {
                // SecondActivityのボタンを押して戻ってきたときの処理

                // TextView要素を可視化
                mTitleMainActivity.setVisibility(View.VISIBLE);

                // SecondActivityのインテントからデータを取得
                // ExtraのキーはSecondActivityの公開キーになります
                String message = data.getStringExtra(SecondActivity.EXTRA_SECOND_MESSAGE);

                // 取得したデータをtextviewにセット
                mMessageFromSecondActivity.setText(message);

                // TextView要素を可視化
                mMessageFromSecondActivity.setVisibility(View.VISIBLE);
            }
        }
    }
}

これでSecondActivityからのデータをMainActivityで受け取って表示することができました。

Discussion