如果應用程式的意圖篩選器中至少有一個 android:autoVerify="true",在搭載 Android 6.0 (API 級別 23) 以上版本的裝置上安裝應用程式時,系統會自動驗證與應用程式意圖篩選器中網址相關聯的主機。在 Android 12 以上版本中,您也可以手動叫用驗證程序,測試驗證邏輯。
自動驗證
系統的自動驗證程序包括:
- 系統會檢查所有包含下列任一項目的意圖篩選器:
- 動作:
android.intent.action.VIEW - 類別:
android.intent.category.BROWSABLE和android.intent.category.DEFAULT - 資料配置:
http或https
- 動作:
- 針對意圖篩選器中找到的每個不重複主機名稱,Android 會在 https://hostname/.well-known/assetlinks.json 查詢對應網站的 Digital Asset Links 檔案。
確認要與應用程式建立關聯的網站清單,以及代管的 JSON 檔案有效後,請在裝置上安裝應用程式。請等待至少 20 秒,讓非同步驗證程序完成。請使用下列指令,檢查系統是否已驗證應用程式,並設定正確的連結處理政策:
adb shell am start -a android.intent.action.VIEW \
-c android.intent.category.BROWSABLE \
-d "http://domain.name:optional_port"
手動驗證
從 Android 12 開始,您可以手動叫用裝置上安裝的應用程式網域驗證。無論應用程式是否指定 Android 12,您都可以執行這項程序。
建立網際網路連線
測試裝置必須連上網際網路,才能執行網域驗證。
支援更新後的網域驗證程序
如果應用程式指定 Android 12 以上版本,系統會自動使用更新後的網域驗證程序。
或者,您也可以手動啟用更新後的驗證程序。方法是在終端機視窗中執行下列指令:
adb shell am compat enable 175408749 PACKAGE_NAME
重設裝置上的 Android 應用程式連結狀態
在裝置上手動叫用網域驗證之前,您必須先重設測試裝置上的 Android 應用程式連結狀態。方法是在終端機視窗中執行下列指令:
adb shell pm set-app-links --package PACKAGE_NAME 0 all
這個指令會將裝置設為使用者為任何網域選擇預設應用程式之前的狀態。
叫用網域驗證程序
重設裝置上的 Android 應用程式連結狀態後,即可執行驗證。方法是在終端機視窗中執行下列指令:
adb shell pm verify-app-links --re-verify PACKAGE_NAME
查看驗證結果
請稍候片刻,讓驗證代理程式完成要求,然後查看驗證結果。如要進行此操作,請執行以下指令:
adb shell pm get-app-links PACKAGE_NAME
這個指令會輸出類似以下的結果:
com.example.pkg:
ID: 01234567-89ab-cdef-0123-456789abcdef
Signatures: [***]
Domain verification state:
example.com: verified
sub.example.com: legacy_failure
example.net: verified
example.org: 1026
成功通過驗證的網域,其網域驗證狀態會是 verified。任何其他狀態都表示無法執行網域驗證。具體來說,none 狀態表示驗證代理程式可能尚未完成驗證程序。
下表列出網域驗證可能為指定網域傳回的傳回值:
none- :尚未記錄這個網域的資料。請稍候幾分鐘,讓驗證代理程式完成與網域驗證相關的要求,然後再次叫用網域驗證程序。
verified- 網域已成功通過宣告應用程式的驗證。
approved- 網域已強制核准,通常是透過執行殼層指令。
denied- 網域遭到強制拒絕,通常是透過執行殼層指令。
migrated- 系統保留了先前使用舊版網域驗證程序的結果。
restored- 使用者執行資料還原後,網域已獲核准。假設網域先前已通過驗證。
legacy_failure- 網域遭舊版驗證工具拒絕。失敗原因不明。
system_configured- 網域已由裝置設定自動核准。
- 錯誤代碼為
1024以上 裝置驗證器專屬的自訂錯誤代碼。
要求使用者將應用程式與網域建立關聯
另一種讓應用程式獲得網域核准的方法,是要求使用者將應用程式與該網域建立關聯。
檢查應用程式是否已獲准使用網域
提示使用者之前,請先檢查應用程式是否為 <intent-filter> 元素中定義網域的預設處理常式。您可以使用下列其中一種方法查詢核准狀態:
DomainVerificationManagerAPI (執行階段)。- 指令列程式 (測試期間)。
DomainVerificationManager
下列程式碼片段展示如何使用 DomainVerificationManager API:
Kotlin
val context: Context = TODO("Your activity or fragment's Context")
val manager = context.getSystemService(DomainVerificationManager::class.java)
val userState = manager.getDomainVerificationUserState(context.packageName)
// Domains that have passed Android App Links verification.
val verifiedDomains = userState?.hostToStateMap
?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_VERIFIED }
// Domains that haven't passed Android App Links verification but that the
// user has associated with an app.
val selectedDomains = userState?.hostToStateMap
?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_SELECTED }
// All other domains.
val unapprovedDomains = userState?.hostToStateMap
?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_NONE }
Java
Context context = TODO("Your activity or fragment's Context");
DomainVerificationManager manager =
context.getSystemService(DomainVerificationManager.class);
DomainVerificationUserState userState =
manager.getDomainVerificationUserState(context.getPackageName());
Map<String, Integer> hostToStateMap = userState.getHostToStateMap();
List<String> verifiedDomains = new ArrayList<>();
List<String> selectedDomains = new ArrayList<>();
List<String> unapprovedDomains = new ArrayList<>();
for (String key : hostToStateMap.keySet()) {
Integer stateValue = hostToStateMap.get(key);
if (stateValue == DomainVerificationUserState.DOMAIN_STATE_VERIFIED) {
// Domain has passed Android App Links verification.
verifiedDomains.add(key);
} else if (stateValue == DomainVerificationUserState.DOMAIN_STATE_SELECTED) {
// Domain hasn't passed Android App Links verification, but the user
// has associated it with an app.
selectedDomains.add(key);
} else {
// All other domains.
unapprovedDomains.add(key);
}
}
指令列程式
在開發期間測試應用程式時,您可以執行下列指令,查詢貴機構擁有的網域驗證狀態:
adb shell pm get-app-links --user cur PACKAGE_NAME
在以下範例輸出中,雖然應用程式未通過「example.org」網域的驗證,但使用者 0 已在系統設定中手動核准應用程式,且沒有其他套件通過該網域的驗證。
com.example.pkg:
ID: ***
Signatures: [***]
Domain verification state:
example.com: verified
example.net: verified
example.org: 1026
User 0:
Verification link handling allowed: true
Selection state:
Enabled:
example.org
Disabled:
example.com
example.net
您也可以使用殼層指令,模擬使用者選取與特定網域相關聯的應用程式。如需這些指令的完整說明,請參閱 adb shell pm 的輸出內容。
提供要求的背景資訊
提出網域核准要求前,請先向使用者提供一些背景資訊。舉例來說,您可以向使用者顯示啟動畫面、對話方塊或類似的 UI 元素,說明應用程式應做為特定網域預設處理常式的原因。
提出要求
使用者瞭解應用程式要求他們執行的操作後,再提出要求。如要執行這項操作,請叫用包含 ACTION_APP_OPEN_BY_DEFAULT_SETTINGS 意圖動作的意圖,以及與目標應用程式 package:com.example.pkg 相符的資料字串,如以下程式碼片段所示:
Kotlin
val context: Context = TODO("Your activity or fragment's Context")
val intent = Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
Uri.parse("package:${context.packageName}"))
context.startActivity(intent)
Java
Context context = TODO("Your activity or fragment's Context");
Intent intent = new Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
Uri.parse("package:" + context.getPackageName()));
context.startActivity(intent);
叫用意圖時,使用者會看到名為「預設開啟」的設定畫面。這個畫面包含名為「開啟支援連結」的圓形按鈕,如圖 1 所示。
使用者開啟「開啟支援的連結」後,系統會在「要在此應用程式中開啟的連結」部分下方顯示一組核取方塊。使用者可以從這裡選取要與應用程式建立關聯的網域。他們也可以選取「新增連結」來新增網域,如圖 2 所示。使用者之後選取新增網域中的任何連結時,系統會自動在應用程式中開啟連結。
在應用程式中開啟無法驗證的網域
應用程式的主要功能可能是以第三方身分開啟連結,但無法驗證處理的網域。如果是這種情況,請向使用者說明,當他們選取網頁連結時,無法在第一方應用程式和您的 (第三方) 應用程式之間選擇。使用者必須手動將網域與您的第三方應用程式建立關聯。
此外,如果使用者偏好在第一方應用程式中開啟連結,請考慮導入對話方塊或 Trampoline 活動,讓使用者能以 Proxy 的形式開啟連結。設定這類對話方塊或跳板活動前,請先設定應用程式,使其對符合應用程式網頁意圖篩選器的第一方應用程式具有套件瀏覽權限。
Digital Asset Links 更新延遲
在網路伺服器上更新 assetlinks.json 檔案後,這些變更反映在使用者裝置上的時間,取決於 OS 版本:
- Android 15 (API 級別 35) 以上版本:系統會定期在背景重新驗證網域。由於系統會快取及排定重新驗證,變更最多可能需要七天,才會套用至所有使用者裝置。
- Android 14 (API 級別 34) 以下版本:系統不會定期在背景重新驗證。通常只有在安裝或更新應用程式時,系統才會擷取檔案更新。
測試更新
如要在測試期間強制重新驗證特定裝置,可以解除安裝並重新安裝應用程式。不過請注意,即使重新安裝,伺服器端快取仍可能延遲將更新後的 assetlinks.json 檔案傳送至裝置。由於快取是以時間為依據,因此如果您在幾小時後重試,延遲通常會自動解決。