عند تنفيذ ميزة ربط التطبيق، عليك اختبار وظيفة الربط للتأكّد من أنّ النظام يمكنه ربط تطبيقك بمواقعك الإلكترونية والتعامل مع طلبات عناوين URL على النحو المتوقّع.
لاختبار ملف بيان حالي، يمكنك استخدام أداة إنشاء قائمة البيانات واختبارها.
توضّح الأقسام التالية كيفية اختبار عملية إثبات ملكية "روابط التطبيق" يدويًا. إذا كنت تفضّل ذلك، يمكنك اختبار عملية التحقّق من خلال أداة "روابط لصفحات في Play" أو "مساعِد روابط التطبيقات" في "استوديو Android".
تأكيد قائمة المضيفين المطلوب إثبات ملكيتهم
عند إجراء الاختبار، عليك تأكيد قائمة المضيفين المرتبطين الذين يجب أن يتحقّق النظام من تطبيقك. أنشئ قائمة بجميع عناوين URL التي تتضمّن فلاتر الأهداف المقابلة السمات والعناصر التالية:
- السمة
android:schemeمع القيمةhttpأوhttps - السمة
android:hostالتي تتضمّن نمط عنوان URL للنطاق - عنصر الإجراء
android.intent.action.VIEW - عنصر الفئة
android.intent.category.BROWSABLE
استخدِم هذه القائمة للتأكّد من توفير ملف بتنسيق JSON يتضمّن روابط تنقل إلى مواد عرض رقمية على كل مضيف فرعي ومضيف مسمّى.
تأكيد ملفات Digital Asset Links
بالنسبة إلى كل موقع إلكتروني، استخدِم Digital Asset Links API للتأكّد من أنّ ملف JSON الخاص بروابط التنقل إلى مواد العرض الرقمية مستضاف ومحدّد بشكل صحيح:
https://digitalassetlinks.googleapis.com/v1/statements:list?
source.web.site=https://<var>domain.name</var>:<var>optional_port</var>&
relation=delegate_permission/common.handle_all_urls
بالنسبة إلى "روابط التطبيقات الديناميكية"، يمكنك أيضًا التحقّق من إضافات العلاقات.
https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://www.example.com&relation=delegate_permission/common.handle_all_urls&return_relation_extensions=true
الاطّلاع على سياسات الروابط
كجزء من عملية الاختبار، يمكنك التحقّق من إعدادات النظام الحالية الخاصة بالتعامل مع الروابط. استخدِم الأمر التالي للحصول على قائمة بسياسات معالجة الروابط الحالية لجميع التطبيقات على جهازك المتصل:
adb shell dumpsys package domain-preferred-apps
يؤدي الأمر التالي الإجراء نفسه:
adb shell dumpsys package d
يعرض الأمر قائمة بكل مستخدم أو ملف شخصي محدّد على الجهاز، مسبوقًا بعنوان بالتنسيق التالي:
App linkages for user 0:
بعد هذا العنوان، يستخدم الإخراج التنسيق التالي لإدراج إعدادات معالجة الروابط الخاصة بهذا المستخدم:
Package: com.android.vending
Domains: play.google.com market.android.com
Status: always : 200000002
تعرض بطاقة البيانات هذه التطبيقات المرتبطة بالنطاقات الخاصة بالمستخدم:
-
Package: يحدّد تطبيقًا من خلال اسم الحزمة، كما هو موضّح في ملف البيان. -
Domains: تعرض هذه السمة القائمة الكاملة بالمضيفين الذين يتعامل معهم هذا التطبيق في ما يخص روابط الويب، مع استخدام مسافات فارغة كفواصل. Status: تعرض هذه السمة إعدادات معالجة الروابط الحالية لهذا التطبيق. إذا اجتاز التطبيق عملية التحقّق وكان بيانه يتضمّنandroid:autoVerify="true"، ستظهر الحالةalways. يرتبط الرقم السداسي العشري الذي يظهر بعد هذه الحالة بسجلّ نظام Android الخاص بإعدادات المستخدم المفضّلة بشأن ربط التطبيقات. لا تشير هذه القيمة إلى ما إذا كانت عملية التحقّق قد نجحت.
مثال على الاختبار
لكي ينجح التحقّق من روابط التطبيقات، يجب أن يتمكّن النظام من التحقّق من تطبيقك باستخدام كل موقع من المواقع الإلكترونية التي تحدّدها في فلتر intent معيّن يستوفي معايير روابط التطبيقات. يوضّح المثال التالي إعدادات البيان التي تتضمّن عدة روابط تطبيقات محدّدة:
<activity android:name="MainActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:scheme="https" />
<data android:host="www.example.com" />
<data android:host="mobile.example.com" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="www.example2.com" />
</intent-filter>
</activity>
<activity android:name="SecondActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="account.example.com" />
</intent-filter>
</activity>
<activity android:name="ThirdActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="https" />
<data android:host="map.example.com" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="market" />
<data android:host="example.com" />
</intent-filter>
</activity>
</application>
في ما يلي قائمة بالمضيفين الذين ستحاول المنصة إثبات ملكيتهم من البيان السابق:
www.example.com
mobile.example.com
www.example2.com
account.example.com
في ما يلي قائمة بالمضيفين الذين لن تحاول المنصة إثبات ملكيتهم من البيان السابق:
map.example.com (it does not have android.intent.category.BROWSABLE)
market://example.com (it does not have either an "http" or "https" scheme)
لمزيد من المعلومات حول قوائم الكلمات الرئيسية، يُرجى الاطّلاع على إنشاء قائمة كلمات رئيسية.
تشخيص مشاكل حلّ الروابط باستخدام العلامة debug-link
بدءًا من Android 17، يمكنك استخدام العلامة --debug-link مع أمر "مدير الأنشطة" (am start) لتشخيص طريقة حل النظام لعنوان URL معيّن. تقدّم هذه الأداة تفصيلاً دقيقًا للتطبيقات المرشّحة التي تطابقت مع الغرض، بالإضافة إلى القواعد المحدّدة من بيان التطبيق وملف assetlinks.json (لروابط التطبيقات الديناميكية) التي تم تقييمها أثناء عملية تحديد التطبيق.
لاختبار حلّ الرابط لعنوان URL معيّن، نفِّذ الأمر التالي في نافذة طرفية:
adb shell am start --debug-link -a android.intent.action.VIEW -d "https://xyz.com/foo"
تتم طباعة ناتج بيانات التشخيص تحت العنوان App Link Resolution Debug
ويتضمّن الأقسام التالية لمساعدتك في فهم عملية حل المشكلة:
- تفاصيل الاستهداف: تحدّد كل تطبيق مرشّح مطابق من خلال اسم الحزمة ونشاط الاستهداف.
- مطابقة فلتر الأهداف (
AndroidManifest.xml): تعرض هذه السمة السمات الثابتة في فلتر الأهداف في ملف البيان (مثلschemeأوhostأوpathأوpathPrefixأوpathPattern) التي تطابقت مع معرّف الموارد الموحّد. - التحقّق من صحة روابط التطبيق: تعرض هذه السمة حالة التحقّق الحالية من صحة النطاق (مثل
STATE_SUCCESS). - روابط التطبيق الديناميكية: إذا كان التطبيق يستخدم قواعد مطابقة "روابط التطبيق الديناميكية" في ملف
assetlinks.json، يسرد هذا القسم كل قاعدة تم تقييمها مقارنةً بمعرّف الموارد المنتظم (URI). تشير كل قاعدة إلى فلاتر عناوين URI المطابَقة (مثل بادئات المسار أو الأنماط) وإلى الحقلallow:allow = 0: قاعدة سماح/تضمين (allow: true). إذا كانت هذه القاعدة متطابقة، يُسمح للتطبيق بفتح معرّف الموارد المنتظم (URI).allow = 1: قاعدة حظر/استبعاد (allow: false/exclude: true). إذا كانت هذه القاعدة مطابقة، يتم منع التطبيق من فتح معرّف الموارد المنتظم (URI).- ملاحظة: تشير سلسلة الفلتر الفارغة (
filter =) إلى بادئة مسار فارغة تتطابق مع جميع المسارات ضمن النطاق (تعمل كحرف بدل أو كعنصر شامل).
مثال على نتائج تصحيح الأخطاء
لنفترض أنّ هناك تطبيقًا (com.example.xyzapp) مرتبطًا بالنطاق https://xyz.com الذي يحدّد قواعد ديناميكية في ملف assetlinks.json لاستبعاد /foo* مع السماح بجميع المسارات الأخرى:
[
{
"relation": [
"delegate_permission/common.handle_all_urls"
],
"target": {
"namespace": "android_app",
"package_name": "com.example.xyzapp",
"sha256_cert_fingerprints": ["..."]
},
"relation_extensions": {
"delegate_permission/common.handle_all_urls": {
"dynamic_app_link_components": [
{"/": "/foo*", "exclude": true},
{"/": "*"}
]
}
}
}
]
عند تشخيص عنوان URL https://xyz.com/foo باستخدام --debug-link:
adb shell am start --debug-link -a android.intent.action.VIEW -d "https://xyz.com/foo"
يعرض الأمر تفاصيل التشخيص التالية:
--- App Link Resolution Debug ---
URI: https://xyz.com/foo
Resolution: Ambiguous (Multiple apps or Browser fallback)
This usually happens when multiple apps can handle the link and no default is set.
All Matching Candidates:
Target:
Package: com.example.xyzapp
Activity: com.example.xyzapp.MainActivity
Intent Filter Match (AndroidManifest.xml)
Scheme: 'https' matched android:scheme="https"
Host: 'xyz.com' matched android:host="xyz.com"
App Link Verification:
Verification status: STATE_SUCCESS
Dynamic App Links:
-> Matched Rule 0: UriRelativeFilterGroup { allow = 1, uri_filters = {UriRelativeFilter { uriPart = PATH, patternType = PREFIX, filter = /foo }}, }
-> Matched Rule 1: UriRelativeFilterGroup { allow = 0, uri_filters = {UriRelativeFilter { uriPart = PATH, patternType = PREFIX, filter = }}, }
Target:
Package: org.chromium.webview_shell
Activity: org.chromium.webview_shell.WebViewBrowserActivity
Intent Filter Match (AndroidManifest.xml)
Scheme: 'https' matched android:scheme="https"
---------------------------------
Starting: Intent { act=android.intent.action.VIEW dat=https://xyz.com/foo }
في هذا المثال، قيّم النظام قاعدتَي "روابط التطبيق الديناميكية" من
assetlinks.json:
- القاعدة 0 (
allow = 1،filter = /foo): تم إنشاؤها من{"/": "/foo*", "exclude": true}، وهي قاعدة استبعاد (allow: false) تحظر عناوين URL التي تبدأ ببادئة المسار/foo. - القاعدة 1 (
allow = 0،filter =): تم إنشاؤها من{"/": "*"}، وهي قاعدة تضمين (allow: true) تتضمّن بادئة مسار فارغة (filter =)، ما يؤدي إلى مطابقة جميع المسارات ضمنxyz.com(قاعدة شاملة).
طريقة عمل تحديد المشكلة في هذا السيناريو:
- تتطابق كلّ من القاعدة 0 والقاعدة 1 مع عنوان URL
https://xyz.com/foo. - يتم تقييم قواعد App Link الديناميكية بترتيب تسلسلي من الأعلى إلى الأسفل (القاعدة الأولى التي تتطابق هي التي يتم تطبيقها).
- بما أنّ القاعدة 0 تظهر أولاً في قائمة العبارات وهي قاعدة استبعاد (
allow = 1)، تكون لها الأولوية على قاعدة السماح العامة (القاعدة 1). - وبالتالي، يتم استبعاد التطبيق من معالجة
https://xyz.com/foo، ما يؤدي إلى أن يعود النظام إلى المتصفّح أو يعرض مربّع حوار لإزالة الغموض.