暗黙的インテントに設定するACTION_*
暗黙的インテントがアプリ内部から発行されると、そのアクションに対応できるアクティビティをもつアプリが選択されて、それが一つの場合は起動、複数の場合は選択ダイアログが表示される。
ACTION_*の種類
- ACTION_CALL
- ACTION_VIEW
- ACTION_SEND
- ACTION_SET_WALLPAPER
- ACTION_WEB_SEARCH
など多数の種類がある。
http://developer.android.com/intl/ja/reference/android/content/Intent.html
メーラを起動させる場合
Intent it = new Intent(); it.setAction(Intent.ACTION_SENDTO); it.setData(Uri.parse("mailto:hoge@hage.com")); it.putExtra(Intent.EXTRA_SUBJECT, "サンプルコードの件"); it.putExtra(intent.EXTRA_TEXT, "あけましておめでとうございます。"); startActivity(it);
メーラが、ACTION_SENDTO に対応できるアクティビティをもっていれば、そのメーラアプリが起動または選択肢の一つとして表示される。
ブラウザを起動させる場合
String text = inputText.getText().toString();
Uri url = Uri.parse(text);
Intent it = new Intent();
it.setAction(Intent.ACTION_VIEW);
it.setData(url);
startActivity(it);
ブラウザが、ACTION_VIEW に対応できるアクティビティをもっていれば、そのブラウザアプリが起動または選択肢の一つとして表示される。
起動されるアプリ側ではどんな記述をされているか。
「あなたは、ACTION_VIEWが暗黙的インテントで発行されたら反応しなさい。」
アプリから発行された「暗黙的インテント」のACTION_*の種類は、起動される(受け取る)アプリ内ではどう記述されているか。
AndroidManifest.xml
<activity android:name=".ReceiveApplication" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter android:label="@string/app_name"> <action android:name="android.intent.action.SEND" /> <data android:mimeType="text/plain" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
ACTION_SENDに対応して反応するように該当アクティビティにインテントフィルターを記述しておく。
また、受け取るインテントのアクション以外の情報
- Data
- Category
- Flags
- Extra
- Type
は、反応する/しないに関係してくるのだろう。
また、すでにインストールしているアプリがそれぞれ「どんな暗黙的インテントに対して反応するか」を調べてみようかと。
インテントフィルターの記述の例
思ったより記述が複雑な気がするので、どんな記述をしているのか集める。
http://www.techdoctranslator.com/android/guide/manifest/data-element
http://mindia.jp/book/dobby/keyword/Intent+Filter
ブラウザの「ページの共有」から起動
<action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" />
ブラウザでリンク遷移しようとしたときに起動
<action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> <data android:scheme="http" />
明示的インテント・暗黙的インテントの使用例
http://thinkit.jp/article/921/1/
Intent intent = new Intent(); intent.setAction(Intent.ACTION_SEND); intent.setType("image/jpeg"); intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("jpegファイルの場所")); startActivity(intent);
<intent-filter> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/jpeg" /> </intent-filter>
逆に、Twidroidから、ホットペッパーのURLを開いたときに、ホットペッパーアプリが呼ばれるような仕組みも実装しています。
http://mtl.recruit.co.jp/blog/2010/01/android.html
<activity android:name=".RwsHotpepperShopActivity" android:label="@string/app_name" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="http" /> <data android:host="www.hotpepper.jp" /> <data android:pathPrefix="/str" /> </intent-filter> </activity>
http://lab.r246.jp/twicca/twicca_plugin.pdf
<intent-filter android:icon="@drawable/plugin_icon" android:label="@string/plugin_name"> <action android:name="jp.r246.twicca.ACTION_UPLOAD" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="image/*" /> …画像をアップロードする場合 <data android:mimeType="video/*" /> </intent-filter>
<intent-filter android:icon="@drawable/plugin_icon" android:label="@string/plugin_name"> <action android:name="jp.r246.twicca.ACTION_PLUGIN_SETTINGS" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter>
Quick Bookmark のことを知らないアプリからでもURLを保存したい場合は、ブラウザを開くIntentを横取りすればいいはずです。以下を Manifest に追加すれば、http:// と https:// を開く Intent が Activity に届くようになります。 <intent-filter> <action android:name="android.intent.action.VIEW" /> <data android:scheme="http" /> <data android:scheme="https" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> ただ、このままだと、URLをデータベースに保存してすぐ終了する Activity であっても、一瞬画面に表示されてしまいます。これを防ぐために、Activity を透明化します。 <activity android:name=".AddActivity" android:label="@string/app_name" android:theme="@android:style/Theme.Translucent.NoTitleBar"> あとは、Activity の onCreate() で getIntent().getData().toString() して URL を文字列として取り出して、DBに保存、即 finish() で終了です
いろんな ACTION_* を発行してみる
上のアクションの種類以外の情報に関しては、無限なパターンが存在することになりそうなので、とりあえずは、アクションの種類のみで発行してみようかと。
アクションの種類のみの発行でインストールされているアクティビティの反応をみるアプリがマーケットにある。
http://jp.androlib.com/android.application.yanzm-example-getintentlist-AqtF.aspx
その他の情報を追加しての発行からの反応をみるアプリもある。
http://jp.androlib.com/android.application.com-codtech-android-intentplayground-qBq.aspx
コマンドラインで反応をみるには、
$ adb shell $ am usage: am [start|broadcast|instrument|profile] am start [-D] INTENT am broadcast INTENT am instrument [-r] [-e <ARG_NAME> <ARG_VALUE>] [-p <PROF_FILE>] [-w] <COMPONENT> am profile <PROCESS> [start <PROF_FILE>|stop] INTENT is described with: [-a <ACTION>] [-d <DATA_URI>] [-t <MIME_TYPE>] [-c <CATEGORY> [-c <CATEGORY>] ...] [-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...] [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...] [-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...] [-n <COMPONENT>] [-f <FLAGS>] [<URI>]
なので
$ am start -a android.intent.action.VIEW http://www.google.com
ログの書式を確認してみる。
I/ActivityManager( 79): Starting activity: Intent { act=android.intent.action.CHOOSER cmp=android/com.android.internal.app.ChooserActivity (has extras) } I/ActivityManager( 79): Starting activity: Intent { act=android.intent.action.SEND typ=text/plain flg=0x3000000 cmp=com.threebanana.notes/.NoteEditor (has extras) } I/ActivityManager( 79): Starting activity: Intent { act=android.intent.action.CHOOSER cmp=android/com.android.internal.app.ChooserActivity (has extras) } I/ActivityManager( 79): Starting activity: Intent { act=android.intent.action.CHOOSER cmp=android/com.android.internal.app.ChooserActivity (has extras) } I/ActivityManager( 79): Starting activity: Intent { act=android.intent.action.SEND typ=text/plain flg=0x3000000 cmp=jp.tomorrowkey.android.hatenabookmark/.PageInfoActivity (has extras) } I/ActivityManager( 79): Starting activity: Intent { act=android.intent.action.CHOOSER cmp=android/com.android.internal.app.ChooserActivity (has extras) } I/ActivityManager( 79): Starting activity: Intent { act=android.intent.action.SEND typ=text/plain flg=0x3000000 cmp=com.mgeek.android.DolphinBrowser.Browser/.PostToDelicious (has extras) } I/ActivityManager( 79): Starting activity: Intent { cmp=com.mgeek.android.DolphinBrowser.Browser/.ModifyDeliciousAccount } I/ActivityManager( 79): Starting activity: Intent { act=android.intent.action.VIEW dat=http://www.google.com flg=0x10000000 cmp=android/com.android.internal.app.ResolverActivity } I/ActivityManager( 79): Starting activity: Intent { act=android.intent.action.VIEW dat=http://www.google.com flg=0x10000000 cmp=android/com.android.internal.app.ResolverActivity } I/ActivityManager( 79): Starting activity: Intent { act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=http://www.google.co.jp/ cmp=android/com.android.internal.app.ResolverActivity } I/ActivityManager( 79): Starting activity: Intent { act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=http://www.google.co.jp/ flg=0x3800000 cmp=com.mgeek.android.DolphinBrowser.Browser/.BrowserActivity }
am start -a android.intent.action.VIEW http://www.google.com
am start -a android.intent.action.VIEW -t plain/text http://www.google.com x
am start -a android.intent.action.SEND http://www.google.com x
am start -a android.intent.action.SEND -t plain/text http://www.google.com