السماح للتطبيقات الأخرى ببدء نشاطك

إذا كان بإمكان تطبيقك تنفيذ إجراء قد يكون مفيدًا لتطبيق آخر، عليك تجهيزه للاستجابة لطلبات الإجراءات من خلال تحديد فلتر الأهداف المناسب في نشاطك.

على سبيل المثال، إذا أنشأت تطبيقًا اجتماعيًا يمكنه مشاركة الرسائل أو الصور مع أصدقاء المستخدم، ادعم هدف ACTION_SEND. وبعد ذلك، عندما يبدأ المستخدمون إجراء "مشاركة" من تطبيق آخر، يظهر تطبيقك كخيار في مربّع حوار أداة الاختيار (المعروف أيضًا باسم مربع حوار التوضيح)، كما هو موضَّح في الشكل 1.

الشكل 1. مربّع حوار أداة الاختيار

للسماح للتطبيقات الأخرى ببدء نشاطك بهذه الطريقة، عليك إضافة عنصر <intent-filter> في ملف البيان للعنصر <activity> المقابل.

عند تثبيت تطبيقك على أحد الأجهزة، يحدد النظام فلاتر الأهداف ويضيف المعلومات إلى الكتالوج الداخلي من الأهداف التي تتوافق معها جميع التطبيقات المثبَّتة. عندما يتصل أحد التطبيقات بـ startActivity() أو startActivityForResult() بنيّة ضمنية، يتحقّق النظام من الأنشطة التي يمكنها الاستجابة للهدف.

إضافة فلتر أهداف

لتحديد الأغراض التي يمكن لنشاطك التجاري التعامل معها بشكل صحيح، اجعل كل فلتر أهداف تضيفه محددًا قدر الإمكان من حيث نوع الإجراء والبيانات التي يقبلها النشاط.

قد يرسل النظام عنصر Intent محدّدًا إلى نشاط إذا كان ذلك النشاط يتضمّن فلتر أهداف يستوفي المعايير التالية لكائن Intent:

الإجراء
سلسلة لتسمية الإجراء المطلوب تنفيذه. عادةً ما تكون إحدى القيم التي يحددها النظام الأساسي، مثل ACTION_SEND أو ACTION_VIEW.

حدِّد ذلك في فلتر الأهداف باستخدام العنصر <action>. يجب أن تكون القيمة التي تحددها في هذا العنصر هي اسم السلسلة الكامل للإجراء، بدلاً من ثابت واجهة برمجة التطبيقات، كما هو موضّح في الأمثلة الواردة في هذه الصفحة.

البيانات
وصف للبيانات المرتبطة بالغرض.

حدِّد ذلك في فلتر الأهداف باستخدام العنصر <data>. باستخدام سمة واحدة أو أكثر في هذا العنصر، يمكنك تحديد نوع MIME أو بادئة عنوان URI أو مخطط معرف موارد منتظم (URI)، أو مزيج من هذه السمات وغيرها مما يشير إلى نوع البيانات المقبول.

ملاحظة: إذا لم تكن بحاجة إلى توضيح تفاصيل حول البيانات: Uri، مثلاً عندما يعالج نشاطك نوعًا آخر من البيانات "الإضافية"، بدلاً من معرّف الموارد المنتظم (URI)، حدِّد فقط السمة android:mimeType لتوضيح نوع البيانات التي يتعامل معها نشاطك، مثل text/plain أو image/jpeg.

الفئة
توفّر طريقة إضافية لوصف النشاط الذي يتعامل مع الغرض، ويرتبط عادةً بإيماءة المستخدم أو الموقع الجغرافي الذي بدأ منه. هناك العديد من الفئات المختلفة التي يدعمها النظام، ولكن نادرًا ما يتم استخدام معظمها. ومع ذلك، يتم تحديد كل الأغراض الضمنية باستخدام CATEGORY_DEFAULT تلقائيًا.

حدِّد هذا الحقل في فلتر الأهداف باستخدام العنصر <category>.

في فلتر الأهداف، يمكنك توضيح المعايير التي يقبلها نشاطك من خلال تعريف كل منها بعناصر 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>

ملاحظة: لتلقّي الأغراض الضمنية، عليك تضمين الفئة CATEGORY_DEFAULT في فلتر الأهداف. تتعامل الطريقتان startActivity() وstartActivityForResult() مع جميع الأغراض كما لو كانتا قد أعلنا عن الفئة CATEGORY_DEFAULT. وإذا لم تذكر ذلك في فلتر الأهداف، لن يتم حل أي أغراض ضمنية لنشاطك.

لمزيد من المعلومات حول إرسال وتلقّي رغبات ACTION_SEND التي تنفّذ سلوكيات المشاركة على الشبكات الاجتماعية، يُرجى الاطّلاع على تلقّي بيانات بسيطة من تطبيقات أخرى. يمكنك أيضًا العثور على معلومات مفيدة حول مشاركة البيانات في مشاركة البيانات البسيطة ومشاركة الملفات.

التعامل مع الغرض من نشاطك

لتحديد الإجراء الذي تريد اتخاذه في نشاطك، اقرأ 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()، وإلا سيتم تجاهل النتيجة.