June 12, 2012

外部アプリから起動されるアプリを作る

外部アプリから起動されるアプリの作り方です。

「電話帳やブラウザなど外部アプリを起動する」では外部アプリをIntentを使って起動しましたが、今度はその逆にIntentを受け取って自分のアプリを外部から起動してもらう方法です。(正確にいうとアプリではなくActivityですが)

ここでいうIntentはImplicit intents(暗黙的なIntent)を指します。いわゆるAction、Category、Dataといった実行したい行動を記述して、それに対応できるアプリの起動を要求する方式です。ブラウザや電話などのアプリが起動するのは、そういうIntentを受け取れるとAndroidManifest.xmlで宣言しているからです。逆に言えば、自分のアプリでもそのような記述をすればIntentを受けれて外部アプリとして起動されるようになります。

その方法は、AndroidManifest.xmlでIntent FilterというものをActivityに設定することで実現できます。Intent Filterとは、Intentのフィルター、つまり自分が受け取れるIntentはこれですよ、それ以外は受け取りません、と宣言するものです。このフィルターに記載されたもののみ受け取ります。なにも記載がなければ一切受け取らないことを意味します。ただし、このフィルターはImplicit Intentsだけに適用されます(起動するActivityを直接指定するExplicit intentはフィルターする意味がないので関係ありません)。

例)URLの閲覧を外部アプリ起動要求する場合、通常はブラウザアプリが候補にあがりますが、そこに自分のアプリも候補にあがるようにします。下記のソースコードでImplicit intentを発行し、Activityの起動を要求します。IntentのactionはACTION_VIEW、dataのスキームはhttpとなります。

Uri uri = Uri.parse("http://android-dev-talk.blogspot.jp/");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);

下記にはActivityが2つ登録されており、SubAppActivityのほうでIntent Filterを登録し、actionがaction.VIEW、dataのschemeがhttp、categoryがDEFAULTを受け取れるように設定しています。

action名がソースコードと違うように見えますが、実は同じです。Intent.ACTION_VIEWはStringの定数で、その中身は"android.intent.action.VIEW"です。Intentのドキュメントにすべて記載されていますので、確認して一致するものを設定します。

あと、ソースコードでは指定していないcategoryにDEFAULTを設定しています。これには理由があり、startActivity()で発行するImplicit intentは自動でcategoryにDEFAULTを付加します。フィルターのルールでcategoryが付加されているintentは、同じものがフィルターに設定されていないと不適合と判断されてしまいます。なので、この設定は必ず必要です。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="jp.myapp.sample"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
        <activity
            android:name="SampleAppActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="SubAppActivity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <data android:scheme="http"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

実行すると下記のようにSampleAppが候補にでてきます。


参考:Android Developers:Intents and Filters
参考:Android Developers:Intent

No comments:

Post a Comment