בדרך כלל, המשתמשים רוצים לתקשר באמצעות אמוג'י, סטיקרים וסוגים אחרים של תוכן עשיר תוכן. בגרסאות קודמות של Android, מקלדות רכות, שנקראות גם עורכים של שיטות הקלט, או רכיבי IME - ניתן לשלוח לאפליקציות אמוג'י ב-Unicode בלבד. לתוכן עשיר, אפליקציות ממשקי API ספציפיים לאפליקציות, שלא ניתן היה להשתמש בהם באפליקציות אחרות או להשתמש בפתרונות עקיפים כמו שליחת תמונות באמצעות פעולת שיתוף פשוטה או בלוח העריכה.
החל מ-Android 7.1 (רמת API 25), Android SDK כולל את האפשרות Commit Content API, שמספק דרך אוניברסלית לשליחת תמונות לרכיבי IME תוכן עשיר ישירות לכלי לעריכת טקסט באפליקציה. ה-API זמין גם ספריית התמיכה v13 נכון לגרסה 25.0.0. מומלץ להשתמש ב'תמיכה' ספרייה כי היא מכילה שיטות מסייעות שמפשטות את ההטמעה.
באמצעות ה-API הזה, תוכלו לפתח אפליקציות להעברת הודעות שמקבלות תוכן עשיר מכל מקלדת ומקלדות שיכולות לשלוח תוכן עשיר לכל אפליקציה. פלטפורמת Google מקלדת ואפליקציות כמו Messages של Google תומכים ב-Commit Content API ב-Android 7.1, כפי שמוצג באיור 1.
המסמך הזה מראה איך להטמיע את Commit Content API ברכיבי IME באפליקציות.
איך זה עובד
כדי להוסיף תמונה במקלדת, נדרשת השתתפות ב-IME ומהאפליקציה. ברצף הבא מתאר כל שלב בתהליך הוספת התמונה:
כשהמשתמש מקיש על
EditText
, העורך שולח רשימה של סוגי תוכן MIME שהוא מקבלEditorInfo.contentMimeTypes
ה-IME קורא את רשימת הסוגים הנתמכים ומציג תוכן שהעורך יכול לקבל.
כאשר המשתמש בוחר תמונה, ה-IME קורא
commitContent()
ושולחתInputContentInfo
לעורך. הקריאהcommitContent()
מקבילהcommitText()
, אבל כשמדובר בתוכן עשיר.InputContentInfo
מכיל URI מזהה את התוכן בתוכן ספק.
התהליך הזה מתואר באיור 2:
הוספת תמיכה בתמונות לאפליקציות
כדי לקבל תוכן עשיר מרכיבי IME, האפליקציה חייבת להגדיר ל-IMEs אילו סוגי תוכן היא
מקבל ומציינים שיטת קריאה חוזרת שמופעלת כשהתוכן מתקבל.
הדוגמה הבאה ממחישה איך יוצרים 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 של תוכן.- שליחת בקשה ואישור הרשאות אם האפליקציה פועלת ברמת API 25
ומעלה,
INPUT_CONTENT_GRANT_READ_URI_PERMISSION
מוגדר על ידי ה-IME. אחרת, כבר יש לך גישה לתוכן URI מכיוון שהוא מוענק על ידי ה-IME או מפני שספק התוכן לא מגבילה את הגישה. למידע נוסף, אפשר לעיין בהוספת תמיכה בתמונות אל IME
- שליחת בקשה ואישור הרשאות אם האפליקציה פועלת ברמת API 25
ומעלה,
createWrapper()
כולל אתInputConnection
, אתEditorInfo
שהשתנה ואת הקריאה החוזרת למכשירInputConnection
חדש, ומחזירה אותו.
אלה השיטות המומלצות:
עורכים שלא תומכים בתוכן עשיר לא מבצעים שיחה
setContentMimeTypes()
, והם משאירים את קבוצתEditorInfo.contentMimeTypes
שלהם אלnull
.העורכים מתעלמים מהתוכן אם סוג ה-MIME שצוין ב-
InputContentInfo
לא תואם לאף אחד מהסוגים שהוא מקבל.תוכן עשיר לא משפיע על מיקום הטקסט ולא מושפע ממנו הסמן. עורכים יכולים להתעלם ממיקום הסמן כשהם עובדים עם תוכן.
בתוך
OnCommitContentListener.onCommitContent()
, אפשר להחזירtrue
באופן אסינכרוני, אפילו לפני טעינת התוכן.בשונה מטקסט, שניתן לערוך ב-IME לפני שמחויבים, עשיר התוכן מחויב באופן מיידי. אם רוצים לאפשר למשתמשים לערוך או למחוק להטמיע את הלוגיקה בעצמכם.
כדי לבדוק את האפליקציה, צריך לוודא שלמכשיר או לאמולטור יש מקלדת שיכולה לשלוח תוכן עשיר. אפשר להשתמש במקלדת Google במערכת Android מגרסה 7.1 ואילך.
הוספת תמיכה בתמונות ל-IME
רכיבי IME שרוצים לשלוח תוכן עשיר לאפליקציות חייבים להטמיע את תוכן ההתחייבות 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
לקבלת מידע על
של ספקי תוכן, ראו
ספק וקובץ
הספק.
אם אתם מפתחים ספק תוכן משלכם, מומלץ לא לייצא אותו
על ידי הגדרה
android:exported
עד
false
במקום זאת, אפשר להפעיל את הענקת ההרשאות בספק באמצעות הגדרה
android:grantUriPermission
אל true
. לאחר מכן, ה-IME יכול להעניק הרשאות גישה ל-URI של התוכן כאשר
שבו התוכן מחויב. ניתן לעשות זאת בשתי דרכים:
ב-Android 7.1 (רמת API 25) ואילך, כשמבצעים קריאה ל-
commitContent()
, מגדירים את הפרמטר של הדגלINPUT_CONTENT_GRANT_READ_URI_PERMISSION
. לאחר מכן, האובייקטInputContentInfo
שהאפליקציה מקבלת יכול לבקש מתן הרשאות קריאה זמניות באמצעות התקשרותrequestPermission()
וגםreleasePermission()
.ב-Android 7.0 (רמת API 24) ומטה, המערכת מתעלמת מ-
INPUT_CONTENT_GRANT_READ_URI_PERMISSION
, לכן הענקת גישה באופן ידני הרשאה לתוכן. דרך אחת לעשות זאת היאgrantUriPermission()
, אבל אתם יכולים להטמיע מנגנון משלכם שעומד בדרישות שלך.
כדי לבדוק את ה-IME, ודאו שלמכשיר או לאמולטור יש אפליקציה שיכולה לקבל תוכן עשיר. ניתן להשתמש באפליקציית Google Messenger במערכת Android 7.1 ומעלה.