إذا كان تطبيقك يمكنه تنفيذ إجراء قد يكون مفيدًا لتطبيق آخر، عليك إعداده للرد على طلبات الإجراءات من خلال تحديد intent filter المناسب في نشاطك.
على سبيل المثال، إذا كنت بصدد إنشاء تطبيق للتواصل الاجتماعي يمكنه مشاركة الرسائل أو الصور مع أصدقاء المستخدم، عليك توفير الدعم للغرض ACTION_SEND.
بعد ذلك، عندما يبدأ المستخدمون إجراء "مشاركة" من تطبيق آخر، يظهر تطبيقك كخيار في مربّع حوار أداة الاختيار (المعروف أيضًا باسم مربّع حوار إزالة الغموض)، كما هو موضّح في الشكل 1.
الشكل 1: مربّع حوار أداة الاختيار
للسماح للتطبيقات الأخرى ببدء نشاطك بهذه الطريقة، عليك إضافة عنصر <intent-filter>
في ملف البيان الخاص بك لعنصر <activity> المقابل.
عند تثبيت تطبيقك على جهاز، يحدّد النظام فلاتر الأهداف ويضيف المعلومات إلى فهرس داخلي للأهداف المتوافقة مع جميع التطبيقات المثبَّتة.
عندما يستدعي تطبيق startActivity() أو startActivityForResult()
باستخدام غرض ضمني، يتحقّق النظام من الأنشطة التي يمكنها الاستجابة
للغرض.
إضافة فلتر أهداف
لتحديد intent التي يمكن أن يتعامل معها نشاطك بشكل صحيح، اجعل كل intent filter تضيفه محدّدًا قدر الإمكان من حيث نوع الإجراء والبيانات التي يقبلها النشاط.
قد يرسل النظام Intent معيّنًا إلى نشاط إذا كان هذا النشاط يتضمّن فلتر أهداف يستوفي المعايير التالية لكائن Intent:
- الإجراء
- سلسلة تحدّد اسم الإجراء المطلوب تنفيذه. عادةً ما تكون إحدى القيم المحدّدة في النظام الأساسي، مثل
ACTION_SENDأوACTION_VIEW.حدِّد ذلك في intent filter باستخدام العنصر
<action>. يجب أن تكون القيمة التي تحدّدها في هذا العنصر هي اسم السلسلة الكاملة للإجراء، بدلاً من الثابت API، كما هو موضّح في الأمثلة الواردة في هذه الصفحة. - البيانات
- وصف للبيانات المرتبطة بالغرض
حدِّد ذلك في intent filter باستخدام العنصر
<data>. باستخدام سمة واحدة أو أكثر في هذا العنصر، يمكنك تحديد نوع MIME أو بادئة URI أو مخطط URI أو مجموعة من هذه العناصر وغيرها التي تشير إلى نوع البيانات المقبولة.ملاحظة: إذا لم تكن بحاجة إلى توضيح تفاصيل حول البيانات
Uri، مثل الحالات التي يتعامل فيها نشاطك مع أنواع أخرى من البيانات "الإضافية"، بدلاً من معرّف الموارد المنتظم (URI)، حدِّد السمةandroid:mimeTypeفقط للإفصاح عن نوع البيانات التي يتعامل معها نشاطك، مثلtext/plainأوimage/jpeg. - الفئة
- توفّر هذه السمة طريقة إضافية لتحديد النشاط الذي يتعامل مع intent، وعادةً ما تكون مرتبطة بإجراء تفاعلي من المستخدم أو الموقع الجغرافي الذي بدأ منه النشاط. يتيح النظام عدة فئات مختلفة، ولكن نادرًا ما يتم استخدام معظمها. ومع ذلك، يتم تحديد جميع النوايا الضمنية باستخدام
CATEGORY_DEFAULTتلقائيًا.حدِّد ذلك في فلتر الأهداف باستخدام العنصر
<category>.
في intent filter، يمكنك تحديد المعايير التي يقبلها نشاطك من خلال تحديد كل معيار باستخدام عناصر تنسيق XML ذات الصلة والمتداخلة في العنصر <intent-filter>.
على سبيل المثال، إليك نشاطًا يتضمّن فلتر أهداف يعالج الهدف ACTION_SEND عندما يكون نوع البيانات نصًا أو صورة:
<activity android:name="ShareActivity"> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> <data android:mimeType="image/*"/> </intent-filter> </activity>
ملاحظة: إذا أردت أن يكون الرمز في مربّع الحوار الخاص بأداة الاختيار مختلفًا عن الرمز التلقائي لنشاطك، أضِف android:icon في العنصر <intent-filter>.
يحدّد كل هدف وارد إجراءً واحدًا ونوع بيانات واحدًا فقط، ولكن لا بأس من تعريف عدة مثيلات للعناصر <action> و<category> و<data> في كل <intent-filter>.
إذا كان أي زوجين من الإجراءات والبيانات يستبعدان بعضهما البعض في سلوكهما، أنشئ فلاتر أهداف منفصلة لتحديد الإجراءات المقبولة عند إقرانها بأنواع البيانات.
على سبيل المثال، لنفترض أنّ النشاط يعالج كلاً من النصوص والصور لكل من الغرضين ACTION_SEND وACTION_SENDTO. في هذه الحالة، يجب تحديد فلترَي أهداف منفصلَين للإجراءَين، لأنّ الهدف ACTION_SENDTO يجب أن يستخدم البيانات Uri لتحديد عنوان المستلِم باستخدام مخطط URI send أو sendto. يظهر ذلك في المثال التالي:
<activity android:name="ShareActivity"> <!-- Filter for sending text; accepts SENDTO action with sms URI schemes --> <intent-filter> <action android:name="android.intent.action.SENDTO"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="sms" /> <data android:scheme="smsto" /> </intent-filter> <!-- Filter for sending text or images; accepts SEND action and text or image data --> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="image/*"/> <data android:mimeType="text/plain"/> </intent-filter> </activity>
ملاحظة: لتلقّي implicit intents، يجب تضمين الفئة CATEGORY_DEFAULT في intent filter. تعامل الطريقتان startActivity() وstartActivityForResult() جميع الأهداف على أنّها
تُصنّف ضمن الفئة CATEGORY_DEFAULT. إذا لم تعرِّفها في intent filter، لن يتم حلّ أي implicit intents لنشاطك.
لمزيد من المعلومات حول إرسال واستلام ACTION_SEND
intent التي تنفّذ سلوكيات المشاركة على وسائل التواصل الاجتماعي، يمكنك الاطّلاع على استلام البيانات البسيطة من التطبيقات الأخرى.
يمكنك أيضًا العثور على معلومات مفيدة حول مشاركة البيانات في المقالتَين
مشاركة البيانات البسيطة و
مشاركة الملفات.
التعامل مع الغرض في نشاطك
لتحديد الإجراء الذي تريد اتّخاذه في نشاطك، اقرأ
Intent المستخدَمة لبدء النشاط.
عندما يبدأ نشاطك، اتّصِل بالرقم getIntent() لاسترداد
Intent الذي بدأ النشاط. يمكنك إجراء ذلك في أي وقت خلال دورة حياة النشاط، ولكن يتم ذلك عادةً أثناء عمليات معاودة الاتصال المبكرة، مثل onCreate() أو onStart().
يظهر ذلك في المثال التالي:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) val data: Uri? = intent?.data // Figure out what to do based on the intent type if (intent?.type?.startsWith("image/") == true) { // Handle intents with image data } else if (intent?.type == "text/plain") { // Handle intents with text } }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Get the intent that started this activity Intent intent = getIntent(); Uri data = intent.getData(); // Figure out what to do based on the intent type if (intent.getType().indexOf("image/") != -1) { // Handle intents with image data } else if (intent.getType().equals("text/plain")) { // Handle intents with text } }
عرض نتيجة
إذا أردت إرجاع نتيجة إلى النشاط الذي استدعى نشاطك، استخدِم setResult() لتحديد رمز النتيجة والنتيجة Intent. عند الانتهاء من العملية وعودة المستخدم إلى النشاط الأصلي، استدعِ finish() لإغلاق نشاطك وإتلافه. يظهر ذلك في المثال التالي:
Kotlin
// Create intent to deliver some kind of result data Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")).also { result -> setResult(Activity.RESULT_OK, result) } finish()
Java
// Create intent to deliver some kind of result data Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")); setResult(Activity.RESULT_OK, result); finish();
يجب دائمًا تحديد رمز نتيجة مع النتيجة. بشكل عام، تكون القيمة إما RESULT_OK أو RESULT_CANCELED. يمكنك بعد ذلك تقديم بيانات إضافية باستخدام Intent، حسب الحاجة.
ملاحظة: يتم ضبط النتيجة على
RESULT_CANCELED
تلقائيًا. لذا، إذا نقر المستخدم على زر "رجوع" قبل إكمال الإجراء وقبل ضبط النتيجة، سيتلقّى النشاط الأصلي النتيجة "تم الإلغاء".
إذا كنت تحتاج فقط إلى عرض عدد صحيح يشير إلى أحد خيارات النتائج المتعددة، يمكنك ضبط رمز النتيجة على أي قيمة أكبر من 0. إذا كنت تستخدم رمز النتيجة لعرض عدد صحيح ولا تحتاج إلى تضمين Intent، يمكنك استدعاء setResult() وتمرير رمز النتيجة فقط:
Kotlin
setResult(RESULT_COLOR_RED) finish()
Java
setResult(RESULT_COLOR_RED); finish();
في هذه الحالة، قد لا يكون هناك سوى عدد قليل من النتائج المحتملة، لذا يكون رمز النتيجة عددًا صحيحًا محدّدًا محليًا (أكبر من 0). ويكون هذا الإجراء مفيدًا عندما تريد عرض نتيجة لنشاط في تطبيقك، لأنّ النشاط الذي يتلقّى النتيجة يمكنه الرجوع إلى الثابت العام لتحديد قيمة رمز النتيجة.
ملاحظة: ليس عليك التحقّق مما إذا كان نشاطك قد بدأ
بالرمز startActivity() أو startActivityForResult(). ما عليك سوى استدعاء setResult() إذا كان الغرض الذي بدأ نشاطك
قد يتوقّع نتيجة. إذا كان النشاط الأصلي قد استدعى startActivityForResult()، سيرسل النظام النتيجة التي تقدّمها إلى setResult()، وإلا سيتم تجاهل النتيجة.