يعرض هذا المستند العديد من حالات الاستخدام الشائعة التي يتفاعل فيها تطبيق مع تطبيقات أخرى. يقدّم كل قسم إرشادات حول كيفية تنفيذ وظائف التطبيق مع إمكانية محدودة للوصول إلى الحِزم، وهو ما عليك أخذه في الاعتبار إذا كان تطبيقك يستهدف الإصدار 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()
باستخدام intent يضبط علامة intent FLAG_ACTIVITY_REQUIRE_NON_BROWSER
. إذا عرض النظام ActivityNotFoundException
، يمكن لتطبيقك فتح عنوان URL في علامة تبويب مخصّصة.
إذا كان أحد الأهداف يتضمّن هذا العلامة، سيؤدي طلب startActivity()
إلى عرض ActivityNotFoundException
عند استيفاء أيّ من الشرطَين التاليَين:
- كانت المكالمة ستؤدي إلى تشغيل تطبيق متصفّح مباشرةً.
- كان من المفترض أن يعرض الاتصال مربّع حوار لإزالة الغموض للمستخدم، حيث تكون خياراته الوحيدة هي تطبيقات المتصفّح.
يوضّح مقتطف الرمز البرمجي التالي كيفية تعديل منطقك لاستخدام علامة
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 بنفسك في هذه الحالات، يمكنك استخدام intent يضبط علامة FLAG_ACTIVITY_REQUIRE_DEFAULT
intent.
إذا كان أحد الأهداف يتضمّن هذا العلامة، سيؤدي طلب إلى 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()
مع intent.
منح إذن الوصول إلى عنوان URI
ملاحظة: يجب الإفصاح عن أذونات الوصول إلى معرّف الموارد الموحّد (URI) على النحو الموضّح في هذا القسم للتطبيقات التي تستهدف الإصدار Android 11 (المستوى 30 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث، ويُنصح بذلك لجميع التطبيقات، بغض النظر عن إصدار حزمة تطوير البرامج (SDK) المستهدَف وما إذا كانت تصدّر موفّري المحتوى.
بالنسبة إلى التطبيقات التي تستهدف الإصدار 11 من نظام التشغيل Android أو الإصدارات الأحدث للوصول إلى معرّف الموارد المنتظم (URI) الخاص بالمحتوى، يجب أن يوضّح الغرض من تطبيقك أذونات الوصول إلى معرّف الموارد المنتظم (URI) من خلال ضبط أحد علامتَي الغرض التاليتَين أو كلتيهما: FLAG_GRANT_READ_URI_PERMISSION
وFLAG_GRANT_WRITE_URI_PERMISSION
.
في نظام التشغيل Android 11 والإصدارات الأحدث، تمنح أذونات الوصول إلى معرّف الموارد الموحّد (URI) التطبيق الذي يتلقّى الغرض الإجراءات التالية:
- قراءة البيانات التي يمثّلها معرّف الموارد المنتظم للمحتوى أو الكتابة إليها، وذلك حسب أذونات معرّف الموارد المنتظم المحدّدة
- يمكنك الاطّلاع على التطبيق الذي يتضمّن موفّر المحتوى الذي يتطابق مع مرجع URI. قد يختلف التطبيق الذي يتضمّن مقدّم المحتوى عن التطبيق الذي يرسل الغرض.
يوضّح مقتطف الرمز التالي كيفية إضافة علامة intent لأذونات عنوان 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);
الربط بالخدمات
إذا كان تطبيقك بحاجة إلى التفاعل مع خدمة غير مرئية
تلقائيًا، يمكنك تعريف إجراء النية المناسب ضمن العنصر <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>
توفير وظائف مخصّصة
إذا كان تطبيقك بحاجة إلى تنفيذ إجراءات قابلة للتخصيص أو عرض معلومات قابلة للتخصيص استنادًا إلى تفاعلاته مع التطبيقات الأخرى، يمكنك تمثيل هذا السلوك المخصّص باستخدام توقيعات فلتر الأهداف كجزء من العنصر <queries>
في ملف البيان. تقدّم الأقسام التالية إرشادات مفصّلة حول عدة سيناريوهات شائعة.
طلب البحث عن تطبيقات الرسائل القصيرة
إذا كان تطبيقك يحتاج إلى معلومات حول مجموعة تطبيقات الرسائل القصيرة المثبَّتة على جهاز، مثلاً للتحقّق من التطبيق الذي يتعامل مع الرسائل القصيرة تلقائيًا على الجهاز، أدرِج عنصر <intent>
التالي كجزء من عنصر <queries>
في ملف البيان:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.SENDTO"/> <data android:scheme="smsto" android:host="*" /> </intent>
إنشاء ورقة مشاركة مخصّصة
استخدِم ورقة مشاركة يوفّرها النظام كلما أمكن ذلك. بدلاً من ذلك، يمكنك تضمين العنصر <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 Provider. لكي يعرض تطبيق جهات الاتصال هذه البيانات المخصّصة، يجب أن يكون قادرًا على تنفيذ ما يلي:
- قراءة ملف
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>