Les utilisateurs veulent souvent communiquer à l'aide d'emoji, d'autocollants et d'autres types d'outils enrichissants contenus. Dans les versions précédentes d'Android, les claviers virtuels, également appelés claviers virtuels, Éditeurs de mode de saisie IME : seuls les emoji Unicode peuvent être envoyés aux applications. Pour un contenu enrichi, les applications API spécifiques à l'application qui ne pouvaient pas être utilisées dans d'autres applications ou qui utilisaient des solutions telles que L'envoi d'images par le biais d'une simple action de partage ou le presse-papiers.
À partir d'Android 7.1 (niveau d'API 25), le SDK Android inclut le commit Content API, qui permet aux IME d'envoyer des images et d'autres du contenu enrichi directement dans un éditeur de texte dans une application. L'API est également disponible dans la bibliothèque Support v13 à partir de la révision 25.0.0. Nous vous recommandons d'utiliser le , car elle contient des méthodes d'assistance qui simplifient l'implémentation.
Cette API vous permet de créer des applications de chat qui acceptent le contenu enrichi provenant de et les claviers qui peuvent envoyer du contenu enrichi à n'importe quelle application. L'application Google Clavier et des applications telles que Messages de Google est compatible avec Commit Content API dans Android 7.1, comme illustré dans la figure 1.
Ce document explique comment implémenter Commit Content API dans les IME et applications.
Fonctionnement
L'insertion d'images de clavier nécessite la participation de l'IME et de l'application. La La séquence suivante décrit chaque étape du processus d'insertion d'images:
Lorsque l'utilisateur appuie sur un
EditText
, l'éditeur envoie la liste des types de contenu MIME qu'il accepte dansEditorInfo.contentMimeTypes
L'IME lit la liste des types pris en charge et affiche le contenu dans le logiciel que l'éditeur peut accepter.
Lorsque l'utilisateur sélectionne une image, l'IME appelle
commitContent()
et envoie uneInputContentInfo
à l'éditeur. L'appelcommitContent()
est analogue à l'appel l'appelcommitText()
, mais pour le contenu enrichi.InputContentInfo
contient un URI qui identifie le contenu dans un contenu fournisseur.
Ce processus est illustré dans la figure 2:
Ajouter la prise en charge des images dans les applications
Pour accepter le contenu enrichi des IME, une application doit indiquer aux éditeurs de quel type de contenu il s'agit
accepte et spécifie une méthode de rappel qui est exécutée lors de la réception de contenu.
L'exemple suivant montre comment créer un élément EditText
qui accepte le format PNG.
images:
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; } };
Voici une explication supplémentaire:
Cet exemple utilise la bibliothèque Support. Il existe donc des références à
android.support.v13.view.inputmethod
au lieu deandroid.view.inputmethod
Cet exemple crée un
EditText
et remplace sesonCreateInputConnection(EditorInfo)
pour modifier leInputConnection
InputConnection
est le canal de communication entre un IME et le application qui reçoit son entrée.L'appel
super.onCreateInputConnection()
préserve le comportement intégré (envoi et réception de texte) vous fait référence àInputConnection
.setContentMimeTypes()
ajoute une liste des types MIME pris en charge auEditorInfo
Appelersuper.onCreateInputConnection()
avant lesetContentMimeTypes()
.callback
s'exécute chaque fois que l'IME valide du contenu. La méthodeonCommitContent()
fait référence àInputContentInfoCompat
, qui contient un URI de contenu.- Demander et libérer des autorisations si votre application s'exécute au niveau d'API 25
ou supérieure, et la valeur
INPUT_CONTENT_GRANT_READ_URI_PERMISSION
est défini par l'IME. Sinon, vous avez déjà accès au contenu URI, car il est accordé par l'IME ou parce que le fournisseur de contenu ne limite pas l'accès. Pour en savoir plus, consultez Ajouter une prise en charge d'images aux IME :
- Demander et libérer des autorisations si votre application s'exécute au niveau d'API 25
ou supérieure, et la valeur
createWrapper()
encapsule leInputConnection
, leEditorInfo
modifié et le rappel dans un nouveauInputConnection
et le renvoie.
Voici les pratiques recommandées:
Les éditeurs qui n'acceptent pas le contenu enrichi n'appellent pas
setContentMimeTypes()
, et ils quittent leur ensembleEditorInfo.contentMimeTypes
ànull
.Les éditeurs ignorent le contenu si le type MIME spécifié dans
InputContentInfo
est spécifié. ne correspond à aucun des types acceptés.Le contenu enrichi n'a aucune incidence sur la position du texte et n'a aucune incidence sur sa position curseur. Les éditeurs peuvent ignorer la position du curseur lorsqu'ils travaillent sur du contenu.
Dans
OnCommitContentListener.onCommitContent()
, vous pouvez renvoyertrue
de manière asynchrone, même avant de charger le contenu.Contrairement au texte, qui peut être modifié dans l'IME avant d'être validé, s'applique immédiatement. Si vous souhaitez autoriser les utilisateurs à modifier ou supprimer implémentez la logique vous-même.
Pour tester votre application, assurez-vous que votre appareil ou votre émulateur dispose d'un clavier capable d'envoyer du contenu enrichi. Vous pouvez utiliser le clavier Google sur Android 7.1 ou version ultérieure.
Ajouter la prise en charge des images aux IME
Les IME qui souhaitent envoyer du contenu enrichi aux applications doivent implémenter le commit de contenu API, comme illustré dans l'exemple suivant:
- Remplacement
onStartInput()
ouonStartInputView()
et lire la liste des types de contenus compatibles à partir de la cible éditeur. L'extrait de code suivant montre comment vérifier si la cible éditeur accepte les images 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. } }
- Validez le contenu dans l'application lorsque l'utilisateur sélectionne une image. Éviter d'appeler
commitContent()
lorsqu'un texte est en cours de composition, car il peut faire perdre le focus à l'éditeur. L'extrait de code suivant montre comment pour valider une image 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); }
En tant qu'auteur IME, vous devrez probablement implémenter votre propre fournisseur de contenu pour
pour répondre aux requêtes d'URI de contenu. La seule exception est si votre IME prend en charge le contenu
de fournisseurs de contenu existants,
MediaStore
Pour plus d'informations sur
création de fournisseurs de contenu, consultez la section Contenu
fournisseur et file
du fournisseur.
Si vous créez votre propre fournisseur de contenu, nous vous recommandons de ne pas l'exporter
en définissant
android:exported
jusqu'à
false
Activez plutôt l'octroi d'autorisations chez le fournisseur en paramétrant
android:grantUriPermission
à true
. Ensuite, votre IME peut accorder des autorisations pour accéder à l'URI de contenu lorsque
le contenu est validé. Pour cela, vous pouvez procéder de deux façons :
Sur Android 7.1 (niveau d'API 25) ou version ultérieure, lorsque vous appelez
commitContent()
, définissez le paramètre d'indicateur surINPUT_CONTENT_GRANT_READ_URI_PERMISSION
Ensuite, l'objetInputContentInfo
que l'application reçoit peut demander et des autorisations de lecture temporaires en appelantrequestPermission()
etreleasePermission()
Sur Android 7.0 (niveau d'API 24) ou version antérieure,
INPUT_CONTENT_GRANT_READ_URI_PERMISSION
est ignoré. Par conséquent, accordez manuellement l'autorisation d'accès au contenu. Pour ce faire, vous pouvez utilisergrantUriPermission()
, mais vous pouvez implémenter votre propre mécanisme qui répond à vos propres exigences.
Pour tester votre IME, assurez-vous que votre appareil ou votre émulateur dispose d'une application pouvant recevoir du contenu enrichi. Vous pouvez utiliser l'application Google Messenger sur Android 7.1 ou version ultérieure.