Les utilisateurs adorent les images, les vidéos et les autres contenus expressifs, mais l'insertion et il n'est pas toujours facile de déplacer ce contenu dans les applications. Pour permettre aux applications de recevoir du contenu enrichi, Android 12 (niveau d'API 31) introduit une API unifiée qui permet à votre application d'accepter du contenu provenant de n'importe quelle source: presse-papiers, clavier ou déplacement.
Vous pouvez associer une interface, telle que OnReceiveContentListener
, aux composants d'interface utilisateur et obtenir un rappel lorsque du contenu est inséré via un mécanisme. Le rappel devient l'emplacement unique que votre code doit gérer
recevoir tous les contenus, du texte brut et stylisé au balisage, aux images, aux vidéos,
des fichiers audio, et autres.
Pour assurer la rétrocompatibilité avec les versions précédentes d'Android, cette API est également disponible sur AndroidX, à partir de Core 1.7 et Appcompat 1.4, que nous vous recommandons d'utiliser pour implémenter cette fonctionnalité.
Présentation
Avec les autres API existantes, chaque mécanisme d'UI (tel que le menu "Appuyer de manière prolongée" ou le glisser-déposer) dispose de son propre API correspondante. Cela signifie que vous devez s'intègrent à chaque API séparément, en ajoutant un code similaire pour chaque mécanisme qui insère du contenu:
L'API OnReceiveContentListener
regroupe ces différents chemins de code en
Créez une seule API à implémenter, ce qui vous permet de vous concentrer sur la logique spécifique à votre application.
et laissez la plate-forme gérer le reste:
Cette approche signifie également que lorsque de nouvelles méthodes d'insertion de contenu sont ajoutées à la plate-forme, vous n'avez pas besoin d'apporter de modifications de code supplémentaires pour activer la prise en charge dans votre application. Et si votre application doit implémenter une personnalisation complète pour un cas d'utilisation particulier, vous pouvez toujours utiliser les API existantes, qui continuent de fonctionner de la même manière.
Implémentation
L'API est une interface d'écouteur avec une méthode unique,
OnReceiveContentListener
Pour assurer la compatibilité avec les anciennes versions de la plate-forme Android, nous vous recommandons d'utiliser la
correspondant
OnReceiveContentListener
dans la bibliothèque AndroidX Core.
Pour utiliser l'API, implémentez l'écouteur en spécifiant les types de contenu que votre application peut gérer :
object MyReceiver : OnReceiveContentListener { val MIME_TYPES = arrayOf("image/*", "video/*") // ... override fun onReceiveContent(view: View, payload: ContentInfoCompat): ContentInfoCompat? { TODO("Not yet implemented") } }
public class MyReceiver implements OnReceiveContentListener { public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"}; // ... }
Après avoir spécifié tous les types MIME de contenu compatibles avec votre application, implémentez le reste de l'écouteur:
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/*") } }
public class MyReceiver implements OnReceiveContentListener { public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"}; @Override public ContentInfoCompat onReceiveContent(View view, ContentInfoCompat contentInfo) { Pair<ContentInfoCompat, ContentInfoCompat> 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; } }
Si votre application est déjà compatible avec le partage avec des intents, vous pouvez réutiliser votre logique spécifique à l'application pour gérer les URI de contenu. Renvoyez toutes les données restantes à de déléguer le traitement de ces données à la plate-forme.
Après avoir implémenté l'écouteur, définissez-le sur les éléments d'interface utilisateur appropriés dans votre application:
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()) } }
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()); } }
Autorisations d'URI
Les autorisations de lecture sont accordées et libérées automatiquement par la plate-forme pour tous les URI de contenu présents dans la charge utile transmise à OnReceiveContentListener
.
En règle générale, votre application traite les URI de contenu dans un service ou une activité. Pour
un traitement de longue durée,
WorkManager. Lorsque vous implémentez cette fonctionnalité, étendez les autorisations au service ou à l'activité cible en transmettant le contenu à l'aide de Intent.setClipData
et en définissant l'indicateur FLAG_GRANT_READ_URI_PERMISSION
.
Vous pouvez également utiliser un thread en arrière-plan dans le contexte actuel pour traiter le contenu. Dans ce cas, vous devez conserver une référence à l'objet payload
reçu par l'écouteur pour vous assurer que les autorisations ne sont pas révoquées prématurément par la plate-forme.
Vues personnalisées
Si votre application utilise une sous-classe View
personnalisée, assurez-vous que le
OnReceiveContentListener
n'est pas ignoré.
Si votre classe View
remplace la méthode onCreateInputConnection
, utilisez l'API Jetpack InputConnectionCompat.createWrapper
pour configurer InputConnection
.
Si votre classe View
remplace la classe
onTextContextMenuItem
, déléguez à super lorsque l'élément de menu est
R.id.paste
ou
R.id.pasteAsPlainText
.
Comparaison avec l'API d'image clavier
Vous pouvez considérer l'API OnReceiveContentListener
comme la prochaine version de
API d'image clavier existante. Cette approche unifiée
est compatible avec les fonctionnalités de l'API d'image clavier, ainsi qu'avec certaines
des fonctionnalités supplémentaires. La compatibilité des appareils et des fonctionnalités varie selon que vous utilisez la bibliothèque Jetpack ou les API natives du SDK Android.
Action ou fonctionnalité | Prise en charge par l'API d'image du clavier | Compatible avec l'API unifiée |
---|---|---|
Insérer depuis le clavier | Oui (niveau d'API 13 ou supérieur) | Oui (niveau d'API 13 ou supérieur) |
Insérer en utilisant le collage tactile et menu de mise en attente | Non | Oui |
Insérer par glisser-déposer | Non | Oui (niveau d'API 24 ou supérieur) |
Action ou fonctionnalité | Prise en charge par l'API d'image du clavier | Compatible avec l'API unifiée |
---|---|---|
Insérer depuis le clavier | Oui (niveau d'API 25 ou version ultérieure) | Oui (Android 12 ou version ultérieure) |
Insérer en utilisant le collage tactile et menu de mise en attente | Non | |
Insérer par glisser-déposer | Non |