注意!
この記事はQiitaにて公開されていた内容をimportしたものです。
これらの内容は場合によっては陳腐化していて役に立たなくなっていたり、有害であったり、現在の著者の主張と異なることがあります。
皆様の判断の上でご利用いただけますと幸いです(度を超してヤバいものは著者に連絡して頂ければ対応します m(_ _)m)
はじめに
Androidアプリ開発では暗黙的Intentを処理することは非常によく発生します。 ただ、記述する定義に対して、明示的・暗黙的なルールがあったりして非常に初見殺しであるとも言えます。
今回は、IntentFilterのdata要素でハマった点を解説します
公式ドキュメントの記載
まずはじめに簡単にdata要素について。
これを読む限り、以下のことが言えます。
- data要素では
android:scheme
属性が最低でもひとつは必要である- ただし
android:mimeType
が指定されていると暗黙的にfile
かcontent
が指定されているものとされる
- ただし
android:host
属性はandroid:scheme
属性が指定されていないと意味を成さないandroid:path
やandroid:pathPrefix
、android:pathPattern
属性はandroid:scheme
およびandroid:host
属性が指定されていないと意味を成さない
これらの情報から、以下の様なIntentFilterを定義し、adb shell am start
コマンドでいくつか検証しました。
<activity android:name=".HogeActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="example.com"
android:scheme="http"/>
</intent-filter>
</activity>
$ adb shell am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d http://example.com/test.mp4
これでHogeActivityが起動するはずです。
問題:Chromeでリンクをタップした時に割り込めない
上記指定で無事に起動しました。めでたし。 ただ、以下のようにdata要素の指定を増やすと(?)、Chromeでリンクをクリックしてもアプリの選択画面に現れなくなります。 (本当にdataが増えたことに因果関係があるかどうかは不明。再現しないケースもある。。)
<activity android:name=".HogeActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="example.com"
android:scheme="http"/>
<data
android:host="*.example.net"
android:scheme="http"/>
</intent-filter>
</activity>
解決策: android:pathPrefix もしくは android:pathPattern を設定する
おなじみのStackOverflowを参照すると、android:pathPrefix
を付与している例が見られます。
また、android:pathPattern=".*"
という一件無意味そうな定義があります。
ただ、これらの指定をすることで、Chromeで該当のリンクをクリックするとちゃんとアプリの選択ダイアログが表示されるようになります。
<activity android:name=".HogeActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data
android:host="example.com"
android:scheme="http"
android:pathPattern="/.*"/>
<data
android:host="*.example.net"
android:scheme="http"
android:pathPattern="/.*"/>
</intent-filter>
</activity>
ちなみに
android:host
にはワイルドカード指定が使えます。