世界を目指せ!Androidアプリ開発入門

第5回アクティビティの制御と明示的インテント

今回は、複数のアクティビティの制御と明示的インテントの基礎について解説します。

前回のおさらいと今回のポイント

前回は、アクティビティの動作に関して学びました。具体的には、

  • 画面のようなもの
  • 複数の遷移状態を持っている
  • の遷移状態を理解した上で、アプリのリソース管理を行う

と言った説明をしました。今回は、

  • 複数のアクティビティの制御
  • 明示的インテントの基礎

について解説します。

インテントには、自身のアクティビティを操作する「明示的インテント」と、ブロードキャストメッセージのような「暗黙的インテント」が存在します。今回ご紹介するのは、基本的な明示的インテントの操作ですが、本格的なアプリでも変わらず、今後のアプリ開発に繋がるので、今回紹介するサンプルに手を加えて試行錯誤するなど、自分のものにしてください。

さて、このインテント、あまり聞き慣れない言葉ですが、他のOSには、似た仕組みがなくAndroid OS特有の機構です。技術者としては、他にはない仕組みや考えに触れるのは良い刺激になり、自身の幅を広げることができるはずなので、本格的なアプリの開発予定がなくても、この仕組みを勉強してみることをお勧めします。

主画面から副画面へ遷移するアプリ

では、以下の手順で、前回のサンプルアプリを複数アクティビティを扱うアプリに修正してみます。

  1. 副画面の準備
  2. ソースコードの準備
  3. AndroidMnifiest.xmlへの準備
  4. 動作テスト

アプリの動きは、主画面のボタンを押すと副画面に遷移するものになります。

副画面の準備

まずは、副画面の用意をします。

Androidの画面は、XMLで表現されているのでテキストエディタでも記述できますが、今回はEclipseに内蔵されているリソースエディタを使います。

[ファイル]メニューの[新規][その他]を選択します。

新規ダイアログが表示されたら[Android]から[Android XML File]を選択して、⁠次へ]をクリックします。

ダイアログが表示されたら、画面1のように設定します。

図1 画面リソースを準備している様子。直接XMLファイルを作成することも可能だが、GUIをで作成することも可能。
図1 画面リソースを準備している様子。直接XMLファイルを作成することも可能だが、GUIをで作成することも可能。

設定値は、以下になります。

File	skeleton_sub_activity.xml
Layoutを選択

[Available Qualifiers]から以下を選択して[Chosen Qualifiers]に移動します。

SizeNormal
RaitoNotLong
OrientationPortrait
PixelDensityMediumDensity
TouchScreenFinger
KeyboardSoft
TextInputQwerty
NavigationTrackball
Dimension480×320
Select the root element for the XML fileは、LinearLayoutを選択します。

Folderが「/res/layout-normal-notlong-port-mdpi-stylus-keyssoft-qwerty-trackball-480x320」となっていますが、気にせず[終了]をクリックします。すると、パッケージの「res」フォルダ以下に「layout-normal-notlong-port-mdpi-stylus-keyssoft-qwerty-trackball-480x320」がフォルダ作成され「skeleton_sub_activity.xml」が格納されます。

「skeleton_sub_activity.xml」「layout」フォルダへドラッグで移動して「layout-normal-notlong-port-mdpi-stylus-keyssoft-qwerty-trackball-480x320」フォルダは削除します。

図2 ⁠res/layout」フォルダ以下に、作成したskeleton_sub_activity.xmlが追加された。
図2 「res/layout」フォルダ以下に、作成したskeleton_sub_activity.xmlが追加された。

「skeleton_sub_activity.xml」をダブルクリックして編集画面を表示します。

編集画面に、図3のように、アウトラインパネルとプロパティパネルが表示されていることを確認してください。アウトラインパネルが表示されてなければ[ウインドウ]メニューの[ビューの表示]からアウトラインを選択します。プロパティパネルも同様に[ウインドウ]メニューの[ビューの表示]から[その他...]を選択します。⁠ビューの表示]ダイアログから[一般]から[プロパティ]を選択して[OK]をクリックします。

図3 筆者の場合は、画面に右側にアウトライン、プロパティーパネルを配置して使っている。
図3 筆者の場合は、画面に右側にアウトライン、プロパティーパネルを配置して使っている。

まずは、ビューのレイアウト方法を決定します。

アウトラインパネルの[LinearLayout]を選択して、プロパティパネルの[Orientation][vertical]に設定します。次に、コントロールを配置して行きます。

[Views]から[EditText]を選択して、ドラッグしてビューに配置します。同じく[Button]を選択して、ドラッグしてビューに配置します。

ビューの[Orientation][vertical]に設定しているので、それぞれのオブジェクトが縦に並ぶはずです。

図4 コントールを配置している様子。
図4 コントールを配置している様子。

ソースコードの準備

もう少し凝った画面にしたいのですが、ここではこれぐらいにして、次にソースコードを用意します。

[ファイル]メニューの[新規][クラス]を選択します。⁠新規Javaクラス]ダイアログが表示されたら、以下の値を入力して[終了]をクリックします。

図5 新しいクラスを作成する様子。
図5 新しいクラスを作成する様子。
パッケージcom.example.android.skeletonapp
名前SkeletonSubActivity
スーパークラスandroid.app.Activity

終了をクリックすると、ひな形のコードが生成されて、クラス名と同じ名前でプロジェクトの「src」フォルダにファイルが作成されます。

SkeletonSubActivity.javaをダブルクリックで開いて、以下のコードを追加します。

先で作成した画面リソースを使用するように、setContentViewの引数で、先で作成した画面リソースを指定しているところがポイントです。

SkeletonSubActivity.java
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // 画面の XML を指定する
    setContentView(R.layout.skeleton_sub_activity);
}

次に、主画面のコードも変更します。

バックボタンは、押すと終了するようになっていますが、動作を変更して、ボタンが押されたら副画面へ遷移するように、onClickのコードを変更します。

SkeletonActivity.java
OnClickListener mBackListener = new OnClickListener() {
    public void onClick(View v) {
        Intent intent = new Intent( SkeletonActivity.this, SkeletonSubActivity.class );
        startActivity( intent );
    }
};

ここで冒頭で説明した「明示的インテント」が登場します。

主画面から副画面に遷移する為に、startActivityを呼び出して、別のアクティビティを表示しています。

AndroidManifest.xmlの準備

Android OSは、画面リソースとソースコードの他にAndroidManifest.xmlに必要な記述を行う必要があります。

AndroidManifest.xmlには、アプリのアクティビティ等が、どのような挙動を行い、どのような情報を公開し、どのようなデータを処理し、どのようにしてそれらを起動するかという情報を記述・保持します。Androidマーケット経由で、アプリをインストールすると「このアプリケーションは、以下の情報にアクセスします」と表示されますが、あれは、このAndroidManifest.xmlに記述された内容を表示しています。これには、正しい記述を行わないと画面すら表示できないので注意してください。

プロジェクト直下にあるAndroidManifest.xmlをダブルクリックで開きます。

編集画面下のタブから[Application]を選択します。⁠Application Nodes]を見ると、既に[SkeletonActivity]が登録されているはずです。これに先で作成した[SkeletonSubActivity]を追加しています。⁠Add...]をクリックして、ダイアログが表示されたら[Activity]を選択して[OK]をクリックします。

図6 一覧にSkeletonSubActivityが追加されることを確認して下さい。
図6 一覧にSkeletonSubActivityが追加されることを確認して下さい。

[SkeletonActivity]が登録されていたリストに[Activity]が表示されています。

これを選択して、⁠Attributes for Activity][Name][Browse...]を選択して[SkeletonSubActivity]を選択して[OK]をクリックします。これで、このアプリが所有するアクティビティが2つになりました。

図7 インテントフィルターが設定されると、画面のような表示になる。
図7 インテントフィルターが設定されると、画面のような表示になる。

最後に、アクティビティが受け取るインテントを設定します。

[Application Nodes][Add..]をクリックして表示されたダイアログで「Intent Filter」を選択して[OK]をクリックします。⁠SkeletonSubActivity」「Intent Filter」が登録されていることを確認してください。次に、追加した「Intent Filter」を選択して、アクションを登録します。

[Add...]をクリックして表示されたダイアログで「Action」を選択して、⁠OK]をクリックします。前の画面に戻ったら[Attributes for Action][Name]「android.intent.action.MAIN」を選択します。

図8 主画面から副画面へ遷移した後の様子。
図8 主画面から副画面へ遷移した後の様子。

動作テスト

これで準備が完了です。では、エミュレータを使って動きを確認してみます。

Eclipseの[実行]メニューの[前回の起動を実行]でアプリを実行します。アプリが起動したら、⁠Back]ボタンをタップします。すると、新たに作成した副画面に遷移するはずです。副画面に遷移したら、エミュレータのバックキーを押してください。起動時の主画面に戻るはずです。

図9 起動時の主画面
図9 起動時の主画面

もう少し改造をしてみます

主画面から副画面へ移動は確認できたでしょうか?

もう少し手を加えて、主画面から副画面へ遷移するときに、データの引き渡しを行ってみます。インテントには、追加データを持たせることができるので、その仕組みを使って、主画面から副画面へ移動する際に、テキストを引き渡して、副画面のテキスト入力エリアへ表示を行います。

まずは、SkeletonActivity.javaのバックボタンが押された際のコードに、追加のデータを引き渡すコードを追加します。

SkeletonActivity.java

OnClickListener mBackListener = new OnClickListener() {
    public void onClick(View v) {
        //finish();
            
        Intent intent = new Intent( SkeletonActivity.this, SkeletonSubActivity.class );
        intent.putExtra( "INTENT_PARAM", "TEST" );
        startActivity( intent );
    }
};

intent.putExtraの部分が追加されたコードです。

第1引数がキーで、インテントが保持している追加データにアクセスするために使います。第2引数は、追加データになり、今回のケースはテキストです。

次にデータの受け側、SkeletonSubActivity.javaのonCreateにコードを追加します。

SkeletonSubActivity.java

@Override
public void onCreate(Bundle savedInstanceState) {
    String str;

super.onCreate(savedInstanceState);

    // 画面の XML を指定する
    setContentView(R.layout.skeleton_sub_activity);
        
    if(( savedInstanceState == null ) || ( savedInstanceState.isEmpty()) )
        {
            // インテントから追加データを取り出す
            str = getIntent().getExtras().getString( "INTENT_PARAM" );
        }
    else
        str = "";

    // 編集エリアに追加データを表示する。
    EditText edit = (EditText)findViewById( R.id.EditText01 );
        edit.setText( str );
}

主画面から渡された追加データのテキストは、以下のコードで取り出しています。

第1引数に、主画面で指定したキーが使われていることに注目してください。

str = getIntent().getExtras().getString( "INTENT_PARAM" );

取り出されたテキストデータは、以下のコードで画面に表示しています。

EditText edit = (EditText)findViewById( R.id.EditText01 );
edit.setText( str );

これで準備が完了です。

エミュレータを使って動きを確認してみます。Eclipseの[実行]メニューの[前回の起動を実行]でアプリを実行します。主画面から副画面に移動して、編集エリアに主画面から引き渡した追加データのテキストが表示されていることを確認してください。

図10 画面が遷移する際に、追加データを渡したので、編集エリアに「TEST」と表示されている。
図10 画面が遷移する際に、追加データを渡したので、編集エリアに「TEST」と表示されている。

今回は、そして次回は…

今回は、

  • 新しい画面を作成して表示。
  • 暗黙的インテントの基本的。
  • インテントに追加データを持たせる方法。

を解説しました。

新しい画面の作成は、慣れないと少々煩雑ですが、画面リソースやAndroidManifestは、XMLで表現されているので、2回目からは使い回しができ、簡単に作ることができるはずです。また、インテントに追加データの持たせ方は、基本的な方法で複数のデータやオブジェクトを引き渡す方法があるので、サンプルを修正するなどして、さまざまな方法を試してください。

次回は、画面周りのコントロールの使い方を紹介します。

おすすめ記事

記事・ニュース一覧