Así como una app puede enviar datos a otras apps, también puede recibirlos de otras apps. Piensa en cómo los usuarios interactúan con tu aplicación y qué tipos de datos quieres recibir de otras aplicaciones. Por ejemplo, una aplicación de redes sociales podría estar interesada en recibir contenido de texto, como una URL web interesante, de otra app.
En una app que usa Compose Navigation, recibir datos enviados por otra app es un proceso de tres pasos:
Declara un
<intent-filter>en el manifiesto: Debes agregar un filtro de intents a tu actividad en el archivoAndroidManifest.xml. Esto le indica al SO Android que tu aplicación puede recibir acciones específicas (comoACTION_SEND) y tipos de MIME (comotext/plain).Define un
navDeepLinken tu gráfico de Compose Navigation: Conecta unnavDeepLinkque coincida con la acción y el tipo de MIME directamente al destino componible que debería mostrar el contenido. ElNavControllerintercepta automáticamente el intent entrante y dirige al usuario directamente a esa pantalla.Extrae la carga útil de datos entrantes: En la pantalla de destino, accede a los extras del intent (como
EXTRA_TEXToEXTRA_STREAM) para recuperar el contenido compartido y actualizar el estado de la IU.
Los objetivos de uso compartido directo son vínculos directos a una actividad específica dentro de tu app. A menudo, representan a una persona o un grupo, y el Android Sharesheet los muestra. Por ejemplo, una app de mensajería puede proporcionar un objetivo de uso compartido directo para una persona que se vincula directamente a una conversación con esa persona. Consulta Proporciona objetivos de uso compartido directo para obtener instrucciones detalladas.
Tipos de MIME compatibles
Lo ideal es que una app pueda recibir la mayor cantidad posible de tipos de MIME.
Por ejemplo, una app de mensajería diseñada para enviar texto, imágenes y video idealmente admite la recepción de text/*, image/* y video/*. Estos son algunos tipos de MIME comunes para enviar y recibir datos en Android.
| Los receptores se registran para | Los emisores envían |
|---|---|
text/* |
|
image/* |
|
video/* |
|
| Extensiones de archivo compatibles | application/pdf |
Consulta el registro oficial de IANA de tipos de medios MIME.
Crea objetivos de uso compartido excelentes
Cuando los usuarios presionen un objetivo de uso compartido asociado con una actividad específica, permíteles confirmar y editar el contenido compartido antes de que tu app lo use. Esto es especialmente importante para los datos de texto.
Cómo recibir datos en tu app
Recibir datos compartidos en una app con Compose implica declarar filtros de intents en tu manifiesto, enrutar los intents entrantes a la pantalla adecuada con vínculos directos y extraer la carga útil del intent para actualizar tu IU.
Actualiza tu manifiesto
Los filtros de intents informan al sistema qué intents acepta un componente de la app. De manera similar
a cómo creaste un intent con una acción ACTION_SEND en la lección Envío
de datos a otras apps, creas filtros de intents para recibir
intents con esta acción. Defines un filtro de intents en tu manifiesto con el
<intent-filter> elemento. Por ejemplo, si tu app controla la recepción de contenido de texto, un manifiesto que incluya una o más imágenes de cualquier tipo se vería como el siguiente fragmento:
<activity android:name=".ui.MyActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
</activity>
Cuando otra app intenta compartir cualquiera de estos elementos mediante la creación de un intent
y su paso a startActivity(), tu aplicación aparece
como una opción en Android Sharesheet o el selector de intents. Si el usuario selecciona tu app, se inicia la actividad correspondiente (.ui.MyActivity en el ejemplo anterior). Luego, depende de ti controlar el contenido de manera adecuada dentro de tu código y la IU.
Define un vínculo directo en tu gráfico de navegación
En Compose Navigation, conecta un navDeepLink directamente al destino componible que debería mostrar el contenido. Cuando otra app comparte datos que coinciden con tu filtro de intents, Compose Navigation dirige al usuario directamente a este destino:
composable( route = "incoming_share", deepLinks = listOf( navDeepLink { action = Intent.ACTION_SEND mimeType = "text/plain" }, navDeepLink { action = Intent.ACTION_SEND mimeType = "image/*" }, navDeepLink { action = Intent.ACTION_SEND_MULTIPLE mimeType = "image/*" } ) ) { SharesheetHandler() }
El navDeepLink coincide con la acción y el tipo de MIME del intent entrante para navegar a la pantalla de destino correcta. Una vez en ese destino, tu controlador inspecciona el intent para determinar qué carga útil se recibió (como una sola imagen en comparación con varias imágenes) y extrae los extras correspondientes.
Cómo administrar el contenido entrante
Para recuperar el contenido entregado por un Intent, lee la actividad actual de LocalActivity.current dentro de tu elemento componible, luego examina el intent para determinar qué hacer a continuación. Si esta actividad se puede iniciar desde otras partes del sistema (como el selector), ten esto en cuenta cuando examines el intent.
Ten mucho cuidado al verificar los datos entrantes: es posible que se establezca el tipo de MIME incorrecto o que una imagen que se envíe sea extremadamente grande. Procesa datos binarios o operaciones de E/S pesadas (como decodificar imágenes grandes o escribir archivos) de forma asíncrona con corrutinas (como Dispatchers.IO) en lugar de hacerlo en el subproceso de IU principal.
@Composable fun SharesheetHandler() { val activity = LocalActivity.current val intent = activity?.intent when (intent?.action) { Intent.ACTION_SEND -> { if (intent.type == "text/plain") { handleSendText(intent) // Handle text being sent } else if (intent.type?.startsWith("image/") == true) { handleSendImage(intent) // Handle single image being sent } } Intent.ACTION_SEND_MULTIPLE -> { if (intent.type?.startsWith("image/") == true) { handleSendMultipleImages(intent) // Handle multiple images being sent } } else -> { // Handle other intents, such as being started from the home screen } } } private fun handleSendText(intent: Intent) { intent.getStringExtra(Intent.EXTRA_TEXT)?.let { // Update UI state with the shared text } } private fun handleSendImage(intent: Intent) { val imageUri = IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java) imageUri?.let { // Update UI state with the shared image } } private fun handleSendMultipleImages(intent: Intent) { val imageUris = IntentCompat.getParcelableArrayListExtra(intent, Intent.EXTRA_STREAM, Uri::class.java) imageUris?.let { // Update UI state with the shared images } }
Cuando extraigas datos binarios o URIs de extras de intents (como EXTRA_STREAM),
usa IntentCompat.getParcelableExtra() o
IntentCompat.getParcelableArrayListExtra()
de la biblioteca AndroidX Core, como se muestra en las funciones handleSendImage y
handleSendMultipleImages anteriores. Android 13 (nivel de API 33) da de baja el método Intent.getParcelableExtra(String) sin parámetros en favor de los métodos con seguridad de tipos que toman el tipo de clase esperado.
Actualizar la IU después de recibir los datos puede ser tan sencillo como actualizar
el estado para propagar un TextFieldo tan complejo como aplicar un filtro
a una imagen. Depende de tu app lo que suceda a continuación.
Cómo compartir la URL de la captura de pantalla
Cuando tomes una captura de pantalla, puedes compartirla y cualquier URL asociada.
Esto proporciona una experiencia del usuario más enriquecida. Cuando recibas una URL, asegúrate de obtener el campo EXTRA_TEXT del intent, como se muestra en el siguiente ejemplo:
IntentCompat.getParcelableExtra(intent, Intent.EXTRA_STREAM, Uri::class.java).let { // Handle the EXTRA_TEXT as well val extraText = intent.getCharSequenceExtra(Intent.EXTRA_TEXT) // Update UI state with the shared image and the EXTRA_TEXT if available }
Cómo asegurarte de que los usuarios reconozcan tu app
Tu app está representada por su ícono y etiqueta en el Android Sharesheet y el selector de intents. Ambos se definen en el manifiesto. Puedes establecer etiquetas de actividad o de filtro de intents para proporcionar más contexto.
A partir de Android 10 (nivel de API 29), Android Sharesheet solo usa los íconos establecidos en el manifiesto en tu etiqueta application. Android ignora los íconos establecidos en las etiquetas intent-filter y activity.
Cómo recibir contenido enriquecido
Si bien los intents ACTION_SEND permiten recibir datos del Android Sharesheet y el selector de intents en el nivel de actividad o navegación, las apps también pueden recibir contenido enriquecido (como imágenes, videos, archivos de audio y texto con estilo) a través de interacciones directas de la IU. Estos mecanismos incluyen lo siguiente:
- Pegar desde el portapapeles (mantener presionado el menú)
- Insertar contenido multimedia directamente desde el teclado en pantalla (IME), como calcomanías o GIFs
- Arrastrar y soltar contenido desde otra app en modo multiventana o de pantalla dividida
En las IUs basadas en vistas, Android 12 (nivel de API 31) y AndroidX Core 1.7 presentan la
API unificada OnReceiveContentListener. Este objeto de escucha consolida el control de contenido desde el portapapeles, el teclado y la función de arrastrar y soltar en una sola devolución de llamada. Para obtener instrucciones detalladas sobre cómo implementar
esto en las vistas, consulta Cómo recibir contenido enriquecido.
En Jetpack Compose, puedes controlar la recepción de contenido enriquecido insertado en componentes de la IU (como campos de texto) con el
Modifier.contentReceiver modificador o los
modificadores de arrastrar y soltar.