يعرض هذا المستند العديد من حالات الاستخدام الشائعة التي يتفاعل فيها أحد التطبيقات مع تطبيقات أخرى. يقدّم كل قسم إرشادات حول كيفية تنفيذ وظائف التطبيق مع إمكانية رؤية محدودة للحِزم، وهو ما يجب مراعاته إذا كان تطبيقك يستهدف الإصدار 11 من نظام التشغيل Android (المستوى 30 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث.
عندما يستخدم تطبيق يستهدف الإصدار 11 من نظام التشغيل Android أو الإصدارات الأحدث هدفًا لبدء نشاط في تطبيق آخر، فإنّ الطريقة الأكثر مباشرةً هي استدعاء الهدف ومعالجة استثناء ActivityNotFoundException في حال عدم توفّر أي تطبيق.
إذا كان جزء من تطبيقك يعتمد على معرفة ما إذا كان من الممكن نجاح طلب
startActivity()
، مثل عرض واجهة مستخدم، أضِف عنصرًا إلى عنصر
<queries> في بيان
تطبيقك. ويكون هذا عادةً عنصر <intent>.
فتح عناوين URL
يصف هذا القسم الطرق المختلفة لفتح عناوين URL في تطبيق يستهدف الإصدار 11 من نظام التشغيل Android أو الإصدارات الأحدث.
فتح عناوين URL في متصفّح أو تطبيق آخر
لفتح عنوان URL، استخدِم نية تحتوي على إجراء النية ACTION_VIEW، كما هو موضّح في دليل تحميل عنوان URL للويب. بعد استدعاء startActivity()
باستخدام هذا الغرض، يحدث أحد الإجراءات التالية:
- يتم فتح عنوان URL في تطبيق متصفّح ويب.
- يتم فتح عنوان URL في تطبيق يتيح استخدام عنوان URL كـ رابط عميق.
- يظهر مربّع حوار لإزالة الغموض، يتيح للمستخدم اختيار التطبيق الذي يفتح عنوان URL.
يحدث
ActivityNotFoundExceptionبسبب عدم تثبيت تطبيق على الجهاز يمكنه فتح عنوان URL. (هذا أمر غير معتاد).ننصحك بأن يرصد تطبيقك الخطأ
ActivityNotFoundExceptionويعالجه في حال حدوثه.
بما أنّ طريقة startActivity() لا تتطلّب إذن الوصول إلى الحزمة لبدء نشاط تطبيق آخر، ليس عليك إضافة عنصر <queries> إلى ملف بيان تطبيقك أو إجراء أي تغييرات على عنصر <queries> حالي. وينطبق ذلك على كلّ من الأهداف الضمنية والصريحة التي تفتح عنوان URL.
التحقّق من توفّر متصفّح
في بعض الحالات، قد يحتاج تطبيقك إلى التحقّق من توفّر متصفّح واحد على الأقل على الجهاز، أو أنّ متصفّحًا معيّنًا هو المتصفّح التلقائي، قبل محاولة فتح عنوان URL. في هذه الحالات، أدرِج عنصر <intent> التالي كجزء من عنصر <queries> في البيان:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" /> </intent>
عند استدعاء queryIntentActivities() وتمرير نية ويب كوسيطة،
تتضمّن القائمة المعروضة تطبيقات المتصفّح المتاحة في بعض الحالات. ولا تتضمّن القائمة تطبيقات المتصفّح إذا ضبط المستخدم عنوان URL ليتم فتحه في تطبيق غير المتصفّح تلقائيًا.
فتح عناوين URL في علامات التبويب المخصّصة
تتيح علامات التبويب المخصّصة للتطبيق تخصيص شكل المتصفّح ومظهره. يمكنك فتح عنوان URL في
علامة تبويب مخصّصة
بدون الحاجة إلى إضافة عنصر <queries> أو تغييره في بيان تطبيقك.
ومع ذلك، قد تحتاج إلى التحقّق مما إذا كان الجهاز يحتوي على متصفّح يتيح استخدام "علامات التبويب المخصّصة" أو اختيار متصفّح معيّن لتشغيله باستخدام "علامات التبويب المخصّصة" من خلال CustomTabsClient.getPackageName().
في هذه الحالات، أدرِج عنصر <intent> التالي كجزء من عنصر <queries> في ملف البيان:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.support.customtabs.action.CustomTabsService" /> </intent>
السماح للتطبيقات غير المتصفّحات بمعالجة عناوين URL
حتى إذا كان بإمكان تطبيقك فتح عناوين URL باستخدام "علامات التبويب المخصّصة"، ننصحك
بالسماح لتطبيق غير متصفّح بفتح عنوان URL إن أمكن. لتوفير هذه الميزة في تطبيقك، حاوِل إجراء مكالمة مع startActivity() باستخدام نية تضبط علامة النية FLAG_ACTIVITY_REQUIRE_NON_BROWSER. إذا عرض النظام الخطأ ActivityNotFoundException، يمكن لتطبيقك
فتح عنوان URL في علامة تبويب مخصّصة.
إذا كان الغرض يتضمّن هذه العلامة، يؤدي استدعاء startActivity() إلى ظهور
ActivityNotFoundException عند حدوث أي من
الشرطَين التاليَين:
- كان من المفترض أن يؤدي الطلب إلى تشغيل تطبيق متصفّح مباشرةً.
- كان من المفترض أن يعرض الطلب للمستخدم مربّع حوار لإزالة الغموض، حيث تكون الخيارات الوحيدة هي تطبيقات المتصفّح.
يوضّح مقتطف الرمز التالي كيفية تعديل المنطق لاستخدام علامة intent FLAG_ACTIVITY_REQUIRE_NON_BROWSER:
Kotlin
try { val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply { // The URL should either launch directly in a non-browser app (if it's // the default) or in the disambiguation dialog. addCategory(CATEGORY_BROWSABLE) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER } startActivity(intent) } catch (e: ActivityNotFoundException) { // Only browser apps are available, or a browser is the default. // So you can open the URL directly in your app, for example in a // Custom Tab. openInCustomTabs(url) }
Java
try { Intent intent = new Intent(ACTION_VIEW, Uri.parse(url)); // The URL should either launch directly in a non-browser app (if it's the // default) or in the disambiguation dialog. intent.addCategory(CATEGORY_BROWSABLE); intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER); startActivity(intent); } catch (ActivityNotFoundException e) { // Only browser apps are available, or a browser is the default. // So you can open the URL directly in your app, for example in a // Custom Tab. openInCustomTabs(url); }
تجنُّب مربّع حوار توضيحي
إذا أردت تجنُّب عرض مربّع حوار إزالة الالتباس الذي قد يظهر للمستخدمين عند فتح عنوان URL، وفضّلت بدلاً من ذلك معالجة عنوان URL بنفسك في هذه الحالات، يمكنك استخدام نية تضبط علامة النية FLAG_ACTIVITY_REQUIRE_DEFAULT.
إذا كان الغرض يتضمّن هذه العلامة، يؤدي استدعاء startActivity() إلى ظهور
ActivityNotFoundException عندما يعرض الاستدعاء
مربّع حوار توضيحي للمستخدم.
إذا كان الغرض يتضمّن كلاً من هذه العلامة وعلامة الغرض
FLAG_ACTIVITY_REQUIRE_NON_BROWSER،
سيؤدي استدعاء startActivity() إلى ظهور ActivityNotFoundException
عند حدوث أي من الشرطَين التاليَين:
- كان من المفترض أن يؤدي الطلب إلى تشغيل تطبيق المتصفّح مباشرةً.
- كان من المفترض أن يعرض الطلب مربّع حوار لإزالة الغموض للمستخدم.
يوضّح مقتطف الرمز التالي كيفية استخدام العلامتَين FLAG_ACTIVITY_REQUIRE_NON_BROWSER وFLAG_ACTIVITY_REQUIRE_DEFAULT معًا:
Kotlin
val url = URL_TO_LOAD try { // For this intent to be invoked, the system must directly launch a // non-browser app. val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply { addCategory(CATEGORY_BROWSABLE) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER or FLAG_ACTIVITY_REQUIRE_DEFAULT } startActivity(intent) } catch (e: ActivityNotFoundException) { // This code executes in one of the following cases: // 1. Only browser apps can handle the intent. // 2. The user has set a browser app as the default app. // 3. The user hasn't set any app as the default for handling this URL. openInCustomTabs(url) }
Java
String url = URL_TO_LOAD; try { // For this intent to be invoked, the system must directly launch a // non-browser app. Intent intent = new Intent(ACTION_VIEW, Uri.parse(url)); intent.addCategory(CATEGORY_BROWSABLE); intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER | FLAG_ACTIVITY_REQUIRE_DEFAULT); startActivity(intent); } catch (ActivityNotFoundException e) { // This code executes in one of the following cases: // 1. Only browser apps can handle the intent. // 2. The user has set a browser app as the default app. // 3. The user hasn't set any app as the default for handling this URL. openInCustomTabs(url); }
فتح ملف
إذا كان تطبيقك يتعامل مع الملفات أو المرفقات، مثل التحقّق مما إذا كان الجهاز يمكنه
فتح ملف معيّن، يكون من الأسهل عادةً محاولة بدء نشاط يمكنه
التعامل مع الملف. لإجراء ذلك، استخدِم نية تتضمّن إجراء النية ACTION_VIEW ومعرّف الموارد المنتظم (URI) الذي يمثّل الملف المحدّد. إذا لم يتوفّر أي تطبيق على الجهاز، يمكن لتطبيقك رصد ActivityNotFoundException. في منطق معالجة الاستثناءات، يمكنك إما إظهار خطأ أو محاولة معالجة الملف بنفسك.
إذا كان تطبيقك بحاجة إلى معرفة ما إذا كان بإمكان تطبيق آخر فتح ملف معيّن،
يمكنك تضمين العنصر <intent> في مقتطف الرمز التالي كجزء من
العنصر <queries> في ملف البيان. قم بتضمين نوع الملف إذا كنت تعرف بالفعل
ما هو في وقت التجميع.
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.VIEW" /> <!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". --> <data android:mimeType="application/pdf" /> </intent>
يمكنك بعد ذلك التحقّق من توفّر تطبيق من خلال استدعاء resolveActivity()
باستخدام نيتك.
منح إذن الوصول إلى معرّف الموارد المنتظم (URI)
ملاحظة: إنّ الإعلان عن أذونات الوصول إلى معرّف الموارد المنتظم (URI) على النحو الموضّح في هذا القسم مطلوب للتطبيقات التي تستهدف الإصدار 11 من نظام التشغيل Android (مستوى واجهة برمجة التطبيقات 30) أو الإصدارات الأحدث، ويُنصح به لجميع التطبيقات، بغض النظر عن إصدار حزمة تطوير البرامج (SDK) المستهدَف وما إذا كانت تصدّر أدوات توفير المحتوى.
بالنسبة إلى التطبيقات التي تستهدف الإصدار 11 من نظام التشغيل Android أو الإصدارات الأحدث،
يجب أن يوضّح intent في تطبيقك أذونات الوصول إلى معرّف الموارد المنتظم
من خلال ضبط علامة واحدة أو كلتا العلامتَين التاليتَين:
FLAG_GRANT_READ_URI_PERMISSION
و
FLAG_GRANT_WRITE_URI_PERMISSION.
في الإصدار 11 من نظام التشغيل Android والإصدارات الأحدث، تمنح أذونات الوصول إلى معرّف الموارد المنتظم (URI) الإمكانات التالية للتطبيق الذي يتلقّى الغرض:
- قراءة البيانات التي يمثّلها معرّف الموارد المنتظم للمحتوى أو الكتابة فيها، استنادًا إلى أذونات معرّف الموارد المنتظم المحدَّدة
- يمكنك الاطّلاع على التطبيق الذي يتضمّن أداة توفير المحتوى التي تتطابق مع مرجع معرّف الموارد المنتظم (URI). قد يختلف التطبيق الذي يتضمّن أداة توفير المحتوى عن التطبيق الذي يرسل الطلب.
يوضّح مقتطف الرمز التالي كيفية إضافة علامة نية لأذونات معرّف الموارد المنتظم (URI) بحيث يمكن لتطبيق آخر يستهدف الإصدار 11 من نظام التشغيل Android أو الإصدارات الأحدث عرض البيانات في معرّف الموارد المنتظم (URI) للمحتوى:
Kotlin
val shareIntent = Intent(Intent.ACTION_VIEW).apply { flags = Intent.FLAG_GRANT_READ_URI_PERMISSION data = CONTENT_URI_TO_SHARE_WITH_OTHER_APP }
Java
Intent shareIntent = new Intent(Intent.ACTION_VIEW); shareIntent.setFlags(FLAG_GRANT_READ_URI_PERMISSION); shareIntent.setData(CONTENT_URI_TO_SHARE_WITH_OTHER_APP);
الربط بالخدمات
إذا كان تطبيقك بحاجة إلى التفاعل مع خدمة غير مرئية
تلقائيًا، يمكنك تحديد
إجراء intent المناسب ضمن عنصر <queries>. تقدّم الأقسام التالية أمثلة باستخدام الخدمات التي يتم الوصول إليها بشكل شائع.
الربط بمحرّك تحويل النص إلى كلام
إذا كان تطبيقك يتفاعل مع محرّك تحويل النص إلى كلام (TTS)، عليك تضمين عنصر <intent> التالي كجزء من عنصر <queries> في ملف البيان:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.TTS_SERVICE" /> </intent>
الاتصال بخدمة التعرّف على الكلام
إذا كان تطبيقك يتفاعل مع خدمة التعرّف على الكلام، عليك تضمين عنصر
<intent> التالي كجزء من عنصر <queries> في ملف البيان:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.speech.RecognitionService" /> </intent>
الربط بخدمات متصفّح الوسائط
إذا كان تطبيقك تطبيقًا لمتصفّح وسائط العميل، يجب تضمين عنصر <intent> التالي كجزء من عنصر <queries> في بيان التطبيق:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.media.browse.MediaBrowserService" /> </intent>
توفير وظائف مخصّصة
إذا كان تطبيقك يحتاج إلى تنفيذ إجراءات مخصّصة أو عرض معلومات قابلة للتخصيص استنادًا إلى تفاعلاته مع التطبيقات الأخرى، يمكنك تمثيل هذا السلوك المخصّص باستخدام توقيعات intent filter كجزء من عنصر <queries> في ملف البيان. تقدّم الأقسام التالية
إرشادات مفصّلة لعدة سيناريوهات شائعة.
الاستعلام عن تطبيقات SMS
إذا كان تطبيقك يحتاج إلى معلومات حول مجموعة تطبيقات SMS المثبّتة على
جهاز، على سبيل المثال للتحقّق من التطبيق الذي يمثّل معالج SMS التلقائي للجهاز،
يُرجى تضمين عنصر <intent> التالي كجزء من عنصر <queries> في
ملف البيان:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.SENDTO"/> <data android:scheme="smsto" android:host="*" /> </intent>
إنشاء ورقة مشاركة مخصّصة
Whenever possible, use a system-provided
sharesheet. بدلاً من ذلك، يمكنك تضمين عنصر <intent> التالي كجزء من عنصر <queries> في ملف البيان:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.SEND" /> <!-- Replace with the MIME type that your app works with, if needed. --> <data android:mimeType="image/jpeg" /> </intent>
تظل عملية إنشاء ورقة المشاركة في منطق تطبيقك، مثل طلب
queryIntentActivities()، بدون تغيير مقارنةً
بإصدارات Android الأقدم من Android 11.
عرض إجراءات تحديد النص المخصّصة
عندما يختار المستخدمون نصًا في تطبيقك، يعرض شريط أدوات اختيار النص مجموعة من العمليات الممكنة التي يمكن إجراؤها على النص المحدّد. إذا كان شريط الأدوات هذا يعرض إجراءات مخصّصة من تطبيقات أخرى، يجب تضمين عنصر <intent> التالي كجزء من عنصر <queries> في ملف البيان:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.PROCESS_TEXT" /> <data android:mimeType="text/plain" /> </intent>
عرض صفوف البيانات المخصّصة لجهة اتصال معيّنة
يمكن للتطبيقات إضافة صفوف بيانات مخصّصة إلى مقدِّم جهات الاتصال. لكي يعرض تطبيق جهات الاتصال هذه البيانات المخصّصة، يجب أن يكون قادرًا على تنفيذ ما يلي:
- قراءة ملف
contacts.xmlمن التطبيقات الأخرى - حمِّل رمزًا يتوافق مع نوع MIME المخصّص.
إذا كان تطبيقك هو تطبيق جهات اتصال، أدرِج عناصر <intent> التالية كجزء من عنصر <queries> في ملف البيان:
<!-- Place inside the <queries> element. --> <!-- Lets the app read the contacts.xml file from other apps. --> <intent> <action android:name="android.accounts.AccountAuthenticator" /> </intent> <!-- Lets the app load an icon corresponding to the custom MIME type. --> <intent> <action android:name="android.intent.action.VIEW" /> <data android:scheme="content" android:host="com.android.contacts" android:mimeType="vnd.android.cursor.item/*" /> </intent>