عند تنفيذ ميزة ربط التطبيقات، يجب اختبار وظيفة الربط للتأكّد من أنّ النظام يمكنه ربط تطبيقك بمواقعك الإلكترونية ومعالجة طلبات عناوين URL على النحو المتوقّع.
لاختبار ملف بيان حالي، يمكنك استخدام أداة Statement List Generator and Tester.
توضّح الأقسام التالية كيفية اختبار عملية التحقّق من روابط التطبيق يدويًا. يمكنك اختبار عملية التحقّق من خلال أداة Deep Links في Play أو "مساعِد روابط التطبيقات" في "استوديو Android".
تأكيد قائمة المضيفين المطلوب التحقّق منهم
عند الاختبار، عليك تأكيد قائمة المضيفين المرتبطين الذين يجب أن يتحقّق منهم النظام لتطبيقك. أنشئ قائمة بجميع عناوين URL التي تتضمّن فلاتر الأهداف المقابلة لها السمات والعناصر التالية:
- سمة
android:schemeبقيمةhttpأوhttps - سمة
android:hostمع نمط عنوان URL للنطاق - عنصر إجراء واحد (
android.intent.action.VIEW) - عنصر فئة واحد (
android.intent.category.BROWSABLE)
استخدِم هذه القائمة للتأكّد من توفّر ملف JSON لروابط التنقل إلى مواد العرض الرقمية على كل مضيف ونطاق فرعي مُسمّى.
تأكيد ملفات روابط التنقل إلى مواد العرض الرقمية
لكل موقع إلكتروني، استخدِم 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 لتفضيلات ربط التطبيقات لدى المستخدم. لا تشير هذه القيمة إلى ما إذا كانت عملية التحقّق قد نجحت أم لا.
مثال على الاختبار
لكي تنجح عملية التحقّق من روابط التطبيقات، يجب أن يتمكّن النظام من التحقّق من تطبيقك باستخدام كل موقع إلكتروني تحدّده في فلتر أهداف معيّن يستوفي معايير روابط التطبيقات. يوضّح المثال التالي إعدادات ملف البيان مع تحديد عدة روابط تطبيقات:
<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) التي تطابقت مع معرّف الموارد المنتظم (URI). - التحقّق من رابط التطبيق: يعرض هذا العمود حالة التحقّق الحالية من النطاق (مثل
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. - يتم تقييم قواعد "روابط التطبيقات الديناميكية" بترتيب تسلسلي من الأعلى إلى الأسفل (يتم تطبيق القاعدة الأولى المطابقة).
- بما أنّ القاعدة 0 تظهر أولاً في قائمة العبارات وهي قاعدة استبعاد (
allow = 1)، تكون لها الأولوية على قاعدة السماح العامة (القاعدة 1). - وبالتالي، يتم استبعاد التطبيق من معالجة
https://xyz.com/foo، ما يؤدي إلى رجوع النظام إلى المتصفّح أو عرض مربّع حوار لإزالة الغموض.