A los usuarios les encantan las imágenes, los videos y otros contenidos expresivos, pero insertar y mover este contenido en apps no siempre es fácil. Para que las apps puedan reciben contenido enriquecido, Android 12 (nivel de API 31) introduce una API unificada que permite que tu app acepte contenido de cualquier fuente: portapapeles, teclado o arrastre.
Puedes adjuntar una interfaz, como
OnReceiveContentListener
:
a los componentes de IU y obtener una devolución de llamada cuando se inserta contenido a través de cualquiera
de atención. La devolución de llamada se convierte en el único lugar para que tu código controle la recepción de todo el contenido, desde texto sin formato y estilo hasta lenguaje de marcado, imágenes, videos, archivos de audio y otros elementos.
Para ofrecer retrocompatibilidad con versiones anteriores de Android, esta API también es disponibles en AndroidX, a partir de Core 1.7 y Appcompat 1.4, que recomendamos usar cuando implementes esta funcionalidad.
Descripción general
Con otras APIs existentes, cada mecanismo de IU, como la función táctil y menú de espera o arrastre) tiene su propia API correspondiente. Eso significa que debes realizar la integración con cada API por separado, lo que agrega código similar para cada mecanismo que inserte contenido:
La API de OnReceiveContentListener
consolida estas rutas de código diferentes creando una sola API para que puedas enfocarte en la lógica específica de tu app y permitir que la plataforma controle el resto:
Este enfoque también significa que cuando se agregan nuevas formas de insertar contenido la plataforma, no es necesario que realices cambios adicionales en el código para habilitar la en tu app. Si tu app necesita implementar una personalización completa para una caso de uso particular, puedes seguir usando las APIs existentes, que siguen funcionando de la misma manera.
Implementación
La API es una interfaz de objeto de escucha con un único método, OnReceiveContentListener
.
Para admitir versiones anteriores de la plataforma de Android, recomendamos el uso de la interfaz OnReceiveContentListener
coincidente en la biblioteca de AndroidX Core.
Para usar la API, implementa el objeto de escucha especificando los tipos de contenido que puede controlar lo siguiente:
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/*"}; // ... }
Después de especificar todos los tipos de MIME de contenido que admite tu app, implementa el resto del objeto de escucha:
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<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 tu app ya admite el uso compartido con intents, puedes reutilizar los lógica específica de la app para controlar los URI de contenido Muestra los datos restantes para delegar su control a la plataforma.
Después de implementar el objeto de escucha, configúralo en los elementos de la IU adecuados de tu app:
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()); } }
Permisos de URI
La plataforma otorga y actualiza automáticamente los permisos de lectura para cualquier
URI de contenido en la
la carga útil pasada a OnReceiveContentListener
.
Normalmente, tu app procesa URI de contenido en un servicio o una actividad. Para
de larga duración, usar
WorkManager. Cuando implementas
esto, extiende los permisos al servicio o la actividad objetivo pasando el
contenido con
Intent.setClipData
y establece la marca
FLAG_GRANT_READ_URI_PERMISSION
.
De manera alternativa, puedes usar un subproceso en segundo plano dentro del contexto actual para procesar el contenido. En este caso, debes mantener una referencia al
payload
que recibe el objeto de escucha para garantizar que los permisos no se
que la plataforma revocó de forma prematura.
Vistas personalizadas
Si tu app usa una subclase View
personalizada, asegúrate de que la
No se puede omitir OnReceiveContentListener
.
Si tu clase View
anula el método onCreateInputConnection
, usa la API de Jetpack InputConnectionCompat.createWrapper
para configurar InputConnection
.
Si tu clase View
anula la
onTextContextMenuItem
y delega a super cuando el elemento de menú
R.id.paste
o
R.id.pasteAsPlainText
Comparación con la API de imagen de teclado
Puedes considerar la API de OnReceiveContentListener
como la próxima versión de la API de imagen de teclado existente. Esta API unificada admite la funcionalidad de la API de imagen de teclado y algunas funciones adicionales. La compatibilidad con los dispositivos y las funciones varía según si usas la biblioteca de Jetpack o las API nativas desde el SDK de Android.
Acción o función | Compatible con la API de imágenes de teclado | Compatible con la API unificada |
---|---|---|
Insertar desde el teclado | Sí (nivel de API 13 y versiones posteriores) | Sí (nivel de API 13 y versiones posteriores) |
Insertar usando la acción de pegar menú de espera | No | Sí |
Insertar con la función de arrastrar y soltar | No | Sí (nivel de API 24 y versiones posteriores) |
Acción o función | Compatible con la API de imágenes de teclado | Compatible con la API unificada |
---|---|---|
Insertar desde el teclado | Sí (nivel de API 25 y versiones posteriores) | Sí (Android 12 y versiones posteriores) |
Insertar usando la acción de pegar menú de espera | No | |
Insertar con la función de arrastrar y soltar | No |