Intent
هو كائن مراسلة يمكنك استخدامه لطلب إجراء
من مكوِّن تطبيق آخر.
على الرغم من أن الأهداف تسهل التواصل بين المكونات بعدة طرق، إلا أن هناك ثلاثة
تشمل حالات الاستخدام الأساسية التالية:
- بدء نشاط
تمثّل السمة
Activity
شاشة واحدة في تطبيق. يمكنك بدء حساب جديد مثال لـActivity
من خلال تمريرIntent
إلىstartActivity()
.Intent
يصف النشاط للبدء ويحمل أي بيانات ضرورية.إذا كنت تريد الحصول على نتيجة من النشاط عند الانتهاء، الاتصال بخدمة
startActivityForResult()
يتلقّى نشاطك النتيجة باعتباره عنصرIntent
منفصل في استدعاءonActivityResult()
لنشاطك. لمزيد من المعلومات، اطّلِع على دليل الأنشطة. - بدء خدمة
Service
هو مكوِّن ينفذ العمليات في الخلفية. بدون واجهة مستخدم. باستخدام الإصدار Android 5.0 (المستوى 21 من واجهة برمجة التطبيقات) والإصدارات الأحدث، يمكنك بدء خدمة معJobScheduler
. لمزيد من المعلومات حولJobScheduler
، راجعAPI-reference documentation
بالنسبة إلى الإصدارات الأقدم من Android 5.0 (المستوى 21 لواجهة برمجة التطبيقات)، يمكنك بدء خدمة باستخدام لفئة
Service
. يمكنك بدء خدمة لإجراء عملية لمرة واحدة (مثل تنزيل ملف) من خلال تمريرIntent
إلىstartService()
.Intent
يصف الخدمة للبدء ويحمل أي بيانات ضرورية.إذا تم تصميم الخدمة باستخدام واجهة خادم عميل، يمكنك الربط بالخدمة من مكوّن آخر عن طريق تمرير
Intent
إلىbindService()
. لمزيد من المعلومات، يُرجى الاطّلاع على دليل الخدمات. - إرسال بث
البث هو رسالة يمكن أن يتلقاها أي تطبيق. يقدم النظام العديد من عمليات البث لأحداث النظام، مثل عند تشغيل النظام أو بدء شحن الجهاز. يمكنك إرسال بث إلى تطبيقات أخرى من خلال ضبط
Intent
. إلىsendBroadcast()
أوsendOrderedBroadcast()
توضّح هذه الصفحة آلية عمل الأهداف وكيفية استخدامها. للحصول على معلومات ذات صلة، يُرجى مراجعة التفاعل مع التطبيقات الأخرى ومشاركة المحتوى
أنواع الأهداف
هناك نوعان من الأهداف:
- الأهداف الصريحة تحدد مكوّن التطبيق الذي سيفي بالغرض، من خلال تحديد
ComponentName
كامل. وسوف هدفًا صريحًا لبدء مكون في تطبيقك الخاص، لأنك تعرف اسم فئة النشاط أو الخدمة التي تريد بدئها. بالنسبة على سبيل المثال، قد تبدأ نشاطًا جديدًا داخل تطبيقك استجابةً لإجراء المستخدم، أو تبدأ خدمة لتنزيل ملف في الخلفية. - لا تذكر الأهداف الضمنية مكوّنًا معيّنًا، ولكنها تعلن بدلاً من ذلك عن إجراء عام. تنفيذها، وهو ما يسمح لمكون من تطبيق آخر بمعالجتها. على سبيل المثال، إذا كنت تريد تعرض للمستخدم موقعًا ما على الخريطة، فيمكنك استخدام نية ضمنية لطلب الحصول على إذن يعرض التطبيق موقعًا جغرافيًا محددًا على الخريطة.
يوضح الشكل 1 كيفية استخدام هدف عند بدء نشاط. عندما
يقوم الكائن Intent
بتسمية مكون نشاط معين بشكل صريح، ويسمي النظام
على الفور بهذا المكون.
![](https://developer.android.com/static/images/components/intent-filters_2x.png?hl=ar)
الشكل 1. كيف يكون الغرض الضمني
تسليمه من خلال النظام لبدء نشاط آخر: [1] يُنشئ النشاط أ
Intent
يتضمن وصف الإجراء ويمرره إلى startActivity()
[2] يبحث نظام Android في جميع
التطبيقات لفلتر أهداف يتطابق مع الهدف. وعند العثور على مطابقة، [3]
يبدأ النشاط المطابق (النشاط ب) باستدعاء طريقة onCreate()
وتمريره Intent
.
عند استخدام هدف ضمني، يعثر نظام Android على المكوّن المناسب لبدء
من خلال مقارنة محتوى intent بفلاتر الأهداف المعرَّفة في ملف البيان للتطبيقات الأخرى على
الخاص بك. إذا تطابق الهدف مع فلتر أهداف، يبدأ النظام هذا المكوِّن ويعرضها.
كائن Intent
. في حال توافق فلاتر الأهداف المتعددة، سيجري النظام
عرض مربع حوار حتى يتمكن المستخدم من اختيار التطبيق الذي يريد استخدامه.
فلتر الأهداف هو تعبير في ملف بيان التطبيق نوع الأهداف التي يمكن للمكوِّن يرغب في الحصول عليه. فعلى سبيل المثال، بإعلان فلتر أهداف لأحد الأنشطة، تُتيح للتطبيقات الأخرى بدء نشاطك مباشرةً بنيّة معيّنة من النية. وبالمثل، في حال لم تُعلن عن أي فلاتر أهداف لنشاط معيّن، يمكن عندئذٍ بدئه. بنيّة صريحة فقط
تنبيه: لضمان أمان تطبيقك، يُرجى دائمًا
استخدام ملف
النية عند بدء Service
وعدم
الإفصاح عن فلاتر الأهداف لخدماتك. يعتبر استخدام نية ضمنية لبدء خدمة ما
خطر أمني لأنك لا تستطيع التأكد من استجابة الخدمة لهدف
ولا يمكن للمستخدم معرفة الخدمة التي بدأت. بدءًا من Android 5.0 (مستوى واجهة برمجة التطبيقات 21)، سيركز
تطرح استثناء إذا طلبت bindService()
بهدف ضمني.
بناء هدف
يحتوي عنصر Intent
على معلومات يستخدمها نظام Android.
لتحديد المكون الذي سيتم البدء فيه (مثل اسم المكون أو المكون بالضبط
فئة يجب أن تتلقى intent)، بالإضافة إلى المعلومات التي يستخدمها مكون المستلم في
من أجل تنفيذ الإجراء بشكل صحيح (مثل الإجراء المطلوب اتخاذه والبيانات التي يجب التصرف بناءً عليها).
المعلومات الأساسية التي يتضمّنها Intent
هي ما يلي:
- اسم المكوِّن
- اسم المكوِّن المطلوب البدء.
هذه خطوة اختيارية، ولكنها المعلومة الحاسمة التي تصنع نية فاضحة، ما يعني أنّ نية الشراء يجب تسليمها إلى مكوّن التطبيق فقط. المحددة بواسطة اسم المكون. وبدون اسم المكوِّن، يكون الغرض ضمنيًا يقرر المكون الذي يجب أن يتلقى الغرض بناءً على معلومات النية الأخرى (مثل الإجراء والبيانات والفئة - كما هو موضَّح أدناه). إذا كنت بحاجة إلى بدء مخطط في تطبيقك، فيجب تحديد اسم المكوِّن.
ملاحظة: عند بدء تشغيل
Service
، حدِّد دائمًا اسم المكوِّن. وبخلاف ذلك، لا يمكنك التأكد من الخدمة وسوف يستجيب للغرض، ولا يمكن للمستخدم معرفة أي خدمة تبدأ.هذا الحقل من
Intent
عبارة عنComponentName
، الذي يمكنك تحديده باستخدام اسم الفئة المؤهلة للمكون المستهدف، بما في ذلك اسم حزمة التطبيق، على سبيل المثال،com.example.ExampleActivity
يمكنك ضبط اسم المكوِّن باستخدامsetComponent()
أوsetClass()
أوsetClassName()
أو أو باستخدام الدالة الإنشائيةIntent
. - الإجراء
- سلسلة تحدد الإجراء العام المطلوب تنفيذه (مثل عرض أو اختيار).
في ما يتعلق بالغرض من البث، هذا هو الإجراء الذي تم إجراؤه والذي يتم الإبلاغ عنه. يحدد الإجراء إلى حد كبير كيفية تنظيم بقية الهدف، خاصةً المعلومات الموجودة في البيانات والإضافات.
يمكنك تحديد إجراءاتك الخاصة لكي يتم استخدامها حسب الأهداف داخل تطبيقك (أو لاستخدامها من قِبل مستخدمين آخرين). التطبيقات لاستدعاء المكونات في تطبيقك)، ولكنك عادةً ما تحدد ثوابت الإجراء محدّدة في فئة
Intent
أو فئات إطار عمل أخرى. إليك بعض الأمثلة الإجراءات الشائعة لبدء نشاط وهي:ACTION_VIEW
- استخدِم هذا الإجراء في مقصد لـ
startActivity()
عندما يكون لديك بعض المعلومات التي نشاط يمكن أن يظهر للمستخدم، مثل صورة لعرضها في تطبيق معرض الصور أو عنوان لعرضها في تطبيق الخرائط ACTION_SEND
- يُعرف أيضًا باسم نية المشاركة، ويجب استخدام هذا الغرض في
startActivity()
، عندما يكون لديك بعض البيانات التي يمكن للمستخدم استخدامها. مشاركتها من خلال تطبيق آخر، مثل تطبيق البريد الإلكتروني أو تطبيق المشاركة على وسائل التواصل الاجتماعي
اطّلِع على مرجع فئة
Intent
لمعرفة المزيد. الثوابت التي تحدد الإجراءات العامة. تم تحديد إجراءات أخرى مكان آخر في إطار عمل Android، مثلSettings
لتنفيذ الإجراءات تفتح شاشات محدّدة في تطبيق "الإعدادات" على النظام.ويمكنك تحديد الإجراء لغرض في
setAction()
أو باستخدام دالة إنشاءIntent
.إذا حدّدت إجراءاتك الخاصة، تأكَّد من تضمين اسم حزمة تطبيقك. كبادئة، كما هو موضح في المثال التالي:
Kotlin
const val ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL"
Java
static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
- البيانات
- معرّف الموارد المنتظم (URI) (كائن
Uri
) الذي يشير إلى البيانات التصرف على و/أو نوع MIME لتلك البيانات. ويعتمد نوع البيانات المقدَّمة بشكل عام على إجراء الغرض. بالنسبة على سبيل المثال، إذا كان الإجراءACTION_EDIT
، يجب أن تحتوي البيانات على السمة معرّف الموارد المنتظم (URI) للمستند المطلوب تعديله.عند إنشاء هدف، من المهم غالبًا تحديد نوع البيانات (نوع MIME) بالإضافة إلى معرّف الموارد المنتظم (URI). على سبيل المثال، قد لا يتمكن أي نشاط يمكنه عرض الصور لتشغيل ملف صوتي، على الرغم من أن تنسيقات معرف الموارد المنتظم (URI) قد تكون متشابهة. يساعد تحديد نوع MIME لبياناتك نظام Android أفضل مكون للحصول على هدفك. ومع ذلك، يمكن أحيانًا استنتاج نوع MIME من معرّف الموارد المنتظم (URI) - خاصةً عندما تكون البيانات معرّف الموارد المنتظم (URI)
content:
يشير معرّف الموارد المنتظم (URI)content:
إلى أنّ البيانات متوفّرة على الجهاز. والتحكم فيه من قِبلContentProvider
، ما يجعل البيانات من نوع MIME مرئية للنظام.لضبط معرّف الموارد المنتظم (URI) للبيانات فقط، يُرجى الاتصال بالرقم
setData()
. لضبط نوع MIME فقط، يمكنك طلبsetType()
. إذا لزم الأمر، يمكن ضبط كليهما بشكلٍ صريح باستخدامsetDataAndType()
.تنبيه: إذا كنت تريد ضبط كل من معرّف الموارد المنتظم (URI) ونوع MIME، عدم الاتصال بـ
setData()
setType()
لأن كل منهما يؤدي إلى إبطال قيمة الآخر. استخدامsetDataAndType()
دائمًا لضبط كليهما معرّف الموارد المنتظم (URI) ونوع MIME - الفئة
- سلسلة تحتوي على معلومات إضافية عن نوع المكوِّن
التي ينبغي أن تتعامل مع الهدف. يمكن أن يكون أي عدد من أوصاف الفئات
موضوعة في هدف، ولكن معظم الأهداف لا تتطلب فئة.
في ما يلي بعض الفئات الشائعة:
CATEGORY_BROWSABLE
- يسمح النشاط الهدف ببدء تشغيله بواسطة متصفح ويب لعرض البيانات المشار إليها بواسطة رابط، مثل صورة أو رسالة بريد إلكتروني.
CATEGORY_LAUNCHER
- النشاط هو النشاط الأولي لمهمة ما ويتم إدراجه في مشغِّل تطبيقات النظام.
راجِع وصف الصف
Intent
للحصول على القائمة الكاملة الفئات.يمكنك تحديد فئة باستخدام
addCategory()
.
تمثل هذه الخصائص المدرجة أعلاه (اسم المكون والإجراء والبيانات والفئة) تحديد خصائص النية. ومن خلال قراءة هذه الخصائص، فإن نظام Android يكون قادرًا على تحديد مكون التطبيق الذي يجب أن يبدأ. ومع ذلك، يمكن أن يحمل النية معلومات إضافية لا تؤثر وكيف يتم حلها إلى مكون التطبيق. يمكن أن يقدم الغرض أيضًا المعلومات التالية:
- الإضافات
- أزواج المفتاح/القيمة التي تتضمّن المعلومات الإضافية المطلوبة لإنجازها
الإجراء المطلوب.
مثلما تستخدم بعض الإجراءات أنواعًا معينة من معرفات الموارد المنتظمة (URI) للبيانات، تستخدم بعض الإجراءات أيضًا إضافات معينة.
يمكنك إضافة بيانات إضافية باستخدام طرق
putExtra()
مختلفة، تقبل كل منهما معلمتين وهما: اسم المفتاح والقيمة. يمكنك أيضًا إنشاء كائنBundle
بجميع البيانات الإضافية، ثم إدراجBundle
فيIntent
معputExtras()
.على سبيل المثال، عند إنشاء نية لإرسال رسالة بريد إلكتروني تحتوي
ACTION_SEND
، يمكنك تحديد مستلم إلى من خلالEXTRA_EMAIL
، وحدد الموضوع المفتاحEXTRA_SUBJECT
:تحدّد الفئة
Intent
العديد من ثوابتEXTRA_*
. لأنواع البيانات الموحدة. إذا كنت بحاجة إلى الإفصاح عن مفاتيحك الإضافية (للأغراض التي الذي يتلقّاه تطبيقك)، فتأكد من تضمين اسم حزمة التطبيق كبادئة، كما هو موضح في المثال التالي:Kotlin
const val EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS"
Java
static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
تحذير: لا تستخدم
Parcelable
أو بياناتSerializable
عند إرسال هدف تتوقّعه تنزيل تطبيق آخر. إذا كان التطبيق يحاول الوصول إلى البيانات في كائنBundle
ولكنه لا حق الوصول إلى الفئة المقسمة أو المتسلسلة، يرفع النظامRuntimeException
- العلامات
- يتم تحديد العلامات في الفئة
Intent
والتي تعمل كبيانات وصفية والنية. قد تُعلم العلامات نظام Android بكيفية بدء نشاط (على سبيل المثال، المهمة يجب أن ينتمي النشاط إليه) وكيفية التعامل معه بعد إطلاقه (على سبيل المثال، ما إذا كان ينتمي إلى قائمة المواقع الإلكترونية الأنشطة).لمزيد من المعلومات، يُرجى الاطّلاع على طريقة
setFlags()
.
مثال على النية الصريحة
الغرض الصريح هو ذلك الذي تستخدمه لتشغيل مكون تطبيق معين، مثل
نشاط أو خدمة معيّنة في تطبيقك لإنشاء نية صريحة، حدد
اسم المكوِّن للكائن Intent
—كل
خصائص intent الأخرى اختيارية.
على سبيل المثال، إذا أنشأت خدمة في تطبيقك باسم DownloadService
،
مصممة لتنزيل ملف من الويب، يمكنك بدؤه بالرمز التالي:
Kotlin
// Executed in an Activity, so 'this' is theContext
// The fileUrl is a string URL, such as "http://www.example.com/image.png" val downloadIntent = Intent(this, DownloadService::class.java).apply { data =Uri.parse
(fileUrl) } startService(downloadIntent)
Java
// Executed in an Activity, so 'this' is theContext
// The fileUrl is a string URL, such as "http://www.example.com/image.png" Intent downloadIntent = new Intent(this, DownloadService.class); downloadIntent.setData(Uri.parse
(fileUrl)); startService(downloadIntent);
Intent(Context, Class)
توفر الدالة الإنشائية التطبيق Context
كائن Class
. وبناءً على ذلك،
يؤدي هذا الغرض صراحةً إلى بدء الفئة DownloadService
في التطبيق.
لمزيد من المعلومات حول إنشاء خدمة وبدء تشغيلها، يمكنك الاطلاع على دليل الخدمات.
مثال على هدف ضمني
يحدد الغرض الضمني إجراءً يمكنه استدعاء أي تطبيق على الجهاز يمكنه لتنفيذ الإجراء. يكون استخدام هدف ضمني مفيدًا عندما يتعذّر على التطبيق تنفيذ الإجراء، ولكن ربما يمكن للتطبيقات الأخرى أن يختار المستخدم التطبيق الذي يريد استخدامه.
على سبيل المثال، إذا كان لديك محتوى تريد أن يشاركه المستخدم مع أشخاص آخرين،
أنشِئ هدفًا
مع إجراء ACTION_SEND
وتضيف ميزات إضافية تحدد المحتوى الذي تريد مشاركته. عند الاتصال
startActivity()
بهذا الغرض، يمكن للمستخدم
اختيار تطبيق لمشاركة المحتوى من خلاله.
Kotlin
// Create the text message with a string. val sendIntent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_TEXT, textMessage) type = "text/plain" } // Try to invoke the intent. try { startActivity(sendIntent) } catch (e: ActivityNotFoundException) { // Define what your app should do if no activity can handle the intent. }
Java
// Create the text message with a string. Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage); sendIntent.setType("text/plain"); // Try to invoke the intent. try { startActivity(sendIntent); } catch (ActivityNotFoundException e) { // Define what your app should do if no activity can handle the intent. }
عند استدعاء الدالة startActivity()
، يستخدم النظام
جميع التطبيقات المثبتة لتحديد التطبيقات التي يمكنها التعامل مع هذا النوع من الأهداف (
نية في الإجراء ACTION_SEND
والتي تتضمن "نص/عادي"
البيانات). إذا لم يكن هناك سوى تطبيق واحد يمكنه التعامل مع هذه العملية، فسيتم فتح هذا التطبيق على الفور وسيتم منحه
والنية. إذا لم تتمكن أي تطبيقات أخرى من التعامل مع هذا الإجراء، يمكن لتطبيقك التقاط
ActivityNotFoundException
التي تحدث. إذا كانت هناك أنشطة متعددة تقبل الغرض، سيجري النظام
لعرض مربع حوار مثل الذي يظهر في الشكل 2، حتى يتمكن المستخدم من اختيار التطبيق المراد استخدامه.
يتم أيضًا توفير مزيد من المعلومات حول إطلاق تطبيقات أخرى في الدليل. حول إرسال المستخدم إلى لتطبيق آخر.
![](https://developer.android.com/static/images/training/basics/intent-chooser.png?hl=ar)
الشكل 2. مربع حوار أداة الاختيار.
فرض أداة اختيار التطبيق
عندما يستجيب أكثر من تطبيق واحد لهدفك الضمني، يمكن للمستخدم اختيار التطبيق الذي يريد استخدامه وجعله هو الخيار التلقائي اتخاذ القرار. تُعد القدرة على تحديد خيار افتراضي مفيدة عند تنفيذ إجراء يريد المستخدم من أجله ربما يريد استخدام التطبيق نفسه في كل مرة، على سبيل المثال عند فتح صفحة ويب (المستخدمون يفضلون غالبًا متصفح ويب واحدًا فقط).
ومع ذلك، إذا كان بإمكان تطبيقات متعددة الاستجابة لهدف المستخدم، وقد يرغب المستخدم في استخدام عنوان URL مختلف
في كل مرة، فسينبغي لك إظهار مربع حوار أداة الاختيار بوضوح. يسأل مربع حوار المُختار
المستخدم لتحديد التطبيق الذي يريد استخدامه في الإجراء (لا يمكن للمستخدم اختيار تطبيق تلقائي
الإجراء). على سبيل المثال، عندما ينفِّذ تطبيقك "مشاركة" من خلال الإجراء ACTION_SEND
، قد يرغب المستخدمون في المشاركة باستخدام تطبيق مختلف، وذلك حسب ما يلي:
على الوضع الحالي، لذا يجب عليك دائمًا استخدام مربع حوار المُختار، كما هو موضح في الشكل 2.
لإظهار أداة الاختيار، أنشِئ Intent
باستخدام createChooser()
ومرِّرها إلى startActivity()
، كما هو موضّح في المثال التالي.
يعرض هذا المثال مربّع حوار يتضمّن قائمة بالتطبيقات التي تستجيب للهدف الذي تم تمريره إلى طريقة createChooser()
وتستخدم النص المقدّم على أنّه
عنوان مربع الحوار.
Kotlin
val sendIntent = Intent(Intent.ACTION_SEND) ... // Always use string resources for UI text. // This says something like "Share this photo with" val title: String = resources.getString(R.string.chooser_title) // Create intent to show the chooser dialog val chooser: Intent = Intent.createChooser(sendIntent, title) // Verify the original intent will resolve to at least one activity if (sendIntent.resolveActivity(packageManager) != null) { startActivity(chooser) }
Java
Intent sendIntent = new Intent(Intent.ACTION_SEND); ... // Always use string resources for UI text. // This says something like "Share this photo with" String title = getResources().getString(R.string.chooser_title); // Create intent to show the chooser dialog Intent chooser = Intent.createChooser(sendIntent, title); // Verify the original intent will resolve to at least one activity if (sendIntent.resolveActivity(getPackageManager()) != null) { startActivity(chooser); }
رصد عمليات الإطلاق غير الآمنة حسب نية العميل
قد يطلق تطبيقك أهدافًا للتنقل بين المكونات داخل التطبيق، أو تنفيذ إجراء نيابةً عن تطبيق آخر. لتحسين أمان المنصة، يوفّر Android 12 (المستوى 31 لواجهة برمجة التطبيقات) والإصدارات الأحدث ميزة لتصحيح الأخطاء تحذّرك. إذا نفّذ تطبيقك عملية إطلاق غير آمنة لهدف معيّن على سبيل المثال، قد تنفيذ إطلاق غير آمن لهدف مدمج، وهو هدف يتم تمريره كعنصر إضافي في هدف آخر.
إذا نفّذ تطبيقك كلا الإجراءين التاليين، يرصد النظام إجراءً غير آمن. إطلاق intent، ومخالفة قواعد StrictMode يحدث:
- يفصل تطبيقك عن الغرض المدمج من العناصر الإضافية لهدف تم إرساله.
- يبدأ تطبيقك على الفور في تشغيل تطبيق.
باستخدام هذا الغرض المتداخل،
مثل تمرير النية إلى
startActivity()
،startService()
, أوbindService()
لمزيد من التفاصيل حول كيفية تحديد هذا الموقف وإجراء تغييرات في تطبيقك، الاطّلاع على مشاركة المدونة حول دمج Android النوايا على Medium.
التحقّق من عمليات الإطلاق غير الآمنة حسب نية العميل
للتحقّق من عمليات تشغيل intent غير الآمنة في التطبيق، يُرجى الاتصال
detectUnsafeIntentLaunch()
عند ضبط VmPolicy
، كما هو موضَّح في مقتطف الرمز التالي. في حال حذف
كشف تطبيقك عن انتهاك للوضع المتشدد، قد تحتاج إلى إيقاف تنفيذ التطبيق
حماية المعلومات التي يُحتمَل أن تكون حسّاسة
Kotlin
fun onCreate() { StrictMode.setVmPolicy(VmPolicy.Builder() // Other StrictMode checks that you've previously added. // ... .detectUnsafeIntentLaunch() .penaltyLog() // Consider also adding penaltyDeath() .build()) }
Java
protected void onCreate() { StrictMode.setVmPolicy(new VmPolicy.Builder() // Other StrictMode checks that you've previously added. // ... .detectUnsafeIntentLaunch() .penaltyLog() // Consider also adding penaltyDeath() .build()); }
استخدام الأهداف بمسؤولية أكبر
لتقليل فرصة الإطلاق غير الآمن لهدف ما وانتهاك السياسة، واتباع أفضل الممارسات هذه.
انسخ العناصر الإضافية الأساسية فقط ضمن الأهداف، ونفِّذ أي إجراءات ضرورية
والصحة والتحقق من الصحة قد ينسخ تطبيقك الميزات الإضافية من intent إلى
نية أخرى تُستخدم لإطلاق مكون جديد. يحدث هذا عندما
مكالمات التطبيقات
putExtras(Intent)
أو
putExtras(Bundle)
فإذا كان التطبيق يجري إحدى هذه العمليات، فانسخ فقط الميزات الإضافية التي
يتوقعه مكون الاستقبال. إذا كان الغرض الآخر (الذي يتلقّى النسخة)
تقوم بتشغيل مكون
تصديرها وتعقيمها
والتحقق من صحة الميزات الإضافية قبل نسخها إلى الغرض الذي يبدأ
المكون.
لا تصدِّر مكوّنات تطبيقك بدون داعٍ. على سبيل المثال، إذا
تعتزم تشغيل أحد مكونات التطبيق باستخدام هدف داخلي مدمج، تعيين
سمة android:exported
للمكون إلى false
.
استخدام PendingIntent
بدلاً من
هدف مدمَج. وبهذه الطريقة، عندما يزيل تطبيق آخر PendingIntent
من
التي تشتمل على Intent
، يمكن للتطبيق الآخر تشغيل PendingIntent
باستخدام
هوية تطبيقك. تسمح هذه الإعدادات للتطبيق الآخر بالتشغيل بأمان.
أي مكوّن في تطبيقك، بما في ذلك أي مكوّن لم يتم تصديره.
يوضح المخطّط البياني في الشكل 2 طريقة التحكّم في النظام من (العميل) تطبيق آخر (خدمة) ثم الرجوع إلى تطبيقك:
- ينشئ تطبيقك هدفًا يستدعي نشاطًا في تطبيق آخر. ضمن
هذا الغرض، تضيف كائن
PendingIntent
كعنصر إضافي. هذا الطلب في انتظار المراجعة يستدعي مكونًا في تطبيقك؛ لا يتم تصدير هذا المكون. - وعند تلقّي هدف التطبيق، يعمل التطبيق الآخر على استخراج البيانات المدمجة
عنصر
PendingIntent
. - يستدعي التطبيق الآخر الطريقة
send()
على الكائنPendingIntent
. - بعد إعادة عنصر التحكّم إلى تطبيقك، يستدعي النظام الطلب الذي كانت في انتظار المراجعة. نية الشراء باستخدام سياق التطبيق.
الشكل 2. مخطّط بياني للتواصل بين التطبيقات عند استخدام عملية تعليق متداخلة والنية.
تلقّي هدف ضمني
للإعلان عن الأهداف الضمنية التي يمكن أن يتلقّاها تطبيقك، اذكر فلترًا واحدًا أو أكثر من فلاتر الأهداف بالنسبة إلى
كل مكوّن من مكوّنات تطبيقك مع <intent-filter>
عنصر في ملف البيان.
يحدد كل فلتر أهداف نوع الأهداف التي يقبلها بناءً على إجراء intent،
والبيانات والفئة. لا يقدِّم النظام هدفًا ضمنيًا لمكوِّن تطبيقك إلا إذا
يمكن أن يمرّ intent عبر أحد فلاتر الأهداف.
ملاحظة: دائمًا ما يتمّ تحقيق النية الصريحة في الهدف المحدّد لها. بصرف النظر عن فلاتر الأهداف التي يفصح عنها المكوِّن.
يجب أن يفصح مكوّن التطبيق عن فلاتر منفصلة لكل مهمة فريدة يمكنه تنفيذها.
على سبيل المثال، قد يحتوي نشاط واحد في تطبيق معرض الصور على فلترَين: فلتر واحد.
لعرض الصورة، وفلتر آخر لتعديل الصورة. عندما يبدأ النشاط،
يفحص "Intent
" ويقرِّر كيفية التصرف بناءً على المعلومات المطلوبة
في Intent
(مثل عرض عناصر تحكُّم المحرِّر أو عدم عرضها)
يتم تحديد كل فلتر أهداف من خلال <intent-filter>
عنصر في ملف بيان التطبيق، ويكون مدمجًا في مكون التطبيق المقابل (على سبيل المثال
بصفتك <activity>
العنصر).
في كل مكون تطبيق يتضمن عنصر <intent-filter>
،
قم بتعيين قيمة
android:exported
تشير هذه السمة إلى ما إذا كان يمكن للتطبيقات الأخرى الوصول إلى مكوِّن التطبيق. في بعض
مثل الأنشطة التي تتضمن فلاتر الأهداف
LAUNCHER
الفئة، من المفيد تعيين هذه السمة على true
. وإلا،
فمن الآمن ضبط هذه السمة على false
.
تحذير: إذا كان هناك نشاط أو خدمة أو بث
يستخدم المستلِم في تطبيقك فلاتر الأهداف ولا يُحدِّد القيمة بشكلٍ صريح
بالنسبة إلى android:exported
، لا يمكن تثبيت تطبيقك على جهاز
يعمل بنظام التشغيل Android 12 أو إصدار أحدث.
داخل <intent-filter>
،
يمكنك تحديد نوع النوايا التي تريد قبولها باستخدام واحد أو أكثر
من هذه العناصر الثلاثة:
<action>
- يوضح إجراء الهدف المقبول في السمة
name
. القيمة أن يكون قيمة السلسلة الحرفية لإجراء ما، وليس ثابت الفئة. <data>
- تعريف نوع البيانات المقبولة باستخدام سمة واحدة أو أكثر من السمات التي تحدد
المتعلقة بمعرّف الموارد المنتظم (URI) للبيانات (
scheme
، وhost
، وport
،path
) ونوع MIME. <category>
- توضيح فئة الهدف المقبولة في السمة
name
القيمة يجب أن يكون قيمة السلسلة الحرفية لأحد الإجراءات، وليس ثابت الفئة.ملاحظة: لتلقّي أغراض ضمنية، يجب إجراء ما يلي: يجب أن يتضمن الفئة
CATEGORY_DEFAULT
في فلتر الأهداف. الطرقstartActivity()
و تتعاملstartActivityForResult()
مع كل الأهداف كما لو كانوا قد أعلنوا عن الفئةCATEGORY_DEFAULT
. في حال عدم تعريف هذه الفئة في فلتر الأهداف، لن يتم حلّ أي نوايا ضمنية إلى نشاطك.
على سبيل المثال، إليك بيان نشاط يتضمّن فلتر أهداف لتلقّي
ACTION_SEND
الغرض عندما يكون نوع البيانات نصًا:
<activity android:name="ShareActivity" android:exported="false"> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> </intent-filter> </activity>
يمكنك إنشاء فلتر يتضمن أكثر من مثيل واحد
<action>
،
<data>
<category>
إذا فعلت ذلك، فيجب أن تكون متأكدًا من أن المكون يمكنه التعامل مع جميع
مجموعات من عناصر التصفية هذه.
عندما تريد التعامل مع أنواع متعددة من الأهداف، ولكن فقط في مجموعات محددة من الإجراء والبيانات ونوع الفئة، فستحتاج إلى إنشاء فلاتر أهداف متعددة.
يتم اختبار هدف ضمني مقابل فلتر من خلال مقارنة الغرض من كل نوع ثلاثة عناصر. ليتم تسليمه إلى المكوِّن، يجب أن يجتاز الغرض جميع الاختبارات الثلاثة. فإذا لم يتطابق مع أي منها، لن يتمكن نظام Android من تسليم هدف المكون. ومع ذلك، ونظرًا لأن أحد المكونات قد يحتوي على فلاتر أهداف متعددة، فإن الغرض من ذلك عدم المرور عبر أحد فلاتر المكون قد ينجح في عامل تصفية آخر. يمكنك الاطّلاع على مزيد من المعلومات حول الطريقة التي يتّبعها النظام لحلّ الأهداف في القسم أدناه. حول تحليل الأهداف.
تنبيه: لا يُعد استخدام فلتر الأهداف طريقة آمنة لمنع التطبيقات الأخرى من البدء.
المكونات. على الرغم من أنّ فلاتر الأهداف تحظر مكوّنًا معيّنًا للاستجابة إلى
أنواعًا معيّنة من الأهداف الضمنية، قد يبدأ تطبيق آخر في تشغيل مكوّن تطبيقك
باستخدام نية واضحة إذا حدَّد مطوّر البرامج أسماء المكوّنات.
إذا كان من المهم أن يتمكن تطبيقك الخاص فقط من بدء أحد المكوّنات،
عدم إدراج فلاتر الأهداف في البيان بدلاً من ذلك، اضبط دالة
السمة exported
إلى "false"
لهذا المكون.
وبالمثل، لتجنب تشغيل تطبيق مختلف عن غير قصد
Service
، يُرجى دائمًا استخدام نية صريحة لبدء الخدمة الخاصة بك.
ملاحظة:
بالنسبة إلى جميع الأنشطة، يجب الإفصاح عن فلاتر الأهداف في ملف البيان.
ومع ذلك، يمكن تسجيل فلاتر مستلمي البث ديناميكيًا من خلال الاتصال
registerReceiver()
يمكنك بعد ذلك إلغاء تسجيل المُستلِم في "unregisterReceiver()
". يؤدي ذلك إلى السماح لتطبيقك
للاستماع إلى رسائل بث محدّدة خلال فترة زمنية محدّدة فقط أثناء استخدام تطبيقك
قيد التشغيل.
أمثلة على الفلاتر
لتوضيح بعض سلوكيات فلتر الأهداف، في ما يلي مثال من ملف البيان الخاص بتطبيق المشاركة على وسائل التواصل الاجتماعي:
<activity android:name="MainActivity" android:exported="true"> <!-- This activity is the main entry, should appear in app launcher --> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="ShareActivity" android:exported="false"> <!-- This activity handles "SEND" actions with text data --> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> </intent-filter> <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data --> <intent-filter> <action android:name="android.intent.action.SEND"/> <action android:name="android.intent.action.SEND_MULTIPLE"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="application/vnd.google.panorama360+jpg"/> <data android:mimeType="image/*"/> <data android:mimeType="video/*"/> </intent-filter> </activity>
النشاط الأول، MainActivity
، هو نقطة الدخول الرئيسية للتطبيق - النشاط الذي
عندما يشغِّل المستخدم التطبيق للمرة الأولى الذي يحمل رمز مشغّل التطبيقات:
- الإجراء
ACTION_MAIN
تشير إلى أن هذه هي نقطة الدخول الرئيسية ولا تتوقع أي بيانات نية. - تشير الفئة
CATEGORY_LAUNCHER
إلى أن هذا النشاط في مشغّل تطبيقات النظام. إذا كان العنصر<activity>
في تحديد رمز من خلالicon
، فسيستخدم النظام الرمز من واجهة برمجة التطبيقات<application>
العنصر.
ويجب إقران هذين الاثنين معًا حتى يظهر النشاط في مشغّل التطبيقات.
يهدف النشاط الثاني، ShareActivity
، إلى تسهيل مشاركة النصوص والوسائط.
المحتوى. رغم أنّ المستخدمين قد يدخلون هذا النشاط من خلال الانتقال إليه من MainActivity
،
يمكنه أيضًا الدخول إلى ShareActivity
مباشرةً من تطبيق آخر يصدر رسالة إلكترونية
أهداف تتطابق مع أحد فلترَي الأهداف.
ملاحظة: يتم اعتبار نوع MIME
application/vnd.google.panorama360+jpg
، هو نوع بيانات خاص يحدد
من الصور البانورامية، والتي يمكنك التعامل معها باستخدام عدسة Google
واجهات برمجة تطبيقات بانوراما.
مطابقة الأهداف مع التطبيقات الأخرى فلاتر الأهداف
إذا كان تطبيق آخر يستهدف Android 13 (المستوى 33 لواجهة برمجة التطبيقات) أو إصدارًا أحدث، يمكنه التعامل مع
الغرض من التطبيق فقط إذا تطابق هدفك مع إجراءات وفئات
العنصر <intent-filter>
في ذلك التطبيق الآخر. وإذا لم يعثر النظام على
تطابق، تطرح
ActivityNotFoundException
يجب أن يتعامل تطبيق الإرسال مع
بهذا الاستثناء.
وبالمثل، عند تحديث تطبيقك بحيث يستهدف Android 13
أو أعلى، يتم تسليم جميع الأهداف الناشئة من تطبيقات خارجية إلى
الذي تم تصديره من تطبيقك فقط إذا تطابق هذا الغرض مع الإجراءات
فئات عنصر <intent-filter>
التي يفصح عنها تطبيقك. هذا السلوك
بغض النظر عن إصدار حزمة تطوير البرامج (SDK) المستهدَف للتطبيق المُرسَل.
في الحالات التالية، لا يتم فرض مطابقة الأهداف:
- الأهداف التي يتم إرسالها إلى المكوّنات التي لا تشير إلى أي فلاتر أهداف.
- الأهداف التي تنشأ من داخل التطبيق نفسه
- الأهداف التي تنشأ من النظام أي الأهداف التي يتم إرسالها من
"المعرّف الفريد للنظام" (uid=1000). تتضمن تطبيقات النظام
system_server
والتطبيقات التي يتم ضبط إعداداتها منandroid:sharedUserId
إلىandroid.uid.system
. - النوايا التي تنشأ من الجذر.
اطّلِع على مزيد من المعلومات عن مطابقة الرغبة في الشراء.
استخدام هدف في انتظار المراجعة
الكائن PendingIntent
هو التفاف حول كائن Intent
. الغرض الأساسي من PendingIntent
هو منح إذن لتطبيق أجنبي
لاستخدام Intent
المتضمّنة كما لو تم تنفيذها من
عملية التطبيق الخاصة.
تشمل حالات الاستخدام الرئيسية لهدف في انتظار المراجعة ما يلي:
- الإعلان عن نية للتنفيذ عندما يتّخذ المستخدم إجراءً من خلال الإشعار
(
NotificationManager
الخاص بنظام Android لتنفيذIntent
). - الإعلان عن نية التنفيذ عندما يتخذ المستخدم إجراءً من خلال
أداة التطبيق
(ينفِّذ تطبيق "الشاشة الرئيسية" علامة
Intent
). - إعلان نية التنفيذ في وقت محدّد في المستقبل (نظام التشغيل
ينفذ
AlarmManager
في النظامIntent
).
وتمامًا كما تم تصميم كل عنصر من عناصر Intent
للتعامل معه من خلال مجموعة محدّدة من العناصر
نوع مكوِّن التطبيق (إما Activity
أو Service
أو
BroadcastReceiver
)، لذا يجب أيضًا أن يكون PendingIntent
أنشأناها بنفس الاعتبارات. وعند استخدام هدف في انتظار المراجعة، لا
يمكن تنفيذ الغرض باستخدام طلب مثل startActivity()
. وبدلاً من ذلك، يجب تعريف نوع المكوِّن المقصود عند إنشاء
PendingIntent
من خلال استدعاء طريقة صانع المحتوى المعني:
PendingIntent.getActivity()
مقابلIntent
يبدأActivity
.PendingIntent.getService()
مقابلIntent
يبدأService
.PendingIntent.getBroadcast()
مقابلIntent
يبدأBroadcastReceiver
.
ما لم يكن تطبيقك يتلقّى الأهداف المعلّقة من تطبيقات أخرى
من المحتمل أن تكون الطرق أعلاه لإنشاء PendingIntent
هي الوحيدة
ستحتاج إلى PendingIntent
طريقة.
تأخذ كل طريقة التطبيق الحالي Context
،
علامة Intent
التي تريد التفافها، وعلامة واحدة أو أكثر تحدد
طريقة استخدام الغرض (مثلاً، تحديد ما إذا كان بالإمكان استخدام الغرض أكثر من مرة)
لمزيد من المعلومات عن استخدام الأهداف التي في انتظار المراجعة، اطّلِع على المستندات لكلّ من حالات الاستخدام المعنية، كما هو الحال في الإشعارات والتطبيقات المصغّرة للتطبيقات.
تحديد قابلية التغيّر
إذا كان تطبيقك يستهدف الإصدار 12 من نظام التشغيل Android أو إصدارًا أحدث، عليك تحديد
قابلية التغيّر لكل عناصر PendingIntent
ينشئها تطبيقك للإقرار بأنّ
كائن PendingIntent
محدد قابل للتغيير أو غير قابل للتغيير، استخدم
PendingIntent.FLAG_MUTABLE
أو
PendingIntent.FLAG_IMMUTABLE
على التوالي.
إذا حاول تطبيقك إنشاء عنصر PendingIntent
بدون تعيين أيٍ من علامات قابلية التغيّر، يعرض النظام
IllegalArgumentException
،
ستظهر الرسالة التالية في Logcat:
PACKAGE_NAME: Targeting S+ (version 31 and above) requires that one of \
FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if \
some functionality depends on the PendingIntent being mutable, e.g. if \
it needs to be used with inline replies or bubbles.
إنشاء أهداف في انتظار المراجعة غير قابلة للتغيير متى أمكن
في معظم الحالات، يجب أن ينشئ تطبيقك عناصر PendingIntent
غير قابلة للتغيير، على النحو التالي:
كما هو موضح في مقتطف الرمز التالي. إذا كان الكائن PendingIntent
غير قابل للتغيير،
فلا يمكن للتطبيقات الأخرى تعديل نية تعديل نتيجة استدعاء الإجراء
والنية.
Kotlin
val pendingIntent = PendingIntent.getActivity(applicationContext, REQUEST_CODE, intent, /* flags */ PendingIntent.FLAG_IMMUTABLE)
Java
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), REQUEST_CODE, intent, /* flags */ PendingIntent.FLAG_IMMUTABLE);
ومع ذلك، تتطلّب بعض حالات الاستخدام عناصر PendingIntent
قابلة للتغيّر بدلاً من ذلك:
- إتاحة إجراءات الرد المباشر في
الإشعارات تشير رسالة الأشكال البيانية
يجب إدخال تغيير على بيانات المقطع في الكائن PendingIntent
المرتبط بالرد. عادةً، تطلب هذا التغيير من خلال تمرير
FILL_IN_CLIP_DATA
كعلم إلىfillIn()
. - ربط الإشعارات بإطار عمل Android Auto، باستخدام أمثلة
CarAppExtender
- وضع المحادثات في فقاعات تفسيرية باستخدام المثيلات
من أصل
PendingIntent
. يسمح كائنPendingIntent
القابل للتغيير للنظام بتطبيق العلامات الصحيحة، مثلFLAG_ACTIVITY_MULTIPLE_TASK
أوFLAG_ACTIVITY_NEW_DOCUMENT
- جارٍ طلب معلومات الموقع الجغرافي للجهاز من خلال الاتصال
requestLocationUpdates()
أو واجهات برمجة تطبيقات مشابهة يسمح كائنPendingIntent
القابل للتغيير للنظام بإضافة إضافات الأهداف التي تمثّل أحداث مراحل نشاط الموقع الجغرافي. تتضمن هذه الأحداث التغيير في الموقع الجغرافي وسيصبح مقدّم الخدمة متاحًا. - جدولة المنبّهات باستخدام
AlarmManager
. يسمح كائنPendingIntent
القابل للتغيير للنظام بإضافة السمةEXTRA_ALARM_COUNT
النية الإضافية. تمثل هذه القيمة الإضافية عدد المرات التي يظهر فيها منبّه متكرر تم تحفيزه. من خلال تضمين هذه المعلومات الإضافية، يمكن لهدف الغرض إبلاغه بدقة أحد التطبيقات لمعرفة ما إذا كان قد تم تشغيل منبّه متكرر عدة مرات، مثل عندما كان الجهاز في وضع السكون.
إذا أنشأ تطبيقك عنصر PendingIntent
قابل للتغيّر، ننصحك بشدة باستخدام
استخدام هدف صريح وملء
ComponentName
بهذه الطريقة، كلما
يستدعي تطبيق آخر PendingIntent
ويعيد التحكم إلى تطبيقك،
ويبدأ فيه دائمًا المكون نفسه في تطبيقك.
استخدام أهداف صريحة ضمن الأهداف التي تنتظر المراجعة
لتحديد الطريقة التي يمكن بها للتطبيقات الأخرى استخدام أغراضها التي في انتظار المراجعة، يُرجى دائمًا إحاطة هدف في انتظار المراجعة بنيّة صريحة للمساعدة في اتّباع أفضل الممارسات هذه، اتّبِع الخطوات التالية:
- تحقَّق من أنّ حقول الإجراء والحزمة والمكوِّن خاصة بالهدف الأساسي تحديدها.
-
يمكنك استخدام
FLAG_IMMUTABLE
التي تمت إضافتها في Android 6.0 (المستوى 23 من واجهة برمجة التطبيقات) لإنشاء أهداف في انتظار المراجعة. هذه العلامة لمنع التطبيقات التي تتلقّى الرمزPendingIntent
من الملء السمات غير المعبأة. إذا كانminSdkVersion
لتطبيقك:22
أو أقل، يمكنك توفير الأمان والتوافق معًا باستخدام التعليمة البرمجية التالية:if (Build.VERSION.SDK_INT >= 23) { // Create a PendingIntent using FLAG_IMMUTABLE. } else { // Existing code that creates a PendingIntent. }
دقة النية بالشراء
عندما يتلقى النظام نية ضمنية لبدء نشاط ما، فإنه يبحث عن أفضل نشاط للهدف من خلال مقارنته بفلاتر الأهداف بناءً على ثلاثة جوانب:
- الحركة.
- البيانات (كل من معرّف الموارد المنتظم (URI) ونوع البيانات)
- الفئة.
توضح الأقسام التالية كيفية مطابقة الأهداف مع المكونات المناسبة وفقًا لبيان فلتر الأهداف في ملف بيان التطبيق.
اختبار الإجراء
لتحديد إجراءات النية المقبولة، يمكن لفلتر الأهداف الإعلان عن صفر أو أكثر
<action>
، كما هو موضّح في المثال التالي:
<intent-filter> <action android:name="android.intent.action.EDIT" /> <action android:name="android.intent.action.VIEW" /> ... </intent-filter>
لاجتياز هذا الفلتر، يكون الإجراء المحدّد في Intent
يجب أن يتطابق مع أحد الإجراءات المدرَجة في الفلتر.
إذا لم يدرج عامل التصفية أي إجراءات، فلا يوجد شيء
ونية المطابقة، لذلك تفشل جميع الأهداف في الاختبار. ومع ذلك، إذا كانت Intent
لا يحدد أي إجراء، فإنه يجتاز الاختبار طالما أن عامل التصفية
يحتوي على إجراء واحد على الأقل.
اختبار الفئة
لتحديد فئات الأهداف المقبولة، يمكن أن يذكر فلتر الأهداف صفرًا أو أكثر
<category>
، كما هو موضّح في المثال التالي:
<intent-filter> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> ... </intent-filter>
لكي تتمكّن من اجتياز اختبار الفئات، يجب أن تكون كل فئة من Intent
يجب أن تتطابق مع فئة في الفلتر. العكس ليس ضروريًا، إذ قد يعمل فلتر الأهداف
الإعلان عن فئات أكثر من الفئات المحدّدة في Intent
لا يزال هناك Intent
بطاقات محفوظة. لذلك، لا يكون الغرض من الغرض بدون فئات
يجتاز هذا الاختبار دائمًا، بغض النظر عن الفئات المعلنة في الفلتر.
ملاحظة:
يطبِّق Android الفئة CATEGORY_DEFAULT
تلقائيًا.
إلى جميع الأهداف الضمنية التي تم تمريرها إلى startActivity()
وstartActivityForResult()
.
إذا كنت تريد أن يتلقّى نشاطك نوايا ضمنية، يجب
أدرِج فئة للموقع الإلكتروني "android.intent.category.DEFAULT"
في فلاتر الأهداف، باعتبارها
كما هو موضح في مثال <intent-filter>
السابق.
اختبار البيانات
لتحديد بيانات الأهداف المقبولة، يمكن لفلتر الأهداف الإعلان عن القيمة صفر أو أكثر
<data>
، كما هو موضّح في المثال التالي:
<intent-filter> <data android:mimeType="video/mpeg" android:scheme="http" ... /> <data android:mimeType="audio/mpeg" android:scheme="http" ... /> ... </intent-filter>
كل <data>
تحديد عنوان URI ونوع البيانات (نوع وسائط MIME).
يُعد كل جزء من معرف الموارد المنتظم (URI) منفصلاً
السمة: scheme
، host
، port
،
وpath
:
<scheme>://<host>:<port>/<path>
يوضّح المثال التالي القيم المحتملة لهذه السمات:
content://com.example.project:200/folder/subfolder/etc
في عنوان URI هذا، المخطط هو content
، والمضيف هو com.example.project
،
المنفذ هو 200
والمسار هو folder/subfolder/etc
.
كل سمة من هذه السمات اختيارية في العنصر <data>
،
ولكن هناك تبعيات خطية:
- في حال عدم تحديد مخطط، يتم تجاهل المضيف.
- في حال عدم تحديد مضيف، سيتم تجاهل المنفذ.
- في حال عدم تحديد كل من المخطط والمضيف، سيتم تجاهل المسار.
فعند مقارنة عنوان URI في الغرض بمواصفات معرف موارد منتظم (URI) في أحد الفلاتر، إلا أنه تتم مقارنته فقط بأجزاء عنوان URI المضمّنة في الفلتر. مثلاً:
- إذا حدّد أحد الفلاتر مخططًا فقط، تتطابق جميع معرّفات الموارد المنتظمة (URI) التي تتضمّن هذا المخطط عامل التصفية.
- إذا كان هناك فلتر يحدد مخططًا ومرجعًا ولكن بدون مسار، سيتم استخدام جميع معرفات الموارد المنتظمة (URI) باستخدام نفس المخطط والسلطة يجتازوا عامل التصفية، بغض النظر عن مساراتهم.
- إذا كان الفلتر يحدد مخططًا ومرجعًا ومسارًا، ستلاحظ أنّ معرفات الموارد المنتظمة (URI) هي التي تستخدم نفس المخطط فقط، وسلطة المسار واجتياز عامل التصفية.
ملاحظة: يمكن أن يحدد مواصفات المسار أن يحتوي على علامة نجمية حرف بدل (*) لطلب تطابق جزئي فقط لاسم المسار.
يقارن اختبار البيانات كلاً من معرّف الموارد المنتظم (URI) ونوع MIME في الغرض بمعرّف الموارد المنتظم (URI) ونوع MIME المحدد في الفلتر. القواعد على النحو التالي:
- ينفي الغرض الذي لا يحتوي على معرّف موارد منتظم (URI) أو نوع MIME لاختباره فقط إذا لم يحدد الفلتر أي معرّفات موارد منتظمة (URI) أو أنواع MIME.
- غرض يحتوي على معرّف موارد منتظم (URI) ولكن بدون نوع MIME (ليس صريحًا ولا يمكن استنتاجه من URI) يجتاز الاختبار فقط إذا كان عنوان URI يتوافق مع تنسيق معرّف الموارد المنتظم (URI) للفلتر وبالمثل، لا يحدد الفلتر نوع MIME.
- يجتاز الغرض الذي يشتمل على نوع MIME ولكن ليس معرّف موارد منتظم (URI) الاختبار فقط إذا كان الفلتر يعرض نوع MIME نفسه ولا يحدد تنسيق معرّف موارد منتظم (URI).
- عبارة عن هدف يحتوي على كل من معرّف الموارد المنتظم (URI) ونوع MIME (سواء كان صريحًا أو يمكن استنتاجه من
URI) يجتاز الجزء من نوع MIME من الاختبار فقط إذا كان ذلك
النوع يتطابق مع النوع المدرج في الفلتر. يجتاز جزء معرّف الموارد المنتظم (URI) في الاختبار
إما إذا كان معرّف الموارد المنتظم (URI) الخاص به يتطابق مع عنوان URL في الفلتر أو إذا كان يتضمّن معرّف
content:
أو معرّف الموارد المنتظم (URI)file:
ولا يحدّد الفلتر معرّف موارد منتظم (URI). أو بعبارةٍ أخرى، يُفترض أن يتيح مكوِّن بياناتcontent:
وfile:
إذا يسرد فلترها نوع MIME فقط.
ملاحظة: إذا حدّد الغرض من نوع معرّف الموارد المنتظم (URI) أو نوع MIME، فسيحدّد اختبار البيانات
وسيتعذّر تنفيذ الإجراء إذا لم تتوفّر عناصر <data>
في <intent-filter>
.
تعكس هذه القاعدة الأخيرة، القاعدة (د)، التوقع
أن المكونات يمكنها الحصول على بيانات محلية من موفر ملف أو محتوى.
وبالتالي، يمكن للفلاتر التي يُجريها إدراج نوع بيانات فقط ولا تحتاج إلى إدراجها بشكل صريح
لتسمية المخططَين content:
وfile:
.
يعرض المثال التالي حالة نموذجية يعرض فيها العنصر <data>
.
يخبر Android أنه يمكن للمكوِّن الحصول على بيانات الصور من المحتوى
المستخدم وعرضها:
<intent-filter> <data android:mimeType="image/*" /> ... </intent-filter>
الفلاتر التي نوع البيانات ولكن ليس عنوان URI هي الأكثر شيوعًا لأن معظمها يقوم مزودو المحتوى بتوزيع البيانات.
هناك تكوين شائع آخر وهو عامل تصفية بمخطط ونوع بيانات. بالنسبة
مثال: <data>
مثل ما يلي يخبر Android أنه
يمكن للمكوِّن استرداد بيانات الفيديو من الشبكة لتنفيذ الإجراء:
<intent-filter> <data android:scheme="http" android:mimeType="video/*" /> ... </intent-filter>
مطابقة الأهداف
تتم مطابقة الأهداف مع فلاتر الأهداف، ليس فقط لاكتشاف هدف
لتنشيطه، وكذلك لاكتشاف شيء ما عن مجموعة
المكونات على الجهاز. على سبيل المثال، يملأ تطبيق Home مشغّل التطبيقات.
من خلال العثور على جميع الأنشطة باستخدام فلاتر الأهداف التي تحدّد
إجراء ACTION_MAIN
الفئة CATEGORY_LAUNCHER
.
لا تكون المطابقة ناجحة إلا إذا تطابقت الإجراءات والفئات في الهدف
مقارنةً بالفلتر، كما هو موضّح في المستندات الخاصة بـ IntentFilter
الصف.
يمكن أن يستخدم تطبيقك ميزة "مطابقة الأهداف" بطريقة مشابهة لتلك التي يستخدمها تطبيق Home.
يتضمّن PackageManager
مجموعة من query...()
.
الطرق التي تُرجع جميع المكونات التي يمكن أن تقبل غرضًا معينًا
سلسلة مماثلة من طرق resolve...()
التي تحدد أفضل
للاستجابة لهدف ما. على سبيل المثال:
تعرض الدالة queryIntentActivities()
قائمة بجميع الأنشطة التي يمكن تنفيذها.
تم تمرير الغرض كوسيطة، وستعرض queryIntentServices()
قائمة مشابهة من الخدمات.
لا تعمل أي من الطريقتين على تنشيط المكونات؛ فإنهم فقط يسردون تلك التي
الاستجابة. هناك طريقة مماثلة،
queryBroadcastReceivers()
، لمستلمي البث