【Android】はじめてのカスタムURLスキーム

こんにちは、Monacaチームの細井です。
あいかわらず、Android一本で仕事をしています。(アシアル社員だとは思えない

さて、今回は、AndroidでカスタムURLスキームを使ってみた、という内容をお送りします。
何故、今更そんな昔からある話を?というと、Monacaデバッガーの新機能で使うことになったからです。

カスタムURLスキームとは?

iOS/Android問わず存在する仕組みですが、アプリを別アプリやブラウザを起動する仕組みになります。
起動時にパラメータを渡せるので、起動後に通常とはことなる処理をさせるといったこともできます。

サンプル

「カスタムURLスキーム android」でググると大量に出てきますので、最低限のサンプルとして、ブラウザのリンクからIDを渡しつつ、アプリを起動する方法を紹介します。

html

<a href="hoge-scheme://hoge-host?id=hogehogehoge">アプリ起動</a>
AndroidManifest

<activity
    android:name="com.hoge.SchemeActivity"
    ...
    <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:scheme="hoge-scheme" android:host="hoge-host" />
    </intent-filter>
</activity>

schemeとhostが同じアプリが複数存在する場合、Androidはどのアプリを起動するか選択することができます。
が、iOSは条件不明ですが、いずれかのアプリが自動的に選択され起動するようです。

QRコードリーダ等のアプリからは「android.intent.category.BROWSABLE」を指定しなくても起動できるので、ブラウザで表示したページから起動したくない場合は、記載しないようにしておきましょう。

SchemeActivity

// uriに「hoge-scheme://hoge-host?id=hogehogehoge」が入る
Uri uri = activity.getIntent().getData();
// パラメータで指定したhogehogehogeが取得できる
String id = uri.getQueryParameter("id");

ひっかかったポイント

カスタムURLスキームに限った問題では無いですが、Androidで別アプリ(タスク)からActivityを呼び出す際は、Activityの保持状態に気をつけなければいけません。
Monacaデバッガーは、これまで別アプリとの連携がなかったこともあり、タスクが必ず1つである前提で作られていたため、そのまま別アプリから起動すると問題がいくつか発生しました。

例えば、QRコードリーダアプリでスキームを読み取って起動しようとすると、リーダアプリのタスク上にMonacaのActivityが起動してしまいました。

リーダアプリがstartActivityしているようです。
AndroidManifestでスキームを指定したActivityにlaunchMode="singleTask(singleInstance)"を設定しましょう。

その他にも、別アプリからActivityを起動した後、ホームのアイコンからアプリを起動した時に、同じActivityが重複してしまったりしました。
以外と嵌ってしまい、各Activityの遷移や破棄のタイミングを確認しながら、launchModeやintent.setFlags()を設定していく羽目になりました。

※タスクとActivityの話は、このページが分かりやすいです。
Androidの開発をされている方は、このlaunchModeの表を見たことある方も多いんじゃないでしょうか。
http://y-anz-m.blogspot.jp/2011/02/androidlauchmode.html

おわりに

カスタムURLスキームを使った新機能は近日リリース予定です!