رابط التطبيق المتوافق مع Android هو نوع خاص من الروابط لصفحات في التطبيق يتيح لعناوين URL الخاصة بموقعك الإلكتروني فتح المحتوى ذي الصلة في تطبيق Android على الفور، بدون أن يضطر المستخدم إلى اختيار التطبيق. تستخدم روابط التطبيقات المتوافقة مع Android واجهة برمجة التطبيقات Digital Asset Links لإثبات أنّ موقعك الإلكتروني قد وافق على فتح الروابط تلقائيًا لهذا النطاق في تطبيقك. إذا تحقّق النظام بنجاح من أنّك تملك عناوين URL، سيوّجه النظام تلقائيًا طلبات البحث عن عناوين URL هذه إلى تطبيقك.
لإثبات ملكيتك لكل من تطبيقك وعناوين URL للموقع الإلكتروني، أكمِل الخطوات التالية:
أضِف فلاتر أهداف تحتوي على السمة
autoVerify
. تشير هذه السمة إلى النظام بأنّه يجب التحقّق مما إذا كان تطبيقك ينتمي إلى نطاقات عناوين URL المستخدَمة في فلاتر الأهداف.حدِّد الربط بين موقعك الإلكتروني وفلاتر الأهداف من خلال استضافة ملف JSON الذي يحتوي على روابط تنقل إلى مواد عرض رقمية في الموقع التالي:
https://domain.name/.well-known/assetlinks.json
يمكنك العثور على معلومات ذات صلة في المَراجع التالية:
إضافة فلاتر الأهداف للتحقّق من روابط التطبيق
لتفعيل عملية التحقّق من إمكانية معالجة الروابط في تطبيقك، أضِف فلاتر الأهداف التي تتطابق مع التنسيق التالي:
<!-- Make sure you explicitly set android:autoVerify to "true". -->
<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" />
<!-- If a user clicks on a shared link that uses the "http" scheme, your
app should be able to delegate that traffic to "https". -->
<!-- Do not include other schemes. -->
<data android:scheme="http" />
<data android:scheme="https" />
<!-- Include one or more domains that should be verified. -->
<data android:host="..." />
</intent-filter>
على الرغم من أنّه يكفي تضمين autoVerify
في بيان <intent-filter>
واحد فقط لكل مضيف، حتى إذا كان هذا المضيف مستخدَمًا في بيانات أخرى غير موسومة، ننصحك بإضافة autoVerify
إلى كل عنصر <intent-filter>
للحفاظ على الاتساق. يضمن ذلك أيضًا أن يظل تطبيقك مرتبطًا بجميع النطاقات التي لا تزال تحدّدها بعد إزالة العناصر أو إعادة هيكلتها في ملف البيان.
تتطلّب عملية إثبات ملكية النطاق الاتصال بالإنترنت وقد تستغرق بعض الوقت. للمساعدة في تحسين كفاءة العملية، يتحقّق النظام من صحة نطاق لتطبيق يستهدف الإصدار 12 من نظام التشغيل Android أو الإصدارات الأحدث فقط إذا كان هذا النطاق ضِمن عنصر <intent-filter>
يحتوي على التنسيق الدقيق المحدّد في مقتطف الرمز السابق.
على سبيل المثال، ستؤدي المخططات بخلاف "http" و "https"، مثل <data android:scheme="custom" />
، إلى منع <intent-filter>
من بدء عملية إثبات ملكية النطاق.
إتاحة ربط التطبيقات بمواقع إلكترونية متعددة
يجب أن يتمكّن النظام من التحقّق من المضيف المحدّد في عناصر البيانات الخاصة بفلاتر الأهداف الخاصة بعناوين URL للتطبيقات، وذلك من خلال مقارنتها بملفات Digital Asset Links المستضافة على نطاقات الويب المعنية في فلتر الأهداف هذا. وفي حال تعذُّر إثبات الملكية، يعود النظام إلى سلوكه العادي لتنفيذ الغرض، كما هو موضّح في مقالة إنشاء روابط لصفحات معيّنة في التطبيق. ومع ذلك، سيظل بإمكانك إثبات ملكية التطبيق كمعالج تلقائي لأي من أنماط عناوين URL المحدّدة في فلاتر intent الأخرى الخاصة بالتطبيق.
ملاحظة: على نظام التشغيل Android 11 (المستوى 30 لواجهة برمجة التطبيقات) والإصدارات الأقدم، لا يتحقّق النظام من أنّ تطبيقك هو المعالج التلقائي إلا إذا عثر على ملف روابط التنقل إلى مواد العرض الرقمية مطابق لجميع المضيفين الذين تحدّدهم في ملف البيان.
على سبيل المثال، لن يجتاز تطبيق يتضمّن فلاتر الأهداف التالية عملية التحقّق إلا بالنسبة إلى https://www.example.com
إذا تم العثور على ملف assetlinks.json
في https://www.example.com/.well-known/assetlinks.json
وليس في https://www.example.net/.well-known/assetlinks.json
:
<application> <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="http" /> <data android:scheme="https" /> <data android:host="www.example.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="www.example.net" /> </intent-filter> </activity> </application>
ملاحظة: يتم دمج جميع عناصر <data>
في فلتر الأهداف نفسه معًا لاحتساب جميع أشكال سماتها المجمّعة. على سبيل المثال، يتضمّن فلتر الأهداف الأول أعلاه عنصر <data>
يعرّف مخطط HTTPS فقط. ولكن يتم دمجه مع عنصر <data>
الآخر لكي يتيح فلتر الأهداف كلاً من http://www.example.com
وhttps://www.example.com
.
وبناءً على ذلك، يجب إنشاء فلاتر أهداف منفصلة عند تحديد مجموعات معيّنة من مخططات URI والنطاقات.
إتاحة ربط التطبيقات بنطاقات فرعية متعددة
يتعامل بروتوكول Digital Asset Links مع النطاقات الفرعية في فلاتر الأهداف على أنّها مضيفات فريدة ومنفصلة. لذلك، إذا كان فلتر الأهداف يتضمّن عدة مضيفين بنطاقات فرعية مختلفة، عليك نشر ملف assetlinks.json
صالح على كل نطاق. على سبيل المثال، يتضمّن فلتر الأهداف التالي www.example.com
وmobile.example.com
كمضيفَين مقبولَين لعنوان URL الخاص بالهدف. لذلك، يجب نشر assetlinks.json
صالح في كل من https://www.example.com/.well-known/assetlinks.json
وhttps://mobile.example.com/.well-known/assetlinks.json
.
<application> <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> </activity> </application>
بدلاً من ذلك، إذا حدّدت اسم المضيف باستخدام حرف بدل (مثل *.example.com
)، عليك نشر ملف assetlinks.json
في اسم المضيف الجذر (example.com
). على سبيل المثال، سيتجاوز تطبيق يتضمّن فلتر الأهداف التالي عملية التحقّق لأي اسم فرعي من example.com
(مثل foo.example.com
) طالما تم نشر ملف assetlinks.json
في https://example.com/.well-known/assetlinks.json
:
<application> <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:host="*.example.com" /> </intent-filter> </activity> </application>
التحقّق من وجود تطبيقات متعدّدة مرتبطة بالنطاق نفسه
إذا نشرت تطبيقات متعددة يرتبط كل منها بالنطاق نفسه، يمكن إثبات ملكية كل تطبيق بنجاح. ومع ذلك، إذا كانت التطبيقات يمكنها تحديد المضيف والمسار نفسهما للنطاق، كما هو الحال مع الإصدارات المخفّفة والكاملة من التطبيق، لن يتمكّن سوى التطبيق الذي تم تثبيته مؤخرًا من تحديد طلبات البحث على الويب لهذا النطاق.
في مثل هذه الحالة، تحقَّق من التطبيقات التي قد تتعارض مع بعضها على جهاز المستخدم،
شرط أن يكون لديك إذن الوصول إلى حزمة
التطبيق اللازم. بعد ذلك، في تطبيقك، اعرض مربّع حوار مخصّصًا لاختيار التطبيق يتضمّن النتائج التي تم الحصول عليها من خلال استدعاء queryIntentActivities()
.
يمكن للمستخدم اختيار التطبيق المفضّل من قائمة التطبيقات المطابقة التي تظهر في مربّع الحوار.
تحديد عمليات الربط بالمواقع الإلكترونية
يجب نشر ملف بتنسيق JSON لروابط التنقل إلى مواد العرض الرقمية على موقعك الإلكتروني للإشارة إلى تطبيقات Android المرتبطة بالموقع الإلكتروني والتحقّق من صحة نوايا عناوين URL للتطبيق. يستخدم ملف JSON الحقول التالية لتحديد التطبيقات المرتبطة:
package_name
: معرّف التطبيق المحدّد في ملفbuild.gradle
الخاص بالتطبيقsha256_cert_fingerprints
: الملفات المرجعية لخوارزمية SHA256 لشهادة توقيع تطبيقك يمكنك استخدام الأمر التالي لإنشاء بصمة الإصبع من خلال أداة keytool في Java: يتيح هذا الحقل استخدام بصمات متعددة يمكن استخدامها لتوفير الدعم لإصدارات مختلفة من تطبيقك، مثل إصدارات تصحيح الأخطاء وإصدارات الإنتاج.keytool -list -v -keystore my-release-key.keystore
إذا كنت تستخدم خدمة "توقيع التطبيق" من Play لتطبيقك، لن يتطابق ملف الشهادة المرجعي الذي يتم إنشاؤه من خلال تنفيذ
keytool
محليًا مع الملف الموجود على أجهزة المستخدمين. يمكنك التحقّق مما إذا كنت تستخدم ميزة "توقيع التطبيق" من Play لتطبيقك في حساب المطوِّر الخاص بك على Play Console ضمنRelease > Setup > App signing
. وفي حال استخدامها، ستعثر أيضًا على المقتطف الصحيح لملف JSON الخاص بروابط التنقل إلى مواد العرض الرقمية لتطبيقك في الصفحة نفسها.
يمنح ملف المثال التالي assetlinks.json
حقوق فتح الروابط إلى تطبيق Android com.example
:
[{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example", "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"] } }]
ربط موقع إلكتروني بعدة تطبيقات
يمكن للموقع الإلكتروني الإعلان عن عمليات ربط بتطبيقات متعددة ضمن ملف assetlinks.json
نفسه. تعرض قائمة الملفات التالية مثالاً لملف بيان يوضّح الربط بتطبيقَين بشكل منفصل، ويقع في https://www.example.com/.well-known/assetlinks.json
:
[{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example.puppies.app", "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.example.monkeys.app", "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"] } }]
قد تتعامل تطبيقات مختلفة مع روابط لموارد مختلفة ضمن مضيف الويب نفسه. على سبيل المثال، قد يعلن التطبيق 1 عن فلتر هدف لـ https://example.com/articles
، وقد يعلن التطبيق 2 عن فلتر هدف لـ https://example.com/videos
.
ملاحظة: قد يتم توقيع تطبيقات متعددة مرتبطة بنطاق باستخدام الشهادة نفسها أو شهادات مختلفة.
ربط مواقع إلكترونية متعدّدة بتطبيق واحد
يمكن أن تعلن مواقع إلكترونية متعددة عن ارتباطها بالتطبيق نفسه في ملفات assetlinks.json
الخاصة بها. توضّح القوائم التالية للملفات
مثالاً على كيفية الإفصاح عن الربط بين example.com وexample.net بالتطبيق app1. تعرض البطاقة الأولى عملية الربط بين example.com
وapp1:
https://www.example.com/.well-known/assetlinks.json
[{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.mycompany.app1", "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"] } }]
تعرض البطاقة التالية ربط example.net بتطبيق app1. يختلف فقط الموقع الذي تتم استضافة هذه الملفات فيه (.com
و.net
):
https://www.example.net/.well-known/assetlinks.json
[{ "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.mycompany.app1", "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
يُرجى التأكّد مما يلي:
- يتم عرض الملف
assetlinks.json
مع نوع المحتوىapplication/json
. - يجب أن يكون ملف
assetlinks.json
قابلاً للوصول إليه عبر اتصال HTTPS، بغض النظر عمّا إذا كانت فلاتر الأهداف في تطبيقك تحدّد HTTPS كمخطط للبيانات. - يجب أن يكون ملف
assetlinks.json
قابلاً للوصول إليه بدون أي عمليات إعادة توجيه (بدون عمليات إعادة توجيه 301 أو 302). - إذا كانت روابط تطبيقك تتيح استخدام نطاقات مضيفة متعددة، عليك نشر ملف
assetlinks.json
على كل نطاق. اطّلِع على إتاحة ربط التطبيقات بمضيفين متعدّدين. - يُرجى عدم نشر تطبيقك مع عناوين URL خاصة بالتطوير/الاختبار في ملف البيان قد لا تكون متاحة للجميع (مثل أي عناوين URL لا يمكن الوصول إليها إلا من خلال شبكة VPN). في مثل هذه الحالات، يمكنك ضبط صيغ الإنشاء لإنشاء ملف بيان مختلف لإصدارات التطبيق المخصّصة للمطوّرين.
التحقّق من روابط التطبيقات المتوافقة مع Android
عندما تكون السمة android:autoVerify="true"
متوفّرة في فلتر واحد على الأقل من فلاتر الأهداف في تطبيقك، يؤدي تثبيت تطبيقك على جهاز يعمل بالإصدار 6.0 من نظام التشغيل Android (المستوى 23 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث إلى أن يتحقّق النظام تلقائيًا من المضيفين المرتبطين بعناوين URL في فلاتر الأهداف في تطبيقك. على نظام التشغيل Android 12 والإصدارات الأحدث، يمكنك أيضًا بدء عملية إثبات الهوية يدويًا لاختبار منطق إثبات الهوية.
التحقّق التلقائي
تتضمّن عملية التحقّق التلقائي من النظام ما يلي:
- يفحص النظام جميع فلاتر الأهداف التي تتضمّن أيًا مما يلي:
- الإجراء:
android.intent.action.VIEW
- الفئات:
android.intent.category.BROWSABLE
وandroid.intent.category.DEFAULT
- مخطط البيانات:
http
أوhttps
- الإجراء:
- بالنسبة إلى كل اسم مضيف فريد تم العثور عليه في فلاتر الأهداف أعلاه، يطلب نظام التشغيل Android ملف Digital Asset Links من المواقع الإلكترونية المقابلة على
https://hostname/.well-known/assetlinks.json
.
بعد تأكيد قائمة المواقع الإلكترونية التي تريد ربطها بتطبيقك، وبعد التأكّد من أنّ ملف JSON المستضاف صالح، ثبِّت التطبيق على جهازك. انتظِر لمدة 20 ثانية على الأقل كي تكتمل عملية إثبات الهوية غير المتزامنة. استخدِم الأمر التالي للتحقّق مما إذا كان النظام قد تحقّق من تطبيقك وضبط سياسات معالجة الروابط الصحيحة:
adb shell am start -a android.intent.action.VIEW \ -c android.intent.category.BROWSABLE \ -d "http://domain.name:optional_port"
التحقّق اليدوي
بدءًا من الإصدار 12 من نظام التشغيل Android، يمكنك تفعيل عملية إثبات ملكية النطاق يدويًا لتطبيق مثبَّت على جهاز. يمكنك تنفيذ هذه العملية بغض النظر عمّا إذا كان تطبيقك يستهدف الإصدار 12 من نظام التشغيل Android.
الاتصال بالإنترنت
لإثبات ملكية النطاق، يجب أن يكون جهاز الاختبار متصلاً بالإنترنت.
إتاحة عملية إثبات ملكية النطاق المعدَّلة
إذا كان تطبيقك يستهدف الإصدار 12 من نظام التشغيل Android أو الإصدارات الأحدث، سيستخدم النظام تلقائيًا عملية إثبات ملكية النطاق المعدَّلة.
ويمكنك بدلاً من ذلك تفعيل عملية تأكيد الحساب المعدَّلة يدويًا. لإجراء ذلك، نفِّذ الأمر التالي في نافذة الوحدة الطرفية:
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
- تمت الموافقة على النطاق بشكل إلزامي، وعادةً ما يتم ذلك من خلال تنفيذ أمر shell.
denied
- تم رفض النطاق بشكل إجباري، وعادةً ما يتم ذلك من خلال تنفيذ أمر shell.
migrated
- احتفظ النظام بنتيجة عملية سابقة استخدمت طريقة التحقّق القديمة من النطاق.
restored
- تمت الموافقة على النطاق بعد أن نفّذ المستخدم عملية استعادة البيانات. يُفترض أنّه تم إثبات ملكية النطاق من قبل.
legacy_failure
- رفضت أداة التحقّق القديمة النطاق. سبب تعذّر النقل غير معروف.
system_configured
- تمت الموافقة على النطاق تلقائيًا من خلال إعدادات الجهاز.
- رمز الخطأ
1024
أو أكبر رمز خطأ مخصّص خاص بأداة التحقّق من الجهاز.
يُرجى التأكّد من إنشاء اتصال بالشبكة، ثم تكرار عملية إثبات ملكية النطاق.
أن تطلب من المستخدم ربط تطبيقك بنطاق
هناك طريقة أخرى للحصول على الموافقة على استخدام نطاق معيّن في تطبيقك، وهي أن تطلب من المستخدم ربط تطبيقك بهذا النطاق.
التحقّق مما إذا تمت الموافقة على تطبيقك من قبل للنطاق
قبل أن تطلب من المستخدم ذلك، تحقَّق مما إذا كان تطبيقك هو المعالج التلقائي للنطاقات التي تحدّدها في عناصر <intent-filter>
. يمكنك طلب حالة الموافقة باستخدام إحدى الطرق التالية:
DomainVerificationManager
API (في وقت التشغيل)- برنامج سطر أوامر (أثناء الاختبار)
DomainVerificationManager
يوضّح مقتطف الرمز التالي كيفية استخدام واجهة برمجة التطبيقات DomainVerificationManager
:
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
يمكنك أيضًا استخدام أوامر shell لمحاكاة العملية التي يختار فيها المستخدم التطبيق المرتبط بنطاق معيّن. يمكنك الاطّلاع على شرح كامل لهذه الأوامر من خلال ناتج adb shell pm
.
توفير سياق للطلب
قبل تقديم طلب الموافقة على النطاق، قدِّم بعض المعلومات الأساسية للمستخدم. على سبيل المثال، يمكنك عرض شاشة البداية أو مربّع حوار أو عنصر مشابه لواجهة المستخدم يوضّح للمستخدم سبب وجوب أن يكون تطبيقك هو المعالج التلقائي لنطاق معيّن.
تقديم الطلب
بعد أن يفهم المستخدم ما يطلبه منه تطبيقك، قدِّم الطلب.
لإجراء ذلك، استدعِ هدفًا يتضمّن
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. عندما يختار المستخدمون لاحقًا أي رابط ضمن النطاقات التي يضيفونها، سيتم فتح الرابط في تطبيقك تلقائيًا.
نطاقات مفتوحة في تطبيقك لا يمكن لتطبيقك إثبات ملكيتها
قد تكون الوظيفة الرئيسية لتطبيقك هي فتح الروابط كجهة خارجية، بدون إمكانية التحقّق من النطاقات التي يتعامل معها. في هذه الحالة، عليك توضيح للمستخدمين أنّه عند النقر على رابط ويب، لن يتمكّنوا من الاختيار بين تطبيق تابع للجهة الأولى وتطبيقك (التابع لجهة خارجية)، بل عليهم ربط النطاقات يدويًا بتطبيقك التابع لجهة خارجية.
بالإضافة إلى ذلك، ننصحك بعرض مربّع حوار أو نشاط "القفز" يتيح للمستخدم فتح الرابط في تطبيق الطرف الأول إذا كان يفضّل ذلك، ما يجعله يعمل كخادم وكيل. قبل إعداد مربع حوار أو نشاط "ترامبولين"، يجب إعداد تطبيقك ليتضمّن إذن الوصول إلى الحزمة للتطبيقات التابعة للجهة الأولى التي تتطابق مع فلتر الأهداف على الويب في تطبيقك.
اختبار روابط التطبيقات
عند تنفيذ ميزة ربط التطبيق، يجب اختبار وظيفة الربط للتأكّد من أنّ النظام يمكنه ربط تطبيقك بمواقعك الإلكترونية والتعامل مع طلبات عناوين URL على النحو المتوقّع.
لاختبار ملف بيان حالي، يمكنك استخدام أداة إنشاء قائمة البيانات واختبارها.
تأكيد قائمة المضيفين المطلوب إثبات ملكيتهم
عند إجراء الاختبار، عليك التأكّد من قائمة المضيفين المرتبطين التي يجب أن يتحقّق منها النظام لتطبيقك. أنشئ قائمة بجميع عناوين URL التي تتضمّن فلاتر الأهداف المقابلة السمات والعناصر التالية:
- السمة
android:scheme
مع القيمةhttp
أوhttps
- السمة
android:host
التي تتضمّن نمط عنوان URL للنطاق - عنصر الإجراء
android.intent.action.VIEW
- عنصر الفئة
android.intent.category.BROWSABLE
استخدِم هذه القائمة للتأكّد من توفير ملف بتنسيق JSON يتضمّن روابط تنقل إلى مواد عرض رقمية على كل مضيف ونطاق فرعي محدّدَين.
تأكيد ملفات Digital Asset Links
بالنسبة إلى كل موقع إلكتروني، استخدِم واجهة برمجة التطبيقات Digital Asset Links للتأكّد من أنّ ملف JSON الخاص بروابط التنقل إلى مواد العرض الرقمية مستضاف ومحدّد بشكل صحيح:
https://digitalassetlinks.googleapis.com/v1/statements:list? source.web.site=https://domain.name:optional_port& relation=delegate_permission/common.handle_all_urls
الاطّلاع على سياسات الروابط
في إطار عملية الاختبار، يمكنك التحقّق من إعدادات النظام الحالية للتعامل مع الروابط. استخدِم الأمر التالي للحصول على قائمة بسياسات معالجة الروابط الحالية لجميع التطبيقات على جهازك المتصل:
adb shell dumpsys package domain-preferred-apps
أو يمكن استخدام ما يلي لتنفيذ الإجراء نفسه:
adb shell dumpsys package d
ملاحظة: احرص على الانتظار لمدة 20 ثانية على الأقل بعد تثبيت تطبيقك للسماح للنظام بإكمال عملية التحقّق.
يعرض الأمر قائمة بكل مستخدم أو ملف شخصي محدّد على الجهاز، ويسبقها عنوان بالتنسيق التالي:
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 معيّن يستوفي معايير روابط التطبيقات. يوضّح المثال التالي إعدادات البيان التي تتضمّن العديد من روابط التطبيق المحدّدة:
<application> <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)
لمزيد من المعلومات حول قوائم العبارات، يُرجى الاطّلاع على إنشاء قائمة عبارات.
حلّ أخطاء التنفيذ الشائعة
إذا تعذّر عليك إثبات ملكية روابط تطبيقات Android، تحقَّق من الأخطاء الشائعة التالية. يستخدم هذا القسم example.com
كاسم نطاق نائب. عند إجراء عمليات التحقّق هذه، استبدِل example.com
باسم النطاق الفعلي للخادم.
- إعداد فلتر intent غير صحيح
- تحقَّق مما إذا كنت قد أدرجت عنوان URL لا يملكه تطبيقك في عنصر
<intent-filter>
. - إعدادات الخادم غير صحيحة
تحقَّق من إعدادات JSON الخاصة بالخادم، وتأكَّد من أنّ قيمة SHA صحيحة.
عليك أيضًا التأكّد من أنّ
example.com.
(مع النقطة الأخيرة) يعرض المحتوى نفسه الذي يعرضهexample.com
.- عمليات إعادة التوجيه من جهة الخادم
لا يتحقّق النظام من أي روابط لتطبيقات Android في تطبيقك إذا أعددت عملية إعادة توجيه مثل ما يلي:
- من
http://example.com
إلى https://example.com
- من
example.com
إلى www.example.com
ويحمي هذا السلوك أمان تطبيقك.
- من
- متانة الخادم
تحقَّق مما إذا كان بإمكان الخادم الاتصال بتطبيقات العميل.
- الروابط التي لا يمكن التحقّق منها
لأغراض الاختبار، يمكنك إضافة روابط لا يمكن التحقّق منها عن قصد. يُرجى العِلم أنّه على نظام التشغيل Android 11 والإصدارات الأقدم، تؤدي هذه الروابط إلى عدم تحقّق النظام من جميع روابط التطبيقات على Android لتطبيقك.
- توقيع غير صحيح في ملف assetlinks.json
تأكَّد من أنّ توقيعك صحيح ويتطابق مع التوقيع المستخدَم لتوقيع تطبيقك. تشمل الأخطاء الشائعة ما يلي:
- توقيع التطبيق باستخدام شهادة تصحيح الأخطاء وتضمين توقيع الإصدار فقط في
assetlinks.json
- أن يكون لديك توقيع بأحرف صغيرة في
assetlinks.json
يجب أن يكون التوقيع بالأحرف الكبيرة. - إذا كنت تستخدم ميزة "توقيع التطبيق" من Play، تأكَّد من استخدام التوقيع الذي تستخدمه Google لتوقيع كل إصدار من إصداراتك. يمكنك التحقّق من هذه التفاصيل، بما في ذلك مقتطف JSON كامل، باتّباع التعليمات حول تحديد المواقع الإلكترونية المرتبطة.
- توقيع التطبيق باستخدام شهادة تصحيح الأخطاء وتضمين توقيع الإصدار فقط في