共用方式為


Android 應用程式連結

通常建議連接網站和行動應用程式,讓網站上的鏈接啟動行動應用程式,並在行動應用程式中顯示內容。 應用程式連結也稱為 深層連結,是一種技術,可讓行動裝置回應 URI,並在 URI 所代表的行動應用程式中啟動內容。

Android 會透過意圖系統處理應用程式連結。 當您點選行動瀏覽器中的連結時,瀏覽器會分派 Android 將委派給已註冊應用程式的意圖。 這些連結可以根據自定義配置,例如 myappname://,或使用 HTTP 或 HTTPS 配置。 例如,按兩下食譜網站上的連結會開啟與該網站相關聯的行動應用程式,然後向用戶顯示特定的食譜。 如果已註冊多個應用程式來處理意圖,Android 會顯示一個釐清對話框,要求用戶選取哪個應用程式來處理意圖。 未安裝應用程式的使用者會前往您網站上的內容。

Android 會將應用程式連結分類為三個類別:

  • 深層連結 是任何將使用者帶到應用程式中特定內容的配置 URI。 按兩下深層連結時,可能會出現釐清對話框,要求使用者選取應用程式來處理深層連結。
  • Web 連結 是使用 HTTP 或 HTTPS 配置的深層連結。 在 Android 12 和更新版本上,網頁連結一律會在網頁瀏覽器中顯示內容。 在舊版 Android 上,如果應用程式可以處理 Web 連結,則會出現一個釐清對話方塊,要求使用者選取應用程式來處理 Web 連結。
  • API 23+ 上提供的 Android 應用程式連結是使用 HTTP 或 HTTPS 配置並包含 屬性的 autoVerify Web 連結。 這個屬性可讓您的應用程式成為應用程式連結的默認處理程式。 因此,按兩下應用程式連結時,您的應用程式會開啟而不顯示混淆對話框。

.NET MAUI Android 應用程式可支援所有三種應用程式連結類別。 不過,本文著重於Android應用程式連結。 這需要證明網域的擁有權,以及裝載數位資產連結網域上的檔案 JSON 檔案,以描述與您的應用程式的關係。 這可讓Android確認嘗試處理URI的應用程式擁有URI網域的擁有權,以防止惡意應用程式攔截您的應用程式連結。

在 .NET MAUI Android 應用程式中處理 Android 應用程式連結的程式如下:

  1. 確認網域擁有權。 如需詳細資訊,請參閱 驗證網域擁有權
  2. 在您的網站上建立及裝載數位資產連結檔案。 如需詳細資訊,請參閱 建立及裝載數位資產鏈接檔案
  3. 在應用程式中為網站 URI 設定意圖篩選。 如需詳細資訊,請參閱 設定意圖篩選
  4. 從傳入意圖讀取數據。 如需詳細資訊,請參閱 從傳入意圖讀取數據。

重要

若要使用 Android 應用程式連結:

  • 您的 App 版本必須在 Google Play 上上線。
  • 隨附網站必須在Google開發人員控制台中針對應用程式註冊。 一旦應用程式與網站相關聯,就可以為網站和應用程式編製索引,以在搜尋結果中提供這些 URI。 如需詳細資訊,請參閱 support.google.com 上的Google搜尋 應用程式索引。

如需 Android 應用程式連結的詳細資訊,請參閱 處理 Android 應用程式連結

核對網域擁有權

您必須確認您在 Google 搜尋控制台提供應用程式連結之網域的擁有權。 擁有權驗證表示證明您擁有特定網站。 Google 搜尋主控台支援多個驗證方法。 如需詳細資訊,請參閱 確認 support.google.com 上的網站擁有權

Android 應用程式連結要求 Android 先確認應用程式與網站之間的關聯,再將應用程式設定為 URI 的預設處理程式。 第一次安裝應用程式時,會發生此驗證。 數字資產鏈接檔案是 JSON 檔案,必須由相關 Web 網域裝載於下列位置: 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.myrecipeappcom.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 的網站關聯

設定意圖篩選

必須設定意圖篩選,以將 URI 或 URI 集合從網站對應至 Android 應用程式中的活動。 在 .NET MAUI 中,您可以藉由將 新增 IntentFilterAttribute 至活動來達成此目的。 意圖篩選必須宣告下列資訊:

  • ActionView - 這會註冊意圖篩選條件,以響應檢視資訊的要求。
  • Categories - 意圖篩選應該同時 CategoryDefault 登錄 和 CategoryBrowsable ,才能正確處理 Web URI。
  • DataScheme - 意圖篩選必須宣告自定義配置,以及/或 HTTPS 和/或 HTTPS。
  • DataHost - 這是 URI 的來源網域。
  • DataPathPrefix - 這是網站上的資源選擇性路徑,其開頭 /必須是 。
  • AutoVerify - 這會告訴Android驗證應用程式與網站之間的關聯性。 它必須設定為 true ,否則 Android 不會驗證應用程式與網站之間的關聯,因此不會將您的應用程式設定為 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 的預設處理程式之前,先針對網站上的數位資產檔案,確認意圖篩選中識別的每個主機。 所有意圖篩選都必須通過驗證,Android 才能將應用程式建立為默認處理程式。 新增具有活動內容 URI 的意圖篩選后,Android 能夠在運行時間將具有相符 URI 的任何意圖路由傳送至您的應用程式。

您也可以將活動標示為可匯出,讓其他應用程式可以啟動您的活動。 這可以藉由將 新增 Exported = true 至現有的 ActivityAttribute來達成。 如需詳細資訊,請參閱 developer.android.com 上的活動專案

叫用 Web URI 意圖時,Android 會嘗試下列動作,直到要求成功為止:

  1. 開啟慣用的應用程式來處理URI。
  2. 開啟唯一可用的應用程式來處理URI。
  3. 允許使用者選取應用程式來處理 URI。

如需意圖和意圖篩選的詳細資訊,請參閱 developer.android.com 上的意圖和意圖篩選

從傳入意圖讀取數據

當 Android 透過意圖篩選啟動活動時,您可以使用意圖所提供的數據來判斷該怎麼做。 這應該在早期生命週期委派中執行,在理想情況下 OnCreate。 建立 OnCreate 活動時會叫用委派。 如需生命週期委派的詳細資訊,請參閱 平臺生命週期事件

若要回應所叫用的Android生命週期委派,ConfigureLifecycleEvents請在類別MauiProgram的方法中呼叫物件CreateMauiapp上的 MauiAppBuilder 方法。 然後,在 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));
                        }
                    });
                });
#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
{
    public App()
    {
        InitializeComponent();

        MainPage = new AppShell();
    }

    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());
    }
}

在上述範例中 OnAppLinkRequestReceived ,覆寫會顯示應用程式連結 URI。 實際上,應用程式鏈接應該將使用者直接帶到 URI 所代表的內容,而不會有任何提示、登入或其他中斷。 因此, OnAppLinkRequestReceived 覆寫是叫用巡覽至 URI 所表示內容的位置。

假設數位資產檔案已正確裝載,您可以使用 Android Debug Bridge adb,搭配活動管理員工具 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 表示應用程式已設定 AutoVerifytrue 且已通過系統驗證。 後面接著代表喜好設定記錄的十六進位數位。

如需命令的詳細資訊 adb ,請參閱 Android 偵錯網橋

此外,您可以透過 Play Console 管理和驗證 Android 應用程式連結。 如需詳細資訊,請參閱 管理及驗證 developer.android.com 上的Android應用程式連結

如需疑難解答建議,請參閱 修正 developer.android.com 上的常見實作錯誤