こんにちは。エンジニアのKです。
アプリへの新しい導線口だけでなく、SEOにも効果があると言われているAppIndexingを
遅ればせながら実装してみました。
AppIndexingについて
ざっくり言うと、Google検索結果にアプリコンテンツへのリンクが表示されるようになります。
Cookpadさんの場合、こんな感じで表示されます。
アプリがインストールされていれば、アプリ内のコンテンツ(この場合「大根」レシピの検索結果画面)が、まるでwebページへの遷移のようにシームレスに行われます。
アプリがインストールされていない場合、Google Playストアのダウンロードページヘ遷移します。便利ですね。
アプリリンクの表示条件は?
実装にあたって、どんな挙動になるか、先駆者様のアプリで見てみようと思ったのですが、
なかなか上手く行かずに苦労しました。
AndroidはGoogleアカウントでログインしていなくても表示されるらしいのですが、なかなか表示されず。。
とりあえず、対象アプリをインストールしたGoogleカウントでログインしたら、表示されるようになりました。
※ Androidバージョンやブラウザアプリのバージョンにもよる違いもあるかもです。
AppIndexingを実装する
公式ドキュメント に従って実装していきますが、試行錯誤した点について補足していければと思います。
サンプルコードは、公式ドキュメントにも出てくる
android-deep-linkingプロジェクト(com.recipe-app) を使います。
インテントフィルタの追加
まず、アプリ内のコンテンツに直接遷移できるディープリンクをサポートする必要があります。
http://recipe-app.com/recipe/{recipeId}といったwebページでレシピ詳細を表示する機能があった場合、
同等の機能を持ったアプリのActivity(.RecipeActivity)に、以下の様なintent-filterを追加します。(AndroidManifest.xml)
HTTPスキームとカスタムスキームどちらかだけでもいいですし、両方設定してももちろん大丈夫です。
要は特定のURLでインテントが飛んだ時に、アプリが反応できるようになっていれば良いということですね。
Googleは実装手順が簡素になるということから、HTTPスキームを推奨しています。
ディープリンクのURIに対応する処理をActivityに実装
intent-filterを追加したことにより、
http://recipe-app.com/recipe/pierogi-poutine といったURLで.RecipeActivityが起動するようになります。
.RecipeActivityはレシピ詳細を表示するアクティビティですので、対象となるレシピIDが必要になります。
アプリ内遷移であれば、前画面から飛ばすintentにputExtraしてレシピIDを渡すのが一般的かと思いますが、
ディープリンクの場合、intent.getDataString()で取得できるURLをパースして、レシピIDを取り出して、後続の処理に渡すようにします。
protected void onNewIntent(Intent intent) {
String action = intent.getAction();
String data = intent.getDataString(); // http://recipe-app.com/recipe/pierogi-poutine
if (Intent.ACTION_VIEW.equals(action) && data != null) {
String recipeId = data.substring(data.lastIndexOf("/") + 1); // pierogi-poutine
// レシピ情報を取得して、表示する処理
Uri contentUri = RecipeContentProvider.CONTENT_URI.buildUpon().appendPath(recipeId).build();
showRecipe(contentUri);
}
}
ディープリンクをGoogleに知らせる
ここまでで、アプリがディープリンクに対応し、Googleの検索結果から直接アプリへ遷移できるようになりました。
あとは、対応したディープリンクをGoogleに教えて、検索結果に表示するようにしてもらいましょう。
教える方法は、
AppIndexing APIをアプリに実装
対応するwebページのmetaタグにディープリンクを指定
sitemap.xmlに記述する
があります。2,3はアプリに対応するwebページを持っている前提となります。
できれば全て対応したほうが、インデックスされやすくなりそうですね。
また、Googleにディープリンクを知らせる際のURLは、以下の様なフォーマットで記述します。
android-app://{package_id}/{scheme}/{path}
上記で対応したディープリンクの場合、
android-app://com.recipe-app/http/recipe/pierogi-poutine
android-app://com.recipe-app/recupe-app/recipe/pierogi-poutine
となります。
AppIndexing APIで知らせる
公式ドキュメント にあるとおり、build.gradleとAndroidManifest.xmlに設定を追加し、ActivityのonStart(), onStop()でAPI
を実行します。
公式ドキュメントにあるコードでは、タイトルとwebのURL、アプリのURLを設定していますが、
以下のように書くと、概要(description) も合わせて送信できるようになります。
※descriptionがどのように評価され、利用されるかは不明
mClient.connect();
String title = "タイトル";
String description = "概要";
Thing object = new Thing.Builder()
.setType("http://schema.org/Thing")
.setName(title)
.setDescription(description)
.setUrl(APP_URL)
.setId(WEB_URL)
.build();
Action viewAction = new Action.Builder(Action.TYPE_VIEW).setObject(object).build();
AppIndex.AppIndexApi.start(mClient, viewAction);
タイトルや概要にマルチバイト文字が含まれる場合、URLエンコードする必要は無いのかな?と迷いましたが、エンコードは不要でした。
公式ドキュメントのApp Indexing API 呼び出しをテストする で見た時、コンソールに文字化けして表示されますが、
リリース後にSearch ConsoleでFetch as Googleで見たところ、正常に日本語が認識されていました。
Webページのmetaタグで知らせる
http://recipe-app.com/recipe/pierogi-poutineのheadタグ内に、以下のmetaタグを追加します。
<html>
<head>
...
...
</head>
...
</html>
sitemap.xmlで知らせる
http://recipe-app.com/recipe/pierogi-poutineの要素にlink要素を追加します。
...
http://recipe-app.com/recipe/pierogi-poutine
...
以上で実装編は完了です(長い)。
次回はGooglePlay DeveloperConsoleやSearchConsoleで必要となる設定についてまとめられたらと思います。
まとめました =>
【Android】AppIndexingを設定してみた