في Android، الرابط لصفحة في التطبيق هو رابط ينقلك مباشرةً إلى وجهة معيّنة داخل تطبيق.
يمكنك دعم نوعَين مختلفَين من الروابط لصفحات في التطبيق في تطبيقك: صريح وضمني. تختلف طريقة تنفيذ الروابط لصفحات في التطبيق حسب نوع الرسم البياني الذي يستخدمه تطبيقك، سواء كان XML or programmatic
إنشاء رابط عميق صريح
الرابط العميق الصريح هو مثيل واحد
من رابط عميق يستخدم PendingIntent
لنقل المستخدمين إلى موقع معيّن داخل تطبيقك. يمكنك عرض رابط
عميق صريح كجزء من إشعار أو تطبيق مصغّر،
مثلاً.
عندما يفتح المستخدم تطبيقك من خلال رابط عميق صريح، يتم محو الأنشطة السابقة واستبدالها بالوجهة التي يؤدي إليها الرابط لصفحة في التطبيق. عند
تضمين رسوم بيانية،
تتم أيضًا إضافة الوجهة الأولية من كل مستوى من مستويات التضمين، أي الوجهة الأولية
من كل عنصر <navigation> في التسلسل الهرمي، إلى المكدّس.
يعني ذلك أنّه عندما يضغط المستخدم على زر الرجوع من وجهة رابط لصفحة في التطبيق، ينتقل إلى أعلى مكدّس التنقّل تمامًا كما لو أنّه دخل إلى تطبيقك من نقطة الدخول.
الرسوم البيانية الآلية
إذا كان رسم التنقّل البياني محدّدًا آليًا (كما هو الحال عادةً في Navigation Compose أو Kotlin DSL)، ننصحك باستخدام TaskStackBuilder لإنشاء PendingIntent للرابط لصفحة في التطبيق.
val id = "exampleId"
val context = LocalContext.current
val deepLinkIntent = Intent(
Intent.ACTION_VIEW,
"https://www.example.com/profile/$id".toUri(),
context,
MyActivity::class.java
)
val pendingIntent: PendingIntent? = TaskStackBuilder.create(context).run {
addNextIntentWithParentStack(deepLinkIntent)
getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
}
الرسوم البيانية بتنسيق XML
يمكنك استخدام فئة NavDeepLinkBuilder
لإنشاء PendingIntent،
كما هو موضّح في المثال أدناه. يُرجى العِلم أنّه إذا لم يكن السياق المقدَّم
Activity، يستخدم المُنشئ
PackageManager.getLaunchIntentForPackage()
كنشاط تلقائي لبدء التشغيل، إذا كان متاحًا.
Kotlin
val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .createPendingIntent()
Java
PendingIntent pendingIntent = new NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .createPendingIntent();
تلقائيًا، يبدأ NavDeepLinkBuilder رابطك العميق الصريح في نشاط بدء التشغيل التلقائي Activity الذي تم الإعلان عنه في بيان تطبيقك. إذا كان NavHost في نشاط آخر، عليك تحديد اسم المكوّن عند إنشاء أداة إنشاء الرابط لصفحة في التطبيق:
Kotlin
val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(DestinationActivity::class.java) .createPendingIntent()
Java
PendingIntent pendingIntent = new NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(DestinationActivity.class) .createPendingIntent();
إذا كان لديك ComponentName،
يمكنك تمريره مباشرةً إلى أداة الإنشاء:
Kotlin
val componentName = ... val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(componentName) .createPendingIntent()
Java
ComponentName componentName = ...; PendingIntent pendingIntent = new NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(componentName) .createPendingIntent();
إذا كان لديك NavController حالي،
يمكنك أيضًا إنشاء رابط لصفحة في التطبيق باستخدام
NavController.createDeepLink().
إنشاء رابط عميق ضمني
يشير الرابط العميق الضمني إلى وجهة معيّنة في تطبيق. عندما يتم استدعاء الرابط العميق، مثلاً عندما ينقر المستخدم على رابط، يمكن لتطبيق Android فتح تطبيقك على الوجهة المقابلة.
يمكن مطابقة الروابط لصفحات في التطبيق حسب معرّف الموارد المنتظم (URI) وإجراءات الهدف وأنواع MIME. يمكنك تحديد أنواع مطابقة متعدّدة لرابط واحد لصفحة في التطبيق، ولكن يُرجى العِلم أنّ مطابقة وسيطة معرّف الموارد المنتظم (URI) لها الأولوية أولاً، يليها الإجراء، ثم نوع MIME.
الرسوم البيانية الآلية
إذا حدّدت رسم التنقّل البياني آليًا (باستخدام Navigation Compose أو Kotlin DSL)، يمكنك تحديد الروابط لصفحات في التطبيق في الرمز.
إنشاء
في Navigation Compose، يمكنك تحديد الروابط لصفحات في التطبيق كجزء من أداة إنشاء الوجهة composable() باستخدام المَعلمة deepLinks. تقبل هذه المَعلمة قائمة بكائنات
NavDeepLink، التي يمكنك إنشاؤها باستخدام الدالة
navDeepLink():
@Serializable
data class Profile(val id: String)
val uri = "https://www.example.com"
composable<Profile>(
deepLinks = listOf(
navDeepLink<Profile>(basePath = "$uri/profile")
)
) { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(id = profile.id)
}
Kotlin DSL
عند استخدام Kotlin DSL، يمكنك تحديد الروابط لصفحات في التطبيق باستخدام دالة الإنشاء
deepLink() ضِمن كتلة الوجهة:
@Serializable
data class Profile(val id: String)
val uri = "https://www.example.com"
fragment<ProfileFragment, Profile> {
deepLink<Profile>(basePath = "$uri/profile")
}
إضافة فلاتر أهداف للرسوم البيانية الآلية
بما أنّ رسوم التنقّل البيانية الآلية يتم إنشاؤها في وقت التشغيل، لا يمكن لمكوّن التنقّل
إنشاء عناصر <intent-filter> المطابقة
في AndroidManifest.xml. بدلاً من ذلك، عليك إضافة العناصر المناسبة يدويًا
<intent-filter>.
لتفعيل الرابط لصفحة في التطبيق في الأمثلة السابقة، أضِف ما يلي ضِمن الـ
عنصر <activity> المقابل في بيانك:
<activity …>
<intent-filter>
...
<data android:scheme="https" android:host="www.example.com" />
</intent-filter>
</activity>
الرسوم البيانية بتنسيق XML
لإنشاء رابط عميق ضمني في رسم بياني يستند إلى XML، يمكنك تحديد عنصر
<deepLink> مباشرةً في XML أو استخدام "محرِّر التنقّل".
في ما يلي مثال على رابط لصفحة في التطبيق يحتوي على معرّف موارد منتظم (URI) وإجراء ونوع MIME:
<fragment android:id="@+id/a"
android:name="com.example.myapplication.FragmentA"
tools:layout="@layout/a">
<deepLink app:uri="www.example.com"
app:action="android.intent.action.MY_ACTION"
app:mimeType="type/subtype"/>
</fragment>
يمكنك أيضًا استخدام "محرِّر التنقّل" لإنشاء رابط عميق ضمني إلى وجهة على النحو التالي:
- في علامة التبويب التصميم في "محرِّر التنقّل"، اختَر الوجهة التي تريد إنشاء الرابط لصفحة في التطبيق إليها.
- انقر على + في قسم الروابط لصفحات في التطبيق ضِمن لوحة السمات.
في مربّع الحوار إضافة رابط لصفحة في التطبيق الذي يظهر، أدخِل معلومات الرابط لصفحة في التطبيق.
يُرجى مراعاة ما يلي:
- يُفترض أنّ معرّفات الموارد المنتظمة (URI) التي لا تتضمّن مخططًا هي
httpأوhttps. على سبيل المثال، يتطابقwww.google.comمع كلّ منhttp://www.google.comوhttps://www.google.com. - تتطابق العناصر النائبة لمعلّمات المسار التي تكون على شكل
{placeholder_name}مع حرف واحد أو أكثر. على سبيل المثال، يتطابقhttp://www.example.com/users/{id}معhttp://www.example.com/users/4. يحاول مكوّن التنقّل تحليل قيم العناصر النائبة إلى أنواع مناسبة من خلال مطابقة أسماء العناصر النائبة مع الوسيطات المحدّدة التي تم تحديدها لوجهة الرابط لصفحة في التطبيق. إذا لم يتم تحديد أي وسيطة بالاسم نفسه، يتم استخدام نوعStringتلقائي للوسيطة. يمكنك استخدام حرف البدل .* لمطابقة 0 أو أكثر من الأحرف. - يمكن استخدام العناصر النائبة لمعلّمات طلب البحث بدلاً من معلّمات المسار أو بالإضافة إليها. على سبيل المثال، يتطابق
http://www.example.com/users/{id}?myarg={myarg}معhttp://www.example.com/users/4?myarg=28. - لا يلزم مطابقة العناصر النائبة لمعلّمات طلب البحث للمتغيّرات المحدّدة بقيم تلقائية أو قيم تقبل القيم الخالية. على سبيل المثال،
http://www.example.com/users/{id}?arg1={arg1}&arg2={arg2}يتطابق معhttp://www.example.com/users/4?arg2=28أوhttp://www.example.com/users/4?arg1=7. لا ينطبق ذلك على معلّمات المسار. على سبيل المثال،http://www.example.com/users?arg1=7&arg2=28لا يتطابق مع النمط أعلاه لأنّه لم يتم توفير معلّمة المسار المطلوبة. - لا تؤثّر معلّمات طلب البحث الخارجية في مطابقة معرّف الموارد المنتظم (URI) للرابط لصفحة في التطبيق. على
سبيل المثال، يتطابق
http://www.example.com/users/{id}معhttp://www.example.com/users/4?extraneousParam=7، على الرغم من أنّه لم يتم تحديدextraneousParamفي نمط معرّف الموارد المنتظم (URI).
- يُفترض أنّ معرّفات الموارد المنتظمة (URI) التي لا تتضمّن مخططًا هي
(اختياري) ضَع علامة في مربّع الاختيار التحقّق تلقائيًا لطلب أن تتحقّق Google من أنّك مالك معرّف الموارد المنتظم (URI). لمزيد من المعلومات، اطّلِع على التحقّق من روابط Android App Links.
انقر على إضافة. يظهر رمز رابط
أعلى الوجهة المحدّدة للإشارة إلى أنّ هذه الوجهة تتضمّن رابطًا لصفحة في التطبيق.انقر على علامة التبويب الرمز للتبديل إلى طريقة عرض XML. تمت إضافة عنصر
<deepLink>متداخل إلى الوجهة:<deepLink app:uri="https://www.google.com" />
لتفعيل الروابط الضمنية لصفحات في التطبيق للرسوم البيانية المستندة إلى XML، عليك أيضًا إجراء إضافات إلى ملف manifest.xml الخاص بتطبيقك. أضِف عنصر <nav-graph>
واحدًا إلى نشاط يشير إلى رسم تنقّل بياني حالي، كما هو موضّح
في المثال التالي:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication"> <application ... > <activity name=".MainActivity" ...> ... <nav-graph android:value="@navigation/nav_graph" /> ... </activity> </application> </manifest>
عند إنشاء مشروعك، يستبدل مكوّن التنقّل عنصر <nav-graph>
بعناصر <intent-filter> تم إنشاؤها لمطابقة جميع الروابط لصفحات في التطبيق
في رسم التنقّل البياني.
الروابط العميقة الضمنية والأنشطة السابقة
عند تشغيل رابط عميق ضمني، تعتمد حالة الأنشطة السابقة على ما إذا تم إطلاق Intent باستخدام Intent.FLAG_ACTIVITY_NEW_TASK العلامة:
- إذا تم ضبط العلامة، يتم محو مكدّس الأنشطة السابقة واستبداله بالوجهة التي يؤدي إليها الرابط لصفحة في التطبيق. كما هو الحال مع الروابط الصريحة لصفحات في التطبيق، عند
تضمين رسوم بيانية،
تتم أيضًا إضافة الوجهة الأولية من كل مستوى من مستويات التضمين، أي الوجهة الأولية من كل عنصر
<navigation>في التسلسل الهرمي، إلى المكدّس. يعني ذلك أنّه عندما يضغط المستخدم على زر الرجوع من وجهة رابط لصفحة في التطبيق، ينتقل إلى أعلى مكدّس التنقّل تمامًا كما لو أنّه دخل إلى تطبيقك من نقطة الدخول. - إذا لم يتم ضبط العلامة، ستبقى في مكدّس المهام الخاص بالتطبيق السابق الذي تم فيه تشغيل الرابط العميق الضمني. في هذه الحالة، يعيدك زر الرجوع إلى التطبيق السابق، بينما يبدأ زر الانتقال إلى أعلى مهمة تطبيقك على الوجهة الرئيسية الهرمية ضِمن رسم التنقّل البياني.
التعامل مع الروابط لصفحات في التطبيق
ننصحك بشدة باستخدام التلقائي
launchMode لـ standard
دائمًا عند استخدام التنقّل. عند استخدام وضع بدء التشغيل standard، يتعامل التنقّل
تلقائيًا مع الروابط لصفحات في التطبيق من خلال استدعاء
handleDeepLink()
لمعالجة أي روابط صريحة أو ضمنية لصفحات في التطبيق ضِمن Intent. ومع ذلك،
لا يحدث ذلك تلقائيًا إذا تم إعادة استخدام Activity عند استخدام
بديل launchMode، مثل singleTop. في هذه الحالة، من الضروري استدعاء handleDeepLink() يدويًا في onNewIntent()، كما هو موضّح في المثال التالي:
Kotlin
override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) navController.handleDeepLink(intent) }
Java
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); navController.handleDeepLink(intent); }