Intent
アプリを作成していくと、別画面に遷移させたいとか、他アプリのイベントを拾いたいとか、電話機能と連携したい等、外部との接点が欲しくなってきます。今回はそういった場合に使用されるIntentについて少し見ていきたいと思います。
・Intentの目的
他のアプリやデバイス(カメラや加速度センサ等)から情報を得ようとすると、プロセスやスレッドを跨いだ処理を考慮しなくてはならず、これが非常にめんどくさいです。このやりとりを簡単に実現するために登場したのがIntentで、ブラウザ立ち上げたとか、コール中といった情報をintentで通知する、いわゆるeventのような位置付けになります。
・明示的Intent、暗黙的Intent
Intentを作成する時には大きく分けて二通りの方法があります。一つは直接クラスを指定して呼び出す方法で、これを明示的Intentといいます。もう一つはこうして欲しいという「意図」をIntentに情報として付与し、システムに誰に処理してもらうかを決めてもらうやり方で、これを暗黙的Intentといいます。また、電話機能から「今電話かかってきたけど何かする?」という暗黙的Intentやシステムから「今起動したけど何かする?」というIntentが送付されてきます。これらのIntentを処理する際に必要になるのが次のIntent-filterです。
・Intent-filter
外部からのIntentを処理するかどうかはAndroidManifest.xmlのIntent-filterにて宣言します。例えばhelloworldのAndroidManifest.xmlを見てみます。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="jp.demo.helloworld" android:versionCode="1" android:versionName="1.0.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".helloworld" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
9~12行目に以下のようなintent-filterが設定されているのが分かります。
<intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
まず、「android.intent.action.MAIN」ですが、これはactionタグの親のactivityが、このアプリケーションのエントリーポイント、開始画面として設定されていることを表します。ランチャーからアプリケーションを起動して、一番最初に表示されるわけです。ランチャーを叩くと、ACTIONが「ACTION_MAIN」であるIntentがアプリケーションに対して投げられ、それを処理できる「android.intent.action.MAIN」のintent-filterを持つactivityがintentを受理し、画面が起動するという流れになるのだと思います。
次に「android.intent.category.LAUNCHER」ですが、categoryというのはactionを受理する際に付加的な情報を付け加えます。ここでのcategoryは「LAUNCHER」ですが、minghaiの日記さんによると、
デフォルトのIntentFilterの意味するところはランチャー向けのアプリケーションだということだ。
CATEGORYのLAUNCHERはシステムのLAUNCHERに登録できることを示す。
とのことです。
・startActivity()とstartActivityForResult()
同一アプリにおいて、別の画面を呼び出すときは明示的Intentを作成し、startActivity()の引数として引き渡します。
例えば以下のように書けます。
Intent intent = new Intent(helloworld.this,XXXXX.class); intent.setAction(Intent.ACTION_VIEW); startActivity(intent);
コンストラクタで自分自身、そして呼び出し先(XXXXX.class)のクラスを指定します。ACTIONにはActivityを表示させるのでACTION_VIEWを指定しています。当然ですね。
これで明示的なIntentの送付完了です。ただし、このstartActivity()では、遷移先のActivityから情報を引き取れません。情報を返して欲しいときはstartActivityForResult()を使うと良いでしょう。