Web サイトとモバイル アプリを接続して、Web サイト上のリンクがモバイル アプリを起動し、モバイル アプリ内でコンテンツを表示させたいという場合はよくあります。 アプリ のリンク ( ディープ リンクとも呼ばれます) は、モバイル デバイスが URI に応答し、URI で表されるモバイル アプリでコンテンツを起動できるようにする手法です。
Android は、意図システムを介してアプリのリンクを処理します。 モバイルブラウザでリンクをタップすると、ブラウザはインテントをディスパッチし、Androidはそれを登録されているアプリに渡します。 これらのリンクは、 myappname://などのカスタム スキームに基づくか、HTTP または HTTPS スキームを使用できます。 たとえば、レシピ Web サイトのリンクをクリックすると、その Web サイトに関連付けられているモバイル アプリが開き、特定のレシピがユーザーに表示されます。 意図を処理するために複数のアプリが登録されている場合、Android には、意図を処理するために選択するアプリをユーザーに求めるあいまいさの解消ダイアログが表示されます。 アプリがインストールされていないユーザーは、Web サイトのコンテンツに移動します。
Android では、アプリのリンクが次の 3 つのカテゴリに分類されます。
- ディープ リンク は、アプリ内の特定のコンテンツにユーザーを移動するスキームの URI です。 ディープ リンクをクリックすると、ユーザーにディープ リンクを処理するアプリを選択するよう求めるあいまいさの解消ダイアログが表示されることがあります。
- Web リンク は、HTTP または HTTPS スキームを使用するディープ リンクです。 Android 12 以降では、Web リンクは常に Web ブラウザーにコンテンツを表示します。 以前のバージョンの Android では、アプリが Web リンクを処理できる場合は、Web リンクを処理するアプリを選択するようユーザーに求めるあいまいさの解消ダイアログが表示されます。
- API 23 以降で利用できる Android アプリ リンクは、HTTP または HTTPS スキームを使用し、
autoVerify属性を含む Web リンクです。 この属性を使用すると、アプリがアプリ リンクの既定のハンドラーになります。 そのため、アプリのリンクがクリックされると、あいまいさを解消するダイアログが表示されずにアプリが開きます。
.NET MAUI Android アプリは、3 つのカテゴリのアプリ リンクをすべてサポートできます。 ただし、この記事では Android アプリのリンクに焦点を当てています。 これには、ドメインの所有権を証明するだけでなく、ドメイン上のデジタル資産リンク ファイル JSON ファイルをホストする必要があります。これは、アプリとの関係を記述します。 これにより、Android は、URI を処理しようとしているアプリが URI ドメインの所有権を持っていることを確認して、悪意のあるアプリがアプリのリンクを傍受するのを防ぐことができます。
.NET MAUI Android アプリで Android アプリのリンクを処理するプロセスは次のとおりです。
- ドメインの所有権を確認します。 詳細については、「 ドメインの所有権を確認する」を参照してください。
- Web サイトでデジタル資産リンク ファイルを作成してホストします。 詳細については、「 デジタル資産リンク ファイルを作成してホストする」を参照してください。
- Web サイト URI 用にアプリで意図フィルターを構成します。 詳細については、「 意図フィルターの構成」を参照してください。
- 受信インテントからデータを読み取る。 詳細については、「 受信インテントからデータを読み取る」を参照してください。
重要
Android アプリのリンクを使用するには:
- アプリのバージョンが Google Play で公開されている必要があります。
- コンパニオン Web サイトは、Google のデベロッパー コンソールでアプリに対して登録する必要があります。 アプリが Web サイトに関連付けられると、Web サイトとアプリの両方で機能する URI のインデックスを作成し、検索結果で提供できます。 詳細については、「google Search on support.google.com でのアプリのインデックス作成 」を参照してください。
Android アプリのリンクの詳細については、「Android アプリ リンク の処理」を参照してください。
ドメインの所有権を確認する
Google Search Console でアプリ リンクを提供しているドメインの所有権を確認する必要があります。 所有権の確認とは、特定の Web サイトを所有していることを証明することを意味します。 Google Search コンソールでは、複数の検証方法がサポートされています。 詳細については、「support.google.com での サイトの所有権の確認 」を参照してください。
デジタル資産リンク ファイルを作成してホストする
Android アプリのリンクでは、アプリを URI の既定のハンドラーとして設定する前に、Android でアプリと Web サイトの間の関連付けを確認する必要があります。 この検証は、アプリが最初にインストールされるときに発生します。 デジタル資産リンク ファイルは、関連する Web ドメインによってホストされる必要がある JSON ファイルです。 https://domain.name/.well-known/assetlinks.json。
デジタル資産ファイルには、Android が関連付けを確認するために必要なメタデータが含まれています。 このファイルには、次のキーと値のペアが必要です。
-
namespace- Android アプリの名前空間。 -
package_name- Android アプリのパッケージ名。 -
sha256_cert_fingerprints-.keystoreファイルから取得した署名済みアプリの SHA256 フィンガープリント。 鍵ストアの署名の取得方法については、鍵ストアの署名の検索を参照してください。
次の例 assetlinks.json ファイルは、 com.companyname.myrecipeapp Android アプリにリンクを開く権限を付与します。
[
{
"relation": [
"delegate_permission/common.handle_all_urls"
],
"target": {
"namespace": "android_app",
"package_name": "com.companyname.myrecipeapp",
"sha256_cert_fingerprints": [
"14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"
]
}
}
]
複数の SHA256 フィンガープリントを登録して、アプリの異なるバージョンまたはビルドをサポートすることができます。 次の assetlinks.json ファイルは、 com.companyname.myrecipeapp と com.companyname.mycookingapp Android アプリの両方にリンクを開く権限を付与します。
[
{
"relation": [
"delegate_permission/common.handle_all_urls"
],
"target": {
"namespace": "android_app",
"package_name": "com.companyname.myrecipeapp",
"sha256_cert_fingerprints": [
"14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"
]
}
},
{
"relation": [
"delegate_permission/common.handle_all_urls"
],
"target": {
"namespace": "android_app",
"package_name": "com.companyname.mycookingapp",
"sha256_cert_fingerprints": [
"14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"
]
}
}
]
ヒント
ステートメント リスト ジェネレーターとテスター ツールを使用して、正しい JSON を生成し、検証します。
JSON 検証ファイルを https://domain.name/.well-known/assetlinks.jsonに発行するときは、次のことを確認する必要があります。
- ファイルは、コンテンツ タイプの
application/jsonで提供されます。 - アプリがスキームとして HTTPS を使用しているかどうかに関係なく、HTTPS 経由でファイルにアクセスできる必要があります。
- ファイルにはリダイレクトなしでアクセスできる必要があります。
- アプリ リンクで複数のドメインがサポートされている場合は、各ドメインに assetlinks.json ファイルを発行する必要があります。
デジタル資産ファイルが適切にフォーマットされ、ホストされていることを確認するには、Google のデジタル資産リンク API を使用します。
https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=
https://<WEB SITE ADDRESS>:&relation=delegate_permission/common.handle_all_urls
詳細については、「developer.android.com で Web サイトの関連付けを宣言 する」を参照してください。
意図フィルターを構成する
Web サイトから Android アプリのアクティビティに URI または URI のセットをマップするように意図フィルターを構成する必要があります。 .NET MAUI では、アクティビティに IntentFilterAttribute を追加することでこれを実現できます。 意図フィルターでは、次の情報を宣言する必要があります。
- ActionView - これにより、情報を表示する要求に応答する意図フィルターが登録されます。
- Categories - 意図フィルターは、web URI を正しく処理できるように、 CategoryDefault と CategoryBrowsable の両方を登録する必要があります。
- DataScheme - 意図フィルターでは、カスタム スキーム、HTTP、または HTTPS を宣言する必要があります。
- DataHost - これは URI の生成元のドメインです。
-
DataPathPrefix - これは、web サイト上のリソースへの省略可能なパスであり、
/で始まる必要があります。 -
AutoVerify - アプリと Web サイトの関係を確認するように Android に指示します。 それ以外
true設定する必要があります。そうしないと、Android はアプリと Web サイトの間の関連付けを検証しないため、アプリを URI の既定のハンドラーとして設定しません。
次の例は、 IntentFilterAttribute を使用して https://www.recipe-app.com/recipesからのリンクを処理する方法を示しています。
using Android.App;
using Android.Content;
using Android.Content.PM;
namespace MyNamespace;
[Activity(
Theme = "@style/Maui.SplashTheme",
MainLauncher = true,
ConfigurationChanges = ConfigChanges.ScreenSize |
ConfigChanges.Orientation |
ConfigChanges.UiMode |
ConfigChanges.ScreenLayout |
ConfigChanges.SmallestScreenSize |
ConfigChanges.KeyboardHidden |
ConfigChanges.Density)]
[IntentFilter(
new string[] { Intent.ActionView },
Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },
DataScheme = "https",
DataHost = "recipe-app.com",
DataPath = "/recipe",
AutoVerify = true,)]
public class MainActivity : MauiAppCompatActivity
{
}
注
意図フィルターでは、複数のスキームとホストを指定できます。 詳細については、「developer.android.com での アプリ コンテンツへのディープ リンクの作成 」を参照してください。
Android は、アプリを URI の既定のハンドラーとして登録する前に、Web サイト上のデジタル資産ファイルに対してインテント フィルターで識別されたすべてのホストを検証します。 Android が既定のハンドラーとしてアプリを確立するには、すべての意図フィルターが検証に合格する必要があります。 アクティビティ コンテンツの URI を含む意図フィルターを追加すると、Android は、一致する URI を持つ意図を実行時にアプリにルーティングできます。
アクティビティを他のアプリが起動できるように、アクティビティをエクスポート可能としてマークする必要がある場合もあります。 これを実現するには、既存のExported = trueにActivityAttributeを追加します。 詳細については、「developer.android.com の Activity 要素」 を参照してください。
Web URI インテントが呼び出されると、Android は要求が成功するまで次のアクションを試行します。
- URI を処理する優先アプリを開きます。
- URI を処理するために使用可能な唯一のアプリを開きます。
- ユーザーが URI を処理するアプリを選択できるようにします。
意図と意図フィルターの詳細については、「developer.android.com の意図と意図フィルター 」を参照してください。
受信インテントからデータを読み取る
Android が意図フィルターを使用してアクティビティを開始するときに、意図によって提供されるデータを使用して、何を行うかを決定できます。 理想的には OnCreate、早期のライフサイクルデリゲートで実行する必要があります。
OnCreate デリゲートは、アクティビティの作成時に呼び出されます。 ライフサイクル デリゲートの詳細については、「 プラットフォーム ライフサイクル イベント」を参照してください。
呼び出されている Android ライフサイクル デリゲートに応答するには、ConfigureLifecycleEvents クラスの MauiAppBuilder メソッド内の CreateMauiapp オブジェクトに対して MauiProgram メソッドを呼び出します。 次に、 ILifecycleBuilder オブジェクトで、 AddAndroid メソッドを呼び出し、必要なデリゲートのハンドラーを登録する Action を指定します。
using Microsoft.Maui.LifecycleEvents;
using Microsoft.Extensions.Logging;
namespace MyNamespace;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
})
.ConfigureLifecycleEvents(lifecycle =>
{
#if ANDROID
lifecycle.AddAndroid(android =>
{
android.OnCreate((activity, bundle) =>
{
var action = activity.Intent?.Action;
var data = activity.Intent?.Data?.ToString();
if (action == Android.Content.Intent.ActionView && data is not null)
{
Task.Run(() => HandleAppLink(data));
}
});
android.OnNewIntent((activity, intent) =>
{
var action = intent?.Action;
var data = intent?.Data?.ToString();
if (action == Android.Content.Intent.ActionView && data is not null)
{
Task.Run(() => HandleAppLink(data));
}
});
});
#endif
});
#if DEBUG
builder.Logging.AddDebug();
#endif
return builder.Build();
}
static void HandleAppLink(string url)
{
if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out var uri))
App.Current?.SendOnAppLinkRequestReceived(uri);
}
}
Intent.Action プロパティは受信インテントに関連付けられたアクションを取得し、Intent.Data プロパティは受信インテントに関連付けられたデータを取得します。 意図アクションが ActionView に設定されている場合は、App メソッドを使用して、意図データを SendOnAppLinkRequestReceived クラスに渡すことができます。
警告
アプリ リンクは潜在的な攻撃ベクトルをアプリに提供するため、すべての URI パラメーターを検証し、形式が正しくない URI を破棄してください。
App クラスで、OnAppLinkRequestReceived メソッドをオーバーライドして意図データを受信して処理します。
namespace MyNamespace;
public partial class App : Application
{
...
protected override async void OnAppLinkRequestReceived(Uri uri)
{
base.OnAppLinkRequestReceived(uri);
// Show an alert to test that the app link was received.
await Dispatcher.DispatchAsync(async () =>
{
await Windows[0].Page!.DisplayAlert("App link received", uri.ToString(), "OK");
});
Console.WriteLine("App link: " + uri.ToString());
}
}
namespace MyNamespace;
public partial class App : Application
{
...
protected override async void OnAppLinkRequestReceived(Uri uri)
{
base.OnAppLinkRequestReceived(uri);
// Show an alert to test that the app link was received.
await Dispatcher.DispatchAsync(async () =>
{
await Windows[0].Page!.DisplayAlertAsync("App link received", uri.ToString(), "OK");
});
Console.WriteLine("App link: " + uri.ToString());
}
}
上記の例では、 OnAppLinkRequestReceived オーバーライドによってアプリ のリンク URI が表示されます。 実際には、アプリ のリンクは、プロンプト、ログイン、またはその他の中断なしに、URI で表されるコンテンツにユーザーを直接移動する必要があります。 したがって、 OnAppLinkRequestReceived オーバーライドは、URI で表されるコンテンツへのナビゲーションを呼び出す場所です。
アプリ のリンクをテストする
デジタル資産ファイルが正しくホストされている場合は、アクティビティ マネージャー ツール (adb) を使用して Android デバッグ ブリッジ amを使用して URI の開きをシミュレートし、アプリ リンクが正しく動作することを確認できます。 たとえば、次のコマンドは、URI に関連付けられているターゲット アプリ アクティビティの表示を試みます。
adb shell am start -W -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d YOUR_URI_HERE
このコマンドは、Android があなたのモバイルアプリに送信するインテントを発出します。これにより、URI に登録されているアクティビティを起動して表示する必要があります。
注
エミュレーターまたはデバイスに対して adb を実行できます。
さらに、デバイスにインストールされているアプリの既存のリンク処理ポリシーを表示できます。
adb shell dumpsys package domain-preferred-apps
このコマンドを実行すると、次の情報が表示されます。
- パッケージ - アプリのパッケージ名。
- ドメイン - スペースで区切られたドメイン。Web リンクはアプリによって処理されます。
- 状態 - アプリの現在のリンク処理状態。
alwaysの値は、アプリがAutoVerifyをtrueに設定し、システム検証に合格したことを意味します。 その後に、設定のレコードを表す 16 進数が続きます。
adb コマンドの詳細については、「Android デバッグ ブリッジ」を参照してください。
さらに、 Play コンソールを使用して Android アプリのリンクを管理および確認できます。 詳細については、「developer.android.com での Android アプリ リンクの管理と検証 」を参照してください。
トラブルシューティングのアドバイスについては、「developer.android.com の 一般的な実装エラーを修正 する」を参照してください。
.NET MAUI