تلقّي البيانات من تطبيقات أخرى

مثلما يمكن للتطبيق إرسال البيانات إلى تطبيقات أخرى، يمكنه أيضًا تلقّي البيانات من تطبيقات أخرى. فكِّر في كيفية تفاعل المستخدمين مع تطبيقك وأنواع البيانات التي تريد تلقّيها من التطبيقات الأخرى. على سبيل المثال، قد يكون تطبيق شبكة اجتماعية مهتمًا بتلقّي محتوى نصي، مثل عنوان URL مثير للاهتمام على الويب، من تطبيق آخر.

في التطبيقات التي تستخدم ميزة "التنقّل في Compose"، يتطلّب تلقّي البيانات المُرسَلة من تطبيق آخر ثلاث خطوات:

  1. الإعلان عن <intent-filter> في ملف البيان: يجب إضافة فلتر الأهداف إلى نشاطك في ملف AndroidManifest.xml. يُعلم هذا الإجراء نظام التشغيل Android بأنّ تطبيقك قادر على تلقّي إجراءات معيّنة (مثل ACTION_SEND) وأنواع MIME (مثل text/plain).

  2. حدِّد navDeepLink في الرسم البياني لـ Compose Navigation: أرفِق navDeepLink يتطابق مع الإجراء ونوع MIME مباشرةً بالوجهة القابلة للإنشاء التي من المفترض أن تعرض المحتوى. يعترض NavController الطلب الوارد تلقائيًا ويوجه المستخدم مباشرةً إلى تلك الشاشة.

  3. استخرِج حمولة البيانات الواردة: في شاشة الوجهة، يمكنك الوصول إلى الإضافات الخاصة بالطلب (مثل EXTRA_TEXT أو EXTRA_STREAM) لاسترداد المحتوى المشترَك وتعديل حالة واجهة المستخدم.

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

أنواع MIME المتوافقة

من الأفضل أن يتمكّن التطبيق من تلقّي أكبر نطاق ممكن من أنواع MIME. على سبيل المثال، تطبيق المراسلة المصمّم لإرسال النصوص والصور والفيديوهات يجب أن يتيح تلقّي text/* وimage/* وvideo/*. في ما يلي بعض أنواع MIME الشائعة لإرسال البيانات واستلامها في Android.

يسجّل المستلِمون في يرسل المرسِلون
text/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
image/*
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
امتدادات الملفات المتوافقة application/pdf

يمكنك الاطّلاع على السجلّ الرسمي لأنواع وسائط MIME في IANA.

إنشاء أهداف مشاركة رائعة

عندما ينقر المستخدمون على هدف مشاركة مرتبط بنشاط معيّن، يجب السماح لهم بتأكيد المحتوى المشترَك وتعديله قبل أن يستخدمه تطبيقك. هذا مهم بشكل خاص للبيانات النصية.

تلقّي البيانات في تطبيقك

لتلقّي البيانات التي تمت مشاركتها في تطبيق يستخدم Compose، يجب تعريف فلاتر الأهداف في ملف البيان، وتوجيه الأهداف الواردة إلى الشاشة المناسبة باستخدام الروابط لصفحات معيّنة، واستخراج الحمولة من الهدف لتعديل واجهة المستخدم.

تعديل ملف البيان

تُعلم فلاتر Intent النظام بالأهداف التي يقبلها مكوِّن التطبيق. على غرار طريقة إنشاء intent باستخدام إجراء ACTION_SEND في درس إرسال البيانات إلى تطبيقات أخرى، يمكنك إنشاء intent filters لتلقّي intents باستخدام هذا الإجراء. يمكنك تحديد intent filter في ملف البيان باستخدام عنصر <intent-filter>. على سبيل المثال، إذا كان تطبيقك يتعامل مع تلقّي محتوى نصي، فإنّ البيان الذي يتضمّن صورة واحدة أو أكثر من أي نوع سيبدو مثل المقتطف التالي:

<activity android:name=".ui.MyActivity" android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND_MULTIPLE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="image/*" />
    </intent-filter>
</activity>

عندما يحاول تطبيق آخر مشاركة أي من هذه العناصر من خلال إنشاء نية وتمريرها إلى startActivity()، يتم إدراج تطبيقك كخيار في "قائمة مشاركة البيانات من Android" أو أداة حلّ النية. إذا اختار المستخدم تطبيقك، سيبدأ النشاط المقابل (.ui.MyActivity في المثال السابق). ويعود إليك بعد ذلك التعامل مع المحتوى بشكل مناسب ضمن الرمز البرمجي وواجهة المستخدم.

في ميزة "التنقّل في Compose"، يمكنك إرفاق navDeepLink مباشرةً بالوجهة القابلة للإنشاء التي من المفترض أن تعرض المحتوى. عندما يشارك تطبيق آخر بيانات تتطابق مع فلتر intent، يوجّه Compose Navigation المستخدم مباشرةً إلى هذه الوجهة:

يطابق navDeepLink الإجراء ونوع MIME للطلب الوارد للانتقال إلى شاشة الوجهة الصحيحة. بعد الوصول إلى تلك الوجهة، يفحص المعالج النية لتحديد الحمولة التي تم تلقّيها (مثل صورة واحدة مقابل صور متعددة) ويستخرج الإضافات المقابلة.

معالجة المحتوى الوارد

لاسترداد المحتوى الذي تم إرساله من خلال Intent، اقرأ النشاط الحالي من LocalActivity.current ضمن الدالة المركّبة، ثم افحص الغرض لتحديد الإجراء التالي. إذا كان من الممكن بدء هذا النشاط من أجزاء أخرى من النظام (مثل مشغّل التطبيقات)، يجب أخذ ذلك في الاعتبار عند فحص الغرض.

يجب توخي الحذر عند التحقّق من البيانات الواردة، فقد يتم ضبط نوع MIME غير صحيح، أو قد تكون الصورة المرسَلة كبيرة جدًا. يجب معالجة البيانات الثنائية أو عمليات الإدخال والإخراج الكثيفة (مثل فك ترميز الصور الكبيرة أو كتابة الملفات) بشكل غير متزامن باستخدام الكوروتين (مثل Dispatchers.IO) بدلاً من سلسلة واجهة المستخدم الرئيسية.

@Composable
fun SharesheetHandler() {
    val activity = LocalActivity.current
    val intent = activity?.intent

    when (intent?.action) {
        Intent.ACTION_SEND -> {
            if (intent.type == "text/plain") {
                handleSendText(intent) // Handle text being sent
            } else if (intent.type?.startsWith("image/") == true) {
                handleSendImage(intent) // Handle single image being sent
            }
        }

        Intent.ACTION_SEND_MULTIPLE -> {
            if (intent.type?.startsWith("image/") == true) {
                handleSendMultipleImages(intent) // Handle multiple images being sent
            }
        }

        else -> {
            // Handle other intents, such as being started from the home screen
        }
    }
}

private fun handleSendText(intent: Intent) {
    intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
        // Update UI state with the shared text
    }
}

private fun handleSendImage(intent: Intent) {
    val imageUri = IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java)
    imageUri?.let {
        // Update UI state with the shared image
    }
}

private fun handleSendMultipleImages(intent: Intent) {
    val imageUris =
        IntentCompat.getParcelableArrayListExtra(intent, Intent.EXTRA_STREAM, Uri::class.java)
    imageUris?.let {
        // Update UI state with the shared images
    }
}

عند استخراج بيانات ثنائية أو معرّفات موارد منتظمة (URI) من إضافات intent (مثل EXTRA_STREAM)، استخدِم IntentCompat.getParcelableExtra() أو IntentCompat.getParcelableArrayListExtra() من مكتبة AndroidX Core، كما هو موضّح في الدالتَين السابقتَين handleSendImage وhandleSendMultipleImages. في الإصدار Android 13 (مستوى واجهة برمجة التطبيقات 33)، تم إيقاف طريقة Intent.getParcelableExtra(String) غير المحدَّدة المَعلمات نهائيًا واستبدالها بطرق تمنع أخطاء الكتابة وتستخدم نوع الفئة المتوقَّع.

يمكن أن يكون تعديل واجهة المستخدم بعد تلقّي البيانات بسيطًا مثل تعديل الحالة لتعبئة TextField، أو معقّدًا مثل تطبيق فلتر على صورة. ويعود الأمر إلى تطبيقك في ما يحدث بعد ذلك.

مشاركة عنوان URL للقطة الشاشة

عند أخذ لقطة شاشة، يمكنك مشاركتها مع أي عنوان URL مرتبط بها. يوفّر ذلك تجربة مستخدم أكثر ثراءً. عند تلقّي عنوان URL، احرص على الحصول على حقل EXTRA_TEXT من الطلب، كما هو موضّح في المثال التالي:

IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java).let {
    // Handle the EXTRA_TEXT as well
    val extraText = intent.getCharSequenceExtra(Intent.EXTRA_TEXT)
    // Update UI state with the shared image and the EXTRA_TEXT if available
}

التأكّد من أنّ المستخدمين يتعرّفون على تطبيقك

يتم تمثيل تطبيقك من خلال رمزه وتصنيفه في "قائمة مشاركة البيانات من Android" وأداة حلّ الأهداف. يتم تحديد كليهما في البيان. يمكنك ضبط تصنيفات فلاتر الأنشطة أو الأهداف لتوفير المزيد من السياق.

اعتبارًا من الإصدار 10 من نظام التشغيل Android (المستوى 29 لواجهة برمجة التطبيقات)، لا تستخدم قائمة مشاركة البيانات من Android سوى الرموز التي تم ضبطها في ملف البيان في علامة application. يتجاهل Android الرموز التي تم ضبطها على علامتَي intent-filter وactivity.

تلقّي محتوى وافٍ

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

  • اللصق من الحافظة (قائمة النقر مع الاستمرار)
  • إدراج الوسائط مباشرةً من لوحة المفاتيح الافتراضية (IME)، مثل الملصقات أو صور GIF
  • سحب المحتوى وإفلاته من تطبيق آخر في وضع النوافذ المتعددة أو وضع تقسيم الشاشة

في واجهات المستخدم المستندة إلى العرض، يقدّم Android 12 (المستوى 31 لواجهة برمجة التطبيقات) وAndroidX Core 1.7 واجهة برمجة التطبيقات الموحّدة OnReceiveContentListener. يجمع هذا المستمع بين معالجة المحتوى من الحافظة ولوحة المفاتيح والسحب والإفلات في استدعاء واحد. للحصول على تعليمات مفصّلة حول كيفية تنفيذ ذلك في Views، يُرجى الاطّلاع على تلقّي محتوى وافٍ.

في Jetpack Compose، يمكنك التعامل مع تلقّي المحتوى الوافي الذي يتم إدراجه في مكوّنات واجهة المستخدم (مثل حقول النص) باستخدام المُعدِّل Modifier.contentReceiver أو مُعدِّلات السحب والإفلات.