2013 年 11 月 20 日

モバイルブラウザからアプリを呼び出す方法

3140-logo

アプリに連動したウェブサイトから、アプリを呼び出したいと思ったことはありませんか。アクティビティのインテントフィルタをURIスキームで定義すると、他のアプリとの連携がURIで利用できるようになります。もちろん、引き渡せる情報はURIパラメータなので、インテントによる起動ほど柔軟ではありません。

最近、ディープリンクが注目されだして、ブラウザからアプリの詳細ページへ直接リンクをつくること(ディープリンク)で、ユーザビリティを向上させることが求められています。Androidブラウザのグーグルの検索結果から直接アプリの詳細ページへジャンプできるようにするという方法があります(Google 検索用 App Indexing)。

FacebookではMobile App Ads for Engagement and Conversion(行動誘発モバイルアプリ広告)が開始され、アプリのインストールだけでなく、アプリの利用を促し、アプリ内課金を促進するFacebook広告も作成できるようになりました。URIによるアプリの起動を実装しておくと、このような広告も簡単に利用することができます。

マニフェスト

スマホのブラウザからアプリを呼び出すには、まずマニフェストでアクティビティに対して設定をしておく必要があります。ブラウザから呼び出したアクティビティの定義に以下のようなintent-filterを追加します。

android:schemeは大文字と小文字が区別されますが、全て小文字で定義することが推奨されているようです(RFCのURI定義とは異なる)。
RFC1738 2.1. The main parts of URLs

android:hostは、ドメインを含むならFQDNに沿っておかないと、ブラウザが不正なものと認識してしまいます。もちろん、実在しなくても大丈夫です。android:pathはルートでよいなら必要ないです。

スキーマの決定で気になるのは、他のアプリと重複しないかですが、host名を所有するドメインにしておけば、問題ないのだろうと推測しています。

iOSでは、以下の記事に詳しく書かれていますが、アンドロイドでは、どのアプリを選択するのかとダイアログが表示されるのだろうと思います。ホスト名までは考慮されないのかもしれません(2014/12/1)

ref.URLスキームが複数のアプリで同一であった時のiOSバージョンごとの挙動について


  
    
    
  
  
    
    
    
    
  

URIを分解

マニフェストでintent-filterを指定したアクティビティのonStartハンドラでURIを調べて、処理を振り分けます。

final static String INTENT_SCHEME = "mycheme";
final static String INTENT_HOST = "app.notice.co.jp";
final static String INTENT_REQUEST = "top";
final static String INTENT_PARAM = "param";

// アクションを調べる。
String action = intent.getAction();
if (!Intent.ACTION_VIEW.equals(action)) {
  return;
}
// インテントからURIを取得する。
final Uri uri = intent.getData();
if (uri != null && uri.toString().toLowerCase(Locale.getDefault()).startsWith(INTENT_SCHEME)) {
  String authority = uri.Authority(); // ホスト名
  String path= uri.getPath(); // パス
  // ここではパスだけで判定しています。
  if (INTENT_REQUEST.equals(path)) {
    // top画面へ遷移する。
  }
}

URIの組み立て

もし、自身のアプリの中からも利用したい場合は、以下のようにURIを組み立てて、アクティビティを呼び出すこともできます。

Uri.Builder builder = new Uri.Builder();
builder.scheme(INTENT_SCHEME)
     .authority(INTENT_HOST)
     .path(INTENT_REQUEST)
     // 必要ならパラメータも付加します。
     .appendQueryParameter(INTENT_PARAM, param);
Intent it = new Intent(Intent.ACTION_VIEW, builder.build());
it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(it);      

モバイルブラウザからの呼出

ウェブサイトのページに以下のようなアンカータグを記述しておきます。そして、モバイルブラウザからこのリンクをたどるとアプリが起動します。

<a href="myscheme://app.notice.co.jp/top/">アプリのトップ画面</a>

しかし、ウェブサイトからアプリが起動できるなら、アプリがインストールされていなければ、インストールを促して、Google Playへ移動したくもなります。

アンドロイドのブラウザにはそのような機能はありませんが、stackoverflow.comにタイムアウトを使った例があったので、合わせてご紹介します。欠点は、インストールの有無を調べるために、最初にlocationへ飛ばすので、インストール済みならそのまま遷移してしまうことです。ページをロードした時点でインストール有無を調べる方法がありません。

Check if URL scheme is supported in javascript