إضافة فلاتر الأهداف لروابط التطبيقات

"روابط التطبيقات" هي روابط لصفحات معيّنة تستخدم بروتوكول HTTP أو HTTPS ويتحقّق نظام التشغيل Android من ارتباطها بموقعك الإلكتروني. لتسجيل تطبيقك لمعالجة روابط التطبيقات، اتّبِع الخطوات التالية:

  1. أضِف فلتر Intent واحدًا أو أكثر إلى بيان تطبيقك يحدّد نطاق موقعك الإلكتروني أو عناوين URL الخاصة به.
  2. أضِف autoVerify="true"attribute إلى عناصر intent filter. يشير ذلك إلى النظام بأنّه يجب محاولة التحقّق من المخطط ونطاقات المضيف مقابل إعدادات assetlinks.json لموقعك الإلكتروني.
  3. الإعلان عن عمليات الربط بالمواقع الإلكترونية

في ما يلي مثال على بيان "رابط التطبيق" يتضمّن المخططات والمضيفين بالإضافة إلى autoVerify="true":

<activity
    android:name=".MainActivity"
    android:exported="true"
    ...>
    <!-- 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 link that uses the "http" scheme, your
             app should be able to delegate that traffic to "https". -->
        <!-- Do not include other schemes, as this will prevent verification. -->
        <data android:scheme="http" />
        <data android:scheme="https" />

        <!-- Include one or more domains that should be verified. -->
        <data android:host="www.example.com" />
        <data android:host="*.example.com" />
    </intent-filter>
</activity>

نقاط رئيسية حول الرمز

  • التحقّق التلقائي: السمة android:autoVerify="true" مطلوبة لروابط التطبيقات. ويشير إلى النظام بأنّه يجب محاولة التحقّق من الربط بين تطبيقك والمخططات والنطاقات المحدّدة في علامات <data>. ننصحك بإضافة autoVerify="true" إلى كل فلتر Intent تريد أن يكون قابلاً للتحقّق منه.
  • عناصر البيانات: يجب أن يتضمّن كل فلتر intent في &quot;روابط التطبيقات&quot; عنصرًا واحدًا أو أكثر من عناصر <data> التي تحدّد المخططات وتنسيقات المضيف التي تتطابق مع نطاق موقعك الإلكتروني القابل للتحقّق منه.
  • المخططات: يجب أن يتضمّن تعبير intent filter عناصر <data> لكلّ من المخططَين http وhttps.
  • المضيفون: يمكنك اختياريًا إضافة عناصر <data> لمطابقة مضيف واحد أو أكثر. استخدِم حرف بدل (*) لمطابقة نطاقات فرعية متعددة (مثل *.example.com). سيحاول النظام التحقّق من كل مضيف من خلال ملف assetlinks.json على موقعك الإلكتروني. يُرجى العِلم أنّ أي توجيه على مستوى المسار يجب أن يتم التعامل معه من خلال ملف assetlinks.json (يُرجى الاطّلاع على قسم أفضل الممارسات أدناه).

  • نطاقات مضيفة متعددة: إذا أعلنت عن نطاقات مضيفة متعددة، يحاول النظام (على Android 12 والإصدارات الأحدث) التحقّق من كل منها. إذا تم التحقّق من أي مضيف، يصبح التطبيق المعالج التلقائي للروابط من ذلك المضيف الذي تم التحقّق منه. على Android 11 والإصدارات الأقدم، يتعذّر التحقّق إذا لم يتم التحقّق من مضيف واحد على الأقل.

  • فلاتر Intent متعددة: من المهم إنشاء فلاتر منفصلة عندما يكون هدفك هو الإعلان عن عناوين URL فريدة (مثل مجموعة معيّنة من المخطط والمضيف)، لأنّ عناصر <data> المتعددة في فلتر Intent نفسه يتم دمجها معًا لمراعاة جميع صيغ سماتها المجمّعة.

اعتبارات حول قواعد فلترة البيان

إذا كنت بصدد إعداد فلاتر لاستخدامها مع &quot;روابط التطبيق الديناميكية&quot; في الإصدار 15 من نظام التشغيل Android والإصدارات الأحدث، من المهمّ أن تتذكّر أنّ القواعد الديناميكية المحدّدة في ملف assetlinks.json من جهة الخادم لا يمكنها توسيع نطاق قواعد عناوين URL التي تحدّدها بشكل ثابت في بيان تطبيقك.

لهذا السبب، ننصحك باتّباع هذا النهج:

  • في بيان تطبيقك، اضبط أوسع نطاق ممكن، مثلاً من خلال تحديد المخطط والنطاق فقط
  • يمكنك الاعتماد على قواعد assetlinks.json من جهة الخادم لإجراء المزيد من التحسينات، مثل التوجيه على مستوى المسار.

باستخدام هذه الإعدادات المثالية، ستتمكّن من إضافة مسارات جديدة لروابط التطبيقات بشكل ديناميكي في ملف assetlinks.json حسب الحاجة، مع العلم أنّها ستتناسب مع النطاق الواسع الذي حدّدته في ملف بيان التطبيق.

إتاحة روابط التطبيقات لمضيفين متعددين

يجب أن يتمكّن النظام من التحقّق من المضيف المحدّد في عناصر بيانات فلاتر الأهداف لعنوان URL الخاص بالتطبيق مقارنةً بملفات &quot;روابط تنقّل إلى مواد عرض رقمية&quot; المستضافة على نطاقات الويب المعنيّة في فلتر الأهداف هذا. إذا تعذّر إثبات الملكية، يعود النظام تلقائيًا إلى سلوكه العادي لحلّ الغرض، كما هو موضّح في إنشاء روابط عميقة لمحتوى التطبيق. ومع ذلك، يمكن التحقّق من التطبيق كمعالج تلقائي لأي من أنماط عناوين URL المحدّدة في intent filter الأخرى للتطبيق.

على سبيل المثال، إذا كان التطبيق يتضمّن فلاتر الأهداف التالية، سيتم التحقّق من ملكية النطاق 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>

إتاحة ربط التطبيقات بنطاقات فرعية متعددة

يتعامل بروتوكول "روابط التنقّل إلى مواد العرض الرقمية" مع النطاقات الفرعية في فلاتر الأهداف على أنّها مضيفون فريدون ومنفصلون. لذا، إذا كان intent filter يتضمّن عدة مضيفين بنطاقات فرعية مختلفة، يجب نشر ملف assetlinks.json صالح على كل نطاق. على سبيل المثال، يتضمّن intent filter التالي www.example.com وmobile.example.com كمضيفَي عناوين URL لـ intent المقبولة. لذلك، يجب نشر 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. يمكن للمستخدم اختيار تطبيقه المفضّل من قائمة التطبيقات المطابقة التي تظهر في مربّع الحوار.

لا تتوفّر ميزات &quot;روابط التطبيقات&quot; الديناميكية، بما في ذلك قواعد المطابقة المتقدّمة في assetlinks.json واستخدام <uri-relative-filter-group>، إلا على الإصدار 15 من نظام التشغيل Android (مستوى واجهة برمجة التطبيقات 35) والإصدارات الأحدث.

في الإصدار 14 من نظام التشغيل Android (مستوى واجهة برمجة التطبيقات 34) والإصدارات الأقدم، لا يأخذ النظام في الاعتبار سوى السمتَين scheme وhost المحدَّدتَين في عناصر <data> في ملف البيان للتحقّق من App Link. لا يتم تطبيق القواعد والاستثناءات الخاصة بالمسار والتحديثات الديناميكية من ملف assetlinks.json.

وهذا يعني أنّه إذا كان ملف البيان يحدّد فقط scheme وhost، قد يلتقط تطبيقك بشكل غير متوقّع جميع المسارات للنطاق الذي تم التحقّق منه على الإصدار 14 من Android والإصدارات الأقدم، بغض النظر عن القواعد الخاصة بالمسار المحدّدة في assetlinks.json للإصدار 15 من Android والإصدارات الأحدث.

لمنع تطبيقك من معالجة جميع الروابط الخاصة بنطاق معيّن على Android 14 والإصدارات الأقدم عندما تنوي استخدام "روابط التطبيقات الديناميكية" لمسارات أكثر تحديدًا على Android 15 والإصدارات الأحدث، يمكنك تضمين مسار غير مطابق في فلتر الأهداف الخاص ببيان التطبيق. أضِف عنصر <data> مع سمة android:path من غير المرجّح أن تكون مسارًا صالحًا لروابطك. يضمن ذلك عدم مطابقة intent filter لجميع المسارات في الإصدارات الأقدم.

مثال:

<activity
    android:name=".MainActivity"
    android:exported="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" />

        <data android:scheme="http" />
        <data android:scheme="https" />
        <data android:host="www.example.com" />

        <!-- Add a non-matching path for backward compatibility -->
        <data android:path="/no_match_for_older_android_versions" />

        <uri-relative-filter-group android:allow="true">
          <data android:pathPattern="/.*"/>
        </uri-relative-filter-group>
    </intent-filter>
</activity>

من خلال إضافة <data android:path="/no_match_for_older_android_versions" />، يمكنك التأكّد من أنّ فلتر الأهداف هذا لا يتطابق مع أي روابط واردة على الإصدار 14 من Android والإصدارات الأقدم، مع السماح بالتحقّق من النطاق لاستخدامه مع "روابط التطبيقات الديناميكية" على الإصدار 15 من Android والإصدارات الأحدث استنادًا إلى قواعد المطابقة المتقدّمة في قواعد assetlinks.json.

إذا كان لديك حاليًا &quot;روابط التطبيقات&quot; مع قواعد مسارات محدّدة (مثل android:pathPrefix) في بيان التطبيق وأردت البدء في استخدام &quot;روابط التطبيقات الديناميكية&quot; على Android 15 والإصدارات الأحدث، يمكنك إضافة العنصر <uri-relative-filter-group> بأمان مباشرةً إلى فلاتر الأهداف الحالية.

بما أنّ الإصدار 14 من Android والإصدارات الأقدم تتجاهل العنصر <uri-relative-filter-group>، ستستمر روابط التطبيق الحالية في العمل تمامًا كما تعمل الآن على الأجهزة التي تعمل بإصدارات أقدم من Android.

ومع ذلك، يجب أن تضع في اعتبارك بعناية كيف يقيّم Android 15 والإصدارات الأحدث الإعدادات "المختلطة":

  • الفلترة على طبقتين: في نظام التشغيل Android 15 والإصدارات الأحدث، يقيّم النظام intent filter كمجموعة. يجتاز عنوان URL عملية التحقّق من ملف البيان إذا كان يستوفي إما علامات <data> الثابتة القديمة أو القواعد العامة في <uri-relative-filter-group>. بعد اجتياز عنوان URL لعملية التحقّق الأولية من ملف البيان، يطبّق النظام القواعد الديناميكية المحدّدة في ملف assetlinks.json كطبقة ثانية من الفلترة الدقيقة. وهذا يعني أنّ قواعد JSON من جهة الخادم هي التي تحدّد في النهاية عناوين URL المطابقة التي تفتح التطبيق فعليًا.

مثال على إعداد مختلط:

<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="www.example.com" />

    <!-- Legacy rule: Android 14 and lower use this. Android 15 and higher
         also use this. -->
    <data android:pathPrefix="/store" />

    <!--
      Dynamic rule: Android 14 and lower ignore this. Android 15 and higher
      evaluate this as a union between all paths and the configuration
      specified in the assetlinks.json file. Make sure to apply further
      refinements in the assetlinks.json file to prevent all URL paths from
      opening in the app.
    -->
    <uri-relative-filter-group android:allow="true">
        <data android:pathPrefix="/" />
    </uri-relative-filter-group>
</intent-filter>