تلقّي محتوى ثري

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

يحب المستخدمون الصور ومقاطع الفيديو وغير ذلك من المحتوى المعبر، ولكن إدراج إلا أن نقل هذا المحتوى في التطبيقات ليس بالأمر السهل دائمًا. لتبسيط الأمر على التطبيقات تلقي محتوى وافٍ، يوفِّر Android 12 (المستوى 31 لواجهة برمجة التطبيقات) واجهة برمجة تطبيقات موحّدة يسمح لتطبيقك بقبول المحتوى من أي مصدر: الحافظة أو لوحة المفاتيح أو السحب.

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

وللتوافق مع الأنظمة القديمة مع إصدارات Android السابقة، يمكن استخدام واجهة برمجة التطبيقات هذه المتوفرة في AndroidX، بدءًا من Core 1.7 Appcompat 1.4, التي ننصحكم باستخدامها عند تطبيق هذه الوظيفة

نظرة عامة

مع واجهات برمجة التطبيقات الحالية الأخرى، تتوفر كل آلية من آلية واجهة المستخدم، مثل اللمس قائمة الانتظار أو السحب — لها واجهة برمجة تطبيقات خاصة بها. هذا يعني أنه يجب عليك مع كل واجهة برمجة تطبيقات على حدة، مع إضافة رمز مماثل لكل آلية لإدراج محتوى:

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

تدمج واجهة برمجة التطبيقات OnReceiveContentListener مسارات الرموز المختلفة هذه من خلال إنشاء واجهة برمجة تطبيقات واحدة لتنفيذها، حتى تتمكّن من التركيز على المنطق الخاص بالتطبيق واترك الباقي على المنصة:

صورة تعرض واجهة برمجة التطبيقات الموحّدة والمبسّطة
الشكل 3. تتيح لك واجهة برمجة التطبيقات الموحدة تنفيذ واجهة واجهة برمجة تطبيقات تتوافق مع جميع آليات واجهة المستخدم

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

التنفيذ

واجهة برمجة التطبيقات هي واجهة مستمِع تُستخدم بطريقة واحدة، OnReceiveContentListener إذا كنت تستخدم إصدارات قديمة من نظام Android الأساسي، ننصحك باستخدام مطابقة OnReceiveContentListener في مكتبة AndroidX Core.

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

Kotlin

object MyReceiver : OnReceiveContentListener {
    val MIME_TYPES = arrayOf("image/*", "video/*")
    
    // ...
    
    override fun onReceiveContent(view: View, payload: ContentInfoCompat): ContentInfoCompat? {
        TODO("Not yet implemented")
    }
}

Java

public class MyReceiver implements OnReceiveContentListener {
     public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};
     // ...
}

بعد تحديد جميع أنواع MIME للمحتوى الذي يتيحه تطبيقك، يجب تنفيذ بقية المستمع:

Kotlin

class MyReceiver : OnReceiveContentListener {
    override fun onReceiveContent(view: View, contentInfo: ContentInfoCompat): ContentInfoCompat {
        val split = contentInfo.partition { item: ClipData.Item -> item.uri != null }
        val uriContent = split.first
        val remaining = split.second
        if (uriContent != null) {
            // App-specific logic to handle the URI(s) in uriContent.
        }
        // Return anything that your app didn't handle. This preserves the
        // default platform behavior for text and anything else that you aren't
        // implementing custom handling for.
        return remaining
    }

    companion object {
        val MIME_TYPES = arrayOf("image/*", "video/*")
    }
}

Java

 public class MyReceiver implements OnReceiveContentListener {
     public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};

     @Override
     public ContentInfoCompat onReceiveContent(View view, ContentInfoCompat contentInfo) {
         Pair split = contentInfo.partition(
                 item -> item.getUri() != null);
         ContentInfo uriContent = split.first;
         ContentInfo remaining = split.second;
         if (uriContent != null) {
             // App-specific logic to handle the URI(s) in uriContent.
         }
         // Return anything that your app didn't handle. This preserves the
         // default platform behavior for text and anything else that you aren't
         // implementing custom handling for.
         return remaining;
     }
 }

إذا كان تطبيقك يتيح المشاركة المستندة إلى الأهداف، يمكنك إعادة استخدام منطق خاص بالتطبيق للتعامل مع معرفات الموارد المنتظمة (URI) للمحتوى. قم بإرجاع أي بيانات متبقية إلى تفويض المعالجة لتلك البيانات إلى النظام الأساسي.

بعد تنفيذ المستمع، قم بتعيينه على عناصر واجهة المستخدم المناسبة في تطبيقك:

Kotlin

class MyActivity : Activity() {
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        val myInput = findViewById(R.id.my_input)
        ViewCompat.setOnReceiveContentListener(myInput, MyReceiver.MIME_TYPES, MyReceiver())
    }
}

Java

public class MyActivity extends Activity {
     @Override
     public void onCreate(Bundle savedInstanceState) {
         // ...

         AppCompatEditText myInput = findViewById(R.id.my_input);
         ViewCompat.setOnReceiveContentListener(myInput, MyReceiver.MIME_TYPES, new MyReceiver());
     }
}

أذونات معرّف الموارد المنتظم (URI)

يتم منح أذونات القراءة وإصدارها تلقائيًا بواسطة النظام الأساسي لأي معرّفات الموارد المنتظمة (URI) للمحتوى في تم تمرير الحمولة إلى OnReceiveContentListener.

عادةً ما يعالج تطبيقك معرّفات الموارد المنتظمة (URI) للمحتوى في خدمة أو نشاط. بالنسبة ومعالجة طويلة الأمد، واستخدام WorkManager. عند تنفيذ هذا، توسيع الأذونات للخدمة أو النشاط المستهدف من خلال تمرير المحتوى باستخدام Intent.setClipData ووضع العلامة FLAG_GRANT_READ_URI_PERMISSION

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

طرق العرض المخصّصة

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

إذا ألغيت فئة View onCreateInputConnection استخدم واجهة برمجة تطبيقات Jetpack InputConnectionCompat.createWrapper لتهيئة InputConnection.

إذا ألغيت فئة View onTextContextMenuItem يتم تفويض المستخدم إلى Super عندما يكون عنصر القائمة R.id.paste أو R.id.pasteAsPlainText.

مقارنة بواجهة برمجة التطبيقات لصور لوحة المفاتيح

يمكنك اعتبار واجهة برمجة تطبيقات OnReceiveContentListener بمثابة الإصدار القادم من واجهة برمجة تطبيقات صورة لوحة المفاتيح الحالية. لقد طوّرنا هذه الميزة تتيح واجهة برمجة التطبيقات وظائف واجهة برمجة تطبيقات صورة لوحة المفاتيح بالإضافة إلى بعض الميزات الإضافية. يختلف توافق الأجهزة والميزات وفقًا سواء كنت تستخدم مكتبة Jetpack أو واجهات برمجة التطبيقات الأصلية من حزمة تطوير البرامج (SDK) لنظام التشغيل Android.

الجدول 1. الميزات المتاحة ومستويات واجهة برمجة التطبيقات المتوافقة مع Jetpack.
الإجراء أو الميزة متوافقة مع واجهة برمجة التطبيقات لصور لوحة المفاتيح متاح من خلال واجهة برمجة التطبيقات الموحدة
إدراج شريحة من لوحة المفاتيح نعم (المستوى 13 من واجهة برمجة التطبيقات والمستويات الأعلى) نعم (المستوى 13 من واجهة برمجة التطبيقات والمستويات الأعلى)
الإدراج باستخدام لصق من اللمس & قائمة الانتظار لا نعم
الإدراج باستخدام السحب والإفلات لا نعم (المستوى 24 من واجهة برمجة التطبيقات والمستويات الأعلى)
الجدول 2. الميزات المتاحة ومستويات واجهة برمجة التطبيقات للإعلانات المدمجة مع المحتوى واجهات برمجة التطبيقات.
الإجراء أو الميزة متوافقة مع واجهة برمجة التطبيقات لصور لوحة المفاتيح متاح من خلال واجهة برمجة التطبيقات الموحدة
إدراج شريحة من لوحة المفاتيح نعم (المستوى 25 من واجهة برمجة التطبيقات والمستويات الأعلى) نعم (نظام التشغيل Android 12 والإصدارات الأحدث)
الإدراج باستخدام لصق من اللمس & قائمة الانتظار لا
الإدراج باستخدام السحب والإفلات لا