魔術師見習いのノート

プロフィール

魔術師見習い
Author魔術師見習い-_-.
Twitter魔術師見習い

コンピュータ関係のメモを主に書きます.

MENU

Androidアプリ サブアクティビティ

投稿日:
タグ:

目次

ADTでプロジェクトを新たに作った時,デフォルトで1つのアクティビティが生成される.しかし,本格的なプログラムではいくつかのアクティビティを使用する.例えばスタート画面や設定画面,プレイ画面などがある.本稿では,複数のアクティビティを作り方のメモである.

アクティビティを追加するには次の3つのことを行わなければならない.

3つ目についてはなくても可能である.また,2つ目についてはファイルを分ける必要はない.しかし,本稿ではアクティビティ毎にファイルを分ける方針を取る.

アクティビティの追加

レイアウトファイルの生成

レイアウトの生成は次のような手順で行う.

  1. [File]を選択.
  2. [New]を選択.
  3. [Android XML File]を選択
  4. レイアウト名を指定.
  5. レイアウトの種類を指定.
  6. [Next >]を選択.
  7. [Finish]を選択.
本稿では,レイアウトの種類は"RelativeLayout"を選択する.また,レイアウト名にはactivity_sub.xmlと付ける.

レイアウトの編集については,ここでは言及しない.

新たなアクティビティの生成

クラスの追加は次のようにして行うことができる.

  1. [File]を選択.
  2. [New]を選択.
  3. [Class]を選択.
  4. クラス名を指定.
  5. スーパクラスをandroid.app.Activityに指定.
本稿ではクラス名にSubActivityという名前を使用する.

出来上がったソースコードには,次のようなコードを追加する必要がある.

public class SubActivity extends android.app.Activity {
        @Override
        protected void onCreate(android.os.Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_sub)
	}
}
setContentView()で指定するidには,新たに生成したレイアウトのものを使用する.

AndroidManifest.xmlへのアクティビティの登録

AndroidManifest.xmlへの登録もレイアウトと同様GUIで編集できる.手順は次の通りである.

  1. [Application]タブを選択.
  2. "Application Nodes"の[Add]を選択.
  3. "Activity"を選んで[OK]を選択.
  4. "Attributes for Activity"の"Name"を指定.
もちろんXMLファイルを直接書き換えても良い.なお,AndroidManifest.xmlの設定を忘れてもコンパイルは支障がなく行えるが,実行中にエラー終了する.


アクティビティの起動

アクティビティから別のアクティビティを実行するには,android.content.Intentを使用する.起動するアクティビティにデータを与えない場合,startActivity()を使用すれば良い.

android.content.Intent intent = new android.content.Intent(MainActivity.this, SubActivity.class);
startActivity(intent);

また,アクティビティの終了にはfinish()を使用する.

SubActivity.this.finish();
呼び出し先のアクティビティが終了すると,呼び出し元のアクティビティに制御が戻る.

データの受け渡し
呼び出し元アクティビティのデータ渡し

呼び出し先のアクティビティにデータを渡す時,startActivity()の代わりにstartActivityForResult()を使用する.そして,データを渡すにはputExtra()を使用する.putExtraは第1引数で指定した名前を鍵として,データを呼び出し先のアクティビティに渡す.また,第2引数はさまざまな型のものがある.

android.content.Intent intent = new android.content.Intent(MainActivity.this, SubActivity.class);
int i = 10;
intent.putExtra("integer", i);
startActivityForResult(intent, 0x01);

呼び出し先アクティビティのデータ受け取り

データを受け取るにはgetIntent()でandroid.content.Intentのデータを初期化する.そして,getExtra系の関数でデータを受け取ることができる.getExtra系の関数は"get + 型名 + Extra"の名前からなる.

android.content.Intent intent = getIntent();
int i = intent.getIntExtra("integer");
i *= 2;

呼び出し先アクティビティのデータ返却(渡し)

結果を呼び出し元返すには,setResult()で結果のタイプとandroid.app.Activityのインスタンスを指定する.

intent.putExtra("integer", i);
setResult(android.app.Activity.RESULT_OK, intent);
finish();

呼び出し元アクティビティのデータ受け取り

アクティビティを制御が戻った際に,onActivityResult()が呼び出される.onActivityResult()は,第1引数で呼び出し時にstartActivityForResult()で指定したアクティビティの識別コード,第2引数で結果のタイプ(呼び出し先アクティビティがsetResult()で指定した値),第3引数でandroid.content.Intentを受け取ることができる.

        @Override
        protected void onActivityResult(int request_code, int
	result_code, android.content.Intent sub)
        {
                int i;
                if (request_code==0x01 && result_code==MainActivity.this.RESULT_OK){
			i = sub.getIntExtra("integer");
                }
        }
第1引数と第2引数の値を判別した後は,呼び出し先アクティビティのデータ受け取り同様getExtra系の関数を使用する.

別のアプリの呼び出し

android.content.Intentはユーザが作成したアクティビティ以外にも別のアプリのアクティビティなどを起動できる.例えば別のアプリで画像を選択させたいような場合,次のようにアクティビティを起動する.

android.content.Intent intent = new android.content.Intent(android.content.Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 0x02);

このサンプルでは,intent初期化にandroid.content.Intent.ACTION_GET_CONTENTを与えているが,他にもいろいろなタイプがある.ただし,本稿ではこれ以上言及しない.

選択した画像のパスを取得する例を以下に示す.

        private String path;

	@Override
	protected void onActivityResult(int request_code, int result_code, android.content.Intent sub)
	{
		super.onActivityResult(request_code, result_code, sub);
		if (request_code==0x02 & result_code==android.app.Activity.RESULT_OK){
			android.content.ContentResolver cr = MainActivity.this.getContentResolver();
			android.database.Cursor c = cr.query(sub.getData(), new String[]{MediaStore.Images.Media.DATA}, null, null, null);
			if (c!=null){
				c.moveToFirst();
				path = c.getString(0);
				c.close();
			}

		}
	}
単純にパスを取得するにはgetData()とgetPathを使うだけで良い.
path = data.getData().getPath();
しかし,これによって取得できるのはURIと呼ばれるパスである.一部の関数はそれだと都合が悪いので,本稿ではそれをディレクトリ階層のパスに変更する例を紹介した.

一覧