إتاحة لوحة المفاتيح للصور

غالبًا ما يرغب المستخدمون في التواصل باستخدام الرموز التعبيرية والملصقات وغيرها من العناصر التفاعلية المحتوى. في الإصدارات السابقة من نظام التشغيل Android، لوحات المفاتيح التي تُعرف أيضًا باسم محرِّري أساليب الإدخال، أو أدوات IME: يمكنها إرسال رموز يونيكود فقط إلى التطبيقات. للحصول على محتوى وافٍ، يتم إنشاء التطبيقات واجهات برمجة التطبيقات الخاصة بالتطبيق التي لا يمكن استخدامها في التطبيقات الأخرى أو تستخدم الحلول البديلة مثل إرسال الصور من خلال إجراء مشاركة بسيط أو الحافظة.

صورة تعرض لوحة مفاتيح تتيح البحث بالصور
الشكل 1. مثال على إتاحة لوحة مفاتيح الصور

بدءًا من الإصدار 7.1 من نظام التشغيل Android (المستوى 25 من واجهة برمجة التطبيقات)، تضم حزمة تطوير البرامج (SDK) لنظام التشغيل Android حزمة Content API، التي تقدّم طريقة عالمية لأدوات IME لإرسال الصور وغيرها المحتوى الوافي مباشرةً إلى محرر نصوص في التطبيق. تتوفر واجهة برمجة التطبيقات أيضًا في مكتبة دعم الإصدار v13 اعتبارًا من الإصدار 25.0.0. ننصحك بالاستعانة بخدمة الدعم المكتبة لأنها تحتوي على طرق مساعدة تبسّط التنفيذ.

باستخدام واجهة برمجة التطبيقات هذه، يمكنك إنشاء تطبيقات مراسلة تقبل المحتوى الوافي من أي لوحة المفاتيح، بالإضافة إلى لوحات المفاتيح التي يمكنها إرسال محتوى وافٍ إلى أي تطبيق. تعمل منصة Google لوحة المفاتيح وتطبيقات مثل الرسائل من Google تقديم واجهة برمجة تطبيقات Content API في نظام التشغيل Android 7.1، كما هو موضَّح في الشكل 1.

يوضح هذا المستند كيفية تنفيذ واجهة برمجة تطبيقات Content API في كل من أدوات IME التطبيقات.

آلية العمل

يتطلب إدراج صورة لوحة المفاتيح المشاركة من أداة IME والتطبيق. تشير رسالة الأشكال البيانية يصف التسلسل التالي كل خطوة في عملية إدراج الصور:

  1. عندما ينقر المستخدم على EditText، يرسل المحرِّر قائمة بأنواع محتوى MIME التي يقبلها EditorInfo.contentMimeTypes

  2. تقرأ أداة IME قائمة الأنواع المتوافقة وتعرض المحتوى في ملفات soft لوحة المفاتيح التي يمكن للمحرر قبولها.

  3. عندما يختار المستخدم صورة، تطلب أداة IME commitContent() وترسل InputContentInfo للمحرر. يشبه الاتصال commitContent() commitText()، ولكن مع المحتوى الوافي. يحتوي InputContentInfo على معرف موارد منتظم (URI) المحتوى في محتوى

تم توضيح هذه العملية في الشكل 2:

صورة تعرض التسلسل من Application إلى IME وتعود إلى التطبيق
الشكل 2. تطبيق IME إلى مسار التطبيق.

إضافة إتاحة الصور إلى التطبيقات

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

Kotlin

var editText: EditText = object : EditText(this) {
    override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection {
        var ic = super.onCreateInputConnection(outAttrs)
        EditorInfoCompat.setContentMimeTypes(outAttrs, arrayOf("image/png"))
        val mimeTypes = ViewCompat.getOnReceiveContentMimeTypes(this)
        if (mimeTypes != null) {
            EditorInfoCompat.setContentMimeTypes(outAttrs, mimeTypes)
            ic = InputConnectionCompat.createWrapper(this, ic, outAttrs)
        }
        return ic
    }
}

Java

EditText editText = new EditText(this) {
    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        InputConnection ic = super.onCreateInputConnection(outAttrs);
        EditorInfoCompat.setContentMimeTypes(outAttrs, new String[]{"image/png"});
        String[] mimeTypes = ViewCompat.getOnReceiveContentMimeTypes(this);
        if (mimeTypes != null) {
            EditorInfoCompat.setContentMimeTypes(outAttrs, mimeTypes);
            ic = InputConnectionCompat.createWrapper(this, ic, outAttrs);
        }
        return ic;
    }
};

في ما يلي شرح إضافي:

  • يستخدم هذا المثال مكتبة الدعم، ولذلك هناك بعض المراجع إلى android.support.v13.view.inputmethod بدلاً من android.view.inputmethod

  • ينشئ هذا المثال EditText ويتجاهل onCreateInputConnection(EditorInfo) لتعديل InputConnection InputConnection هو قناة الاتصال بين أداة IME و التطبيق الذي يتلقى مدخلاته.

  • المكالمة super.onCreateInputConnection() على السلوك المدمج - إرسال النص واستلامه - مرجعًا لـ InputConnection.

  • setContentMimeTypes() تضيف قائمة بأنواع MIME المتوافقة إلى EditorInfo اتصل super.onCreateInputConnection() قبل setContentMimeTypes().

  • يتم تنفيذ السياسة callback كلما نفّذت أداة IME المحتوى. الطريقة onCommitContent() مرجع إلى InputContentInfoCompat, الذي يحتوي على معرف موارد منتظم (URI) للمحتوى.

    • طلب الأذونات وإصدارها إذا كان تطبيقك يعمل بالمستوى 25 من واجهة برمجة التطبيقات أو أعلى وكذلك INPUT_CONTENT_GRANT_READ_URI_PERMISSION التي يتم تعيينها بواسطة أداة IME. بخلاف ذلك، سيكون لديك إذن بالوصول إلى المحتوى معرّف موارد منتظم (URI) لأنه تم منحه بواسطة أداة IME أو لأن موفّر المحتوى لا يحظر الوصول. لمزيد من المعلومات، يُرجى الاطّلاع على إضافة إتاحة استخدام الصور إلى أدوات IME:
  • createWrapper() ويشتمل على InputConnection والEditorInfo المعدَّلة في InputConnection جديدة وتُرجعه.

في ما يلي الممارسات المقترَحة:

  • لا يتصل المحررون الذين لا يدعمون المحتوى الوافي setContentMimeTypes()، ويتركان مجموعة EditorInfo.contentMimeTypes إلى null.

  • يتجاهل المحرّرون المحتوى إذا كان نوع MIME المحدّد في InputContentInfo. لا يطابق أيًا من الأنواع التي تقبلها.

  • لا يؤثّر المحتوى المنسَّق في موضع النص ولا يتأثر به. المؤشر. يمكن للمحررين تجاهل موضع المؤشر عند التعامل مع المحتوى.

  • في دور المحرر OnCommitContentListener.onCommitContent()، يمكنك عرض true بشكل غير متزامن، حتى قبل تحميل المحتوى.

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

لاختبار تطبيقك، تأكّد من أنّ جهازك أو المحاكي يتضمّن لوحة مفاتيح يمكنها إرسال المحتوى الوافي. يمكنك استخدام لوحة مفاتيح Google في الإصدار 7.1 من نظام Android أو الإصدارات الأحدث.

إتاحة عرض الصور في أدوات IME

على أدوات IME التي تريد إرسال محتوى وافٍ إلى التطبيقات تنفيذ محتوى Commit. API، كما هو موضّح في المثال التالي:

  • تجاهُل onStartInput() أو onStartInputView() واقرأ قائمة أنواع المحتوى المتوافقة من الهدف المحرِّر. يعرض مقتطف الرمز التالي كيفية التحقق مما إذا كان الهدف المحرر صور GIF.

Kotlin

override fun onStartInputView(editorInfo: EditorInfo, restarting: Boolean) {
    val mimeTypes: Array<String> = EditorInfoCompat.getContentMimeTypes(editorInfo)

    val gifSupported: Boolean = mimeTypes.any {
        ClipDescription.compareMimeTypes(it, "image/gif")
    }

    if (gifSupported) {
        // The target editor supports GIFs. Enable the corresponding content.
    } else {
        // The target editor doesn't support GIFs. Disable the corresponding
        // content.
    }
}

Java

@Override
public void onStartInputView(EditorInfo info, boolean restarting) {
    String[] mimeTypes = EditorInfoCompat.getContentMimeTypes(editorInfo);

    boolean gifSupported = false;
    for (String mimeType : mimeTypes) {
        if (ClipDescription.compareMimeTypes(mimeType, "image/gif")) {
            gifSupported = true;
        }
    }

    if (gifSupported) {
        // The target editor supports GIFs. Enable the corresponding content.
    } else {
        // The target editor doesn't support GIFs. Disable the corresponding
        // content.
    }
}
  • التزام المحتوى بالتطبيق عندما يختار المستخدم صورة. تجنُّب إجراء المكالمات commitContent() عندما يكون هناك أي نص يتم إنشاؤه، لأنه إلى فقدان المحرر التركيز. يوضح مقتطف الرمز التالي كيفية تصميم صورة GIF

Kotlin

// Commits a GIF image.

// @param contentUri = Content URI of the GIF image to be sent.
// @param imageDescription = Description of the GIF image to be sent.

fun commitGifImage(contentUri: Uri, imageDescription: String) {
    val inputContentInfo = InputContentInfoCompat(
            contentUri,
            ClipDescription(imageDescription, arrayOf("image/gif")),
            null
    )
    val inputConnection = currentInputConnection
    val editorInfo = currentInputEditorInfo
    var flags = 0
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
        flags = flags or InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION
    }
    InputConnectionCompat.commitContent(inputConnection, editorInfo, inputContentInfo, flags, null)
}

Java

// Commits a GIF image.

// @param contentUri = Content URI of the GIF image to be sent.
// @param imageDescription = Description of the GIF image to be sent.

public static void commitGifImage(Uri contentUri, String imageDescription) {
    InputContentInfoCompat inputContentInfo = new InputContentInfoCompat(
            contentUri,
            new ClipDescription(imageDescription, new String[]{"image/gif"}),
            null
    );
    InputConnection inputConnection = getCurrentInputConnection();
    EditorInfo editorInfo = getCurrentInputEditorInfo();
    Int flags = 0;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
        flags |= InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION;
    }
    InputConnectionCompat.commitContent(
            inputConnection, editorInfo, inputContentInfo, flags, null);
}

بصفتك مؤلف أداة IME، عليك على الأرجح استخدام موفر المحتوى الخاص بك الاستجابة لطلبات معرف الموارد المنتظم (URI) للمحتوى. ولكن الاستثناء هو إذا كان أداة IME تتوافق مع المحتوى من مزودي المحتوى الحاليين مثل MediaStore للحصول على معلومات عن موفِّري المحتوى الذين ينشئون المحتوى، فراجع المحتوى الجهة الموفّرة للخدمة والملف Google for Education.

إذا كنت تنشئ موفّر محتوى خاصًا بك، ننصحك بعدم تصديره. عبر الإعداد android:exported إلى false يمكنك بدلاً من ذلك تفعيل منح الإذن في موفّر الخدمة من خلال ضبط android:grantUriPermission إلى true. بعد ذلك، يمكن لأداة IME منح الأذونات للوصول إلى معرّف الموارد المنتظم (URI) للمحتوى في حال إذا كان المحتوى ملتزمًا وهناك طريقتان لذلك:

  • في الإصدار 7.1 من نظام التشغيل Android (المستوى 25 من واجهة برمجة التطبيقات) والإصدارات الأحدث، عند الاتصال بخدمة commitContent()، ضبط معلمة العلامة على INPUT_CONTENT_GRANT_READ_URI_PERMISSION بعد ذلك، يمكن لكائن InputContentInfo الذي يتلقّاه التطبيق طلبه إِصْدَارْ إِذْنْ بِالْقِرَاءَة الْمُؤَقَّتْ عَنْ طَرِيقْ نَتِيجَةْ requestPermission() أو releasePermission()

  • في الإصدار Android 7.0 (المستوى 24 لواجهة برمجة التطبيقات) والإصدارات الأقدم، تم تجاهل INPUT_CONTENT_GRANT_READ_URI_PERMISSION، لذا سيتم منحه يدويًا إذن بالوصول إلى المحتوى. تتمثل إحدى طرق القيام بذلك grantUriPermission()، ولكن يمكنك تنفيذ آليتك الخاصة يلبي متطلباتك الخاصة.

لاختبار أداة IME، تأكد من وجود تطبيق على جهازك أو المحاكي يمكنه استقبال المحتوى الوافي. يمكنك استخدام تطبيق مراسلة Google في الإصدار 7.1 من نظام Android أو الإصدارات الأحدث.