Android usa intents y sus servicios adicionales asociados para permitir que los usuarios compartan información de manera rápida y fácil con sus apps favoritas.
Los usuarios pueden compartir contenido en Android de dos formas:
- Android Sharesheet se diseñó principalmente para enviar contenido fuera de tu app o directamente a otro usuario. (por ejemplo, para compartir una URL con un amigo)
- El agente de resolución de intent de Android es más adecuado para pasar datos a la siguiente etapa de una tarea bien definida. Por ejemplo, abrir un PDF desde tu app y permitir que los usuarios elijan el visor que prefieran.
Cuando construyes un intent, debes especificar la acción que deseas que realice.
Android usa la acción ACTION_SEND
para enviar datos de una actividad a otra, incluso entre límites del proceso. Debes especificar
los datos y su tipo. El sistema identifica automáticamente las actividades compatibles que pueden recibir los datos y las muestra al usuario. En el caso del agente de resolución de intents, si solo una actividad puede controlar el intent, esa actividad se inicia de inmediato.
Por qué usar Android Sharesheet
Te recomendamos que uses Android Sharesheet para mantener la coherencia de tus usuarios en todas las apps. No muestres la lista de objetivos de uso compartido de tu app ni crees tus propias variaciones de Sharesheet.
Android Sharesheet permite a los usuarios compartir información con la persona adecuada mediante sugerencias de apps relevantes, todo con un solo toque. Sharesheet puede sugerir objetivos no disponibles para soluciones personalizadas y usa una clasificación coherente. Esto se debe a que Sharesheet puede tener en cuenta información sobre la actividad de la app y del usuario que solo está disponible para el sistema.
Android Sharesheet también tiene diversas funciones útiles para desarrolladores. Por ejemplo, puedes hacer lo siguiente:
- Conocer cuándo los usuarios implementan el uso compartido y dónde
- Agrega un
ChooserTarget
personalizado y destinos de la app - Proporcionar vistas previas de contenido de texto enriquecido a partir de Android 10 (nivel de API 29)
- Cómo excluir destinos que coinciden con nombres de componentes específicos
Cómo usar Android Sharesheet
Para todos los tipos de uso compartido, crea un intent y configura su acción en Intent.ACTION_SEND
.
Para mostrar Android Sharesheet, llama a Intent.createChooser()
y pásale tu objeto Intent
.
Se mostrará una versión del intent en la que siempre se indicará Android Sharesheet.
Envía contenido de texto
El uso más sencillo y común de Android Sharesheet es enviar contenido de texto de una actividad a otra. Por ejemplo, la mayoría de los navegadores pueden compartir la URL de la página que se muestra actualmente como texto con otra app. Esto es útil para compartir un artículo o sitio web con amigos por correo electrónico o redes sociales. Este es un ejemplo de cómo hacerlo:
Kotlin
val sendIntent: Intent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_TEXT, "This is my text to send.") type = "text/plain" } val shareIntent = Intent.createChooser(sendIntent, null) startActivity(shareIntent)
Java
Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send."); sendIntent.setType("text/plain"); Intent shareIntent = Intent.createChooser(sendIntent, null); startActivity(shareIntent);
De manera opcional, puedes agregar servicios adicionales para incluir más información, como destinatarios de correo electrónico (EXTRA_EMAIL
, EXTRA_CC
, EXTRA_BCC
), el asunto del correo electrónico (EXTRA_SUBJECT
), etcétera.
Nota: Algunas apps de correo electrónico, como Gmail, esperan una String[]
para extras como EXTRA_EMAIL
y EXTRA_CC
. Usa putExtra(String, String[])
para agregarlos a tu intent.
Enviar contenido binario
Comparte los datos binarios con la acción ACTION_SEND
.
Configura el tipo de MIME adecuado y coloca un URI en los datos del EXTRA_STREAM
adicional, como se muestra en el siguiente ejemplo.
Por lo general, se usa para compartir una imagen, pero se puede usar para compartir cualquier tipo de contenido binario.
Kotlin
val shareIntent: Intent = Intent().apply { action = Intent.ACTION_SEND // Example: content://com.google.android.apps.photos.contentprovider/... putExtra(Intent.EXTRA_STREAM, uriToImage) type = "image/jpeg" } startActivity(Intent.createChooser(shareIntent, null))
Java
Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); // Example: content://com.google.android.apps.photos.contentprovider/... shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage); shareIntent.setType("image/jpeg"); startActivity(Intent.createChooser(shareIntent, null));
La aplicación receptora necesita permiso para acceder a los datos a los que apunta Uri
. Hay dos maneras recomendadas de hacerlo:
- Almacena los datos en tu
ContentProvider
y asegúrate de que otras apps tengan el permiso correcto para acceder a tu proveedor. El mecanismo preferido para proporcionar acceso es usar permisos por URI, que son temporales y solo otorgan acceso a la aplicación receptora. Una manera fácil de crear unContentProvider
como este es usar la clase auxiliarFileProvider
. - Usa la clase
MediaStore
del sistema.MediaStore
es principalmente para tipos de MIME de imagen, video y audio. Sin embargo, a partir de Android 3.0 (nivel de API 11), también puede almacenar tipos que no sean multimedia. Para obtener más información, consultaMediaStore.Files
. Los archivos se pueden insertar enMediaStore
conscanFile()
, después de lo cual se pasa unUri
de estilocontent://
adecuado para compartir a la devolución de llamadaonScanCompleted()
proporcionada. Ten en cuenta que, una vez que se agrega alMediaStore
del sistema, cualquier app del dispositivo puede acceder al contenido.
Usa el tipo de MIME correcto
Proporciona el tipo de MIME más específico disponible para los datos que envías. Por ejemplo, usa text/plain
cuando compartas texto sin formato. Estos son algunos tipos de MIME comunes cuando se envían datos simples en Android:
Los receptores se registran para | Los remitentes envían |
---|---|
text/* |
|
`image/*` |
|
video/* |
|
Extensiones de archivo compatibles | application/pdf |
Para obtener más información sobre los tipos de MIME, consulta el registro oficial de IANA de los tipos de medios MIME.
Android Sharesheet podría mostrar una vista previa de contenido, según el tipo de MIME proporcionado. Algunas funciones de versión preliminar solo están disponibles para tipos específicos.
Compartir varios tipos de contenido
Para compartir varios elementos de contenido, usa la acción ACTION_SEND_MULTIPLE
junto con una lista de URI que apunta al contenido. El tipo de MIME varía según la combinación de contenido que compartes. Por ejemplo, si compartes tres imágenes JPEG, usarás el tipo "image/jpg"
. En el caso de una combinación de tipos de imágenes, usa "image/*"
para hacer coincidir una actividad que controle cualquier tipo de imagen. Si bien es posible compartir una combinación de tipos, no recomendamos hacerlo, ya que el receptor no tiene claro qué se va a enviar. Si es necesario enviar varios tipos, usa "*/*"
. Depende de la aplicación receptora analizar
y procesar tus datos. Por ejemplo:
Kotlin
val imageUris: ArrayList<Uri> = arrayListOf( // Add your image URIs here imageUri1, imageUri2 ) val shareIntent = Intent().apply { action = Intent.ACTION_SEND_MULTIPLE putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris) type = "image/*" } startActivity(Intent.createChooser(shareIntent, null))
Java
ArrayList<Uri> imageUris = new ArrayList<Uri>(); imageUris.add(imageUri1); // Add your image URIs here imageUris.add(imageUri2); Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND_MULTIPLE); shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, imageUris); shareIntent.setType("image/*"); startActivity(Intent.createChooser(shareIntent, null));
Asegúrate de que los objetos Uri
proporcionados apunten a datos a los que pueda acceder una aplicación receptora.
Cómo agregar contenido enriquecido a las vistas previas de texto
A partir de Android 10 (nivel de API 29), Android Sharesheet muestra una vista previa del texto que se comparte. En algunos casos, el texto que se comparte puede ser difícil de comprender. Considera compartir una URL complicada, como https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4
. Una vista previa más completa puede asegurarles a los usuarios lo que se comparte.
Mientras se muestra una vista previa del texto, puedes definir un título, una imagen en miniatura o ambas. Agrega una descripción a Intent.EXTRA_TITLE
antes de llamar a Intent.createChooser()
y agrega una miniatura relevante con ClipData
.
Nota: El URI de contenido de la imagen se proporciona desde un FileProvider
, por lo general, de un <cache-path>
configurado.
Para obtener más información, consulta Cómo compartir archivos. Asegúrate de otorgar a Sharesheet los permisos adecuados para leer cualquier imagen que quieras usar como miniatura. Para obtener más información, consulta Intent.FLAG_GRANT_READ_URI_PERMISSION
.
Por ejemplo:
Kotlin
val share = Intent.createChooser(Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/") // (Optional) Here you're setting the title of the content putExtra(Intent.EXTRA_TITLE, "Introducing content previews") // (Optional) Here you're passing a content URI to an image to be displayed data = contentUri flags = Intent.FLAG_GRANT_READ_URI_PERMISSION }, null) startActivity(share)
Java
Intent sendIntent = new Intent(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, "https://developer.android.com/training/sharing/"); // (Optional) Here you're setting the title of the content sendIntent.putExtra(Intent.EXTRA_TITLE, "Introducing content previews"); // (Optional) Here you're passing a content URI to an image to be displayed sendIntent.setData(contentUri); sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // Show the Sharesheet startActivity(Intent.createChooser(sendIntent, null));
La vista previa debería ser similar a la siguiente:
Cómo agregar acciones personalizadas a la hoja compartida
En Android 14 (nivel de API 34) y versiones posteriores, las apps pueden agregar acciones personalizadas a Android Sharesheet.
Las acciones personalizadas se muestran como íconos de acción pequeños en la parte superior de Android Sharesheet, y las apps pueden especificar cualquier Intent
como la acción que se invoca cuando se hace clic en el ícono.
Para agregar acciones personalizadas en Android Sharesheet, primero crea un ChooserAction
con ChooserAction.Builder
.
Puedes especificar un PendingIntent
como la acción invocada cuando se hace clic en el ícono. Crea un array que contenga todas tus acciones personalizadas y especifícalo como EXTRA_CHOOSER_CUSTOM_ACTIONS
del recurso compartido Intent
.
Kotlin
val sendIntent = Intent(Intent.ACTION_SEND) .setType("text/plain") .putExtra(Intent.EXTRA_TEXT, text) val shareIntent = Intent.createChooser(sendIntent, null) val customActions = arrayOf( ChooserAction.Builder( Icon.createWithResource(context, R.drawable.ic_custom_action), "Custom", PendingIntent.getBroadcast( context, 1, Intent(Intent.ACTION_VIEW), PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT ) ).build() ) shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions) context.startActivity(shareIntent)
Java
Intent sendIntent = new Intent(Intent.ACTION_SEND) .setType("text.plain") .putExtra(Intent.EXTRA_TEXT, text); Intent shareIntent = Intent.createChooser(sendIntent, null); ChooserAction[] actions = new ChooserAction[]{ new ChooserAction.Builder( Icon.createWithResource(context, R.drawable.ic_custom_action), "Custom", PendingIntent.getBroadcast( context, 1, new Intent(Intent.ACTION_VIEW), PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT ) ).build() }; shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions); context.startActivity(shareIntent);
Agregar orientaciones personalizadas
Android Sharesheet te permite especificar hasta dos objetos ChooserTarget
que se muestran antes de los destinos de uso compartido y del selector que se cargan desde ChooserTargetServices
. También puedes especificar hasta dos intents que apunten a actividades que se enumeran antes de las sugerencias de la app:
Agrega Intent.EXTRA_CHOOSER_TARGETS
y Intent.EXTRA_INITIAL_INTENTS
a tu intent de uso compartido después de llamar a Intent.createChooser()
:
Kotlin
val share = Intent.createChooser(myShareIntent, null).apply { putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray) putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray) }
Java
Intent shareIntent = Intent.createChooser(sendIntent, null); share.putExtra(Intent.EXTRA_CHOOSER_TARGETS, myChooserTargetArray); share.putExtra(Intent.EXTRA_INITIAL_INTENTS, myInitialIntentArray);
Usa esta función con cuidado. Cada Intent
y ChooserTarget
personalizados que agregas reduce la cantidad que sugiere el sistema. Por lo general, no recomendamos agregar segmentaciones personalizadas. Una forma apropiada de agregar Intent.EXTRA_INITIAL_INTENTS
es proporcionar acciones adicionales que los usuarios puedan realizar en el contenido compartido. Por ejemplo, un usuario comparte imágenes y se usa Intent.EXTRA_INITIAL_INTENTS
para permitirle enviar un vínculo. Una forma apropiada de agregar Intent.EXTRA_CHOOSER_TARGETS
es indicar personas o dispositivos relevantes que proporciona tu app.
Cómo excluir destinos específicos por componente
Para excluir segmentaciones específicas, proporciona Intent.EXTRA_EXCLUDE_COMPONENTS
.
Haz esto solo para quitar las orientaciones que controlas. Un caso de uso común es ocultar los objetivos de uso compartido de la app cuando los usuarios comparten contenido desde la app, ya que es probable que su intención lo comparta fuera de la app.
Agrega Intent.EXTRA_EXCLUDE_COMPONENTS
a tu intent después de llamar a Intent.createChooser()
:
Kotlin
val share = Intent.createChooser(Intent(), null).apply { // Only use for components you have control over val excludedComponentNames = arrayOf(ComponentName("com.example.android", "ExampleClass")) putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames) }
Java
Intent shareIntent = Intent.createChooser(new Intent(), null); // Only use for components you have control over ComponentName[] excludedComponentNames = { new ComponentName("com.example.android", "ExampleClass") }; shareIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludedComponentNames);
Obtén información sobre el uso compartido
Puede ser útil saber cuándo los usuarios comparten y qué objetivo seleccionan. Android Sharesheet te permite obtener esta información proporcionando el ComponentName
de los destinos que tus usuarios seleccionan con una IntentSender
.
Primero, crea un PendingIntent
para un BroadcastReceiver
y proporciona su IntentSender
en Intent.createChooser()
:
Kotlin
var share = Intent(Intent.ACTION_SEND) // ... val pi = PendingIntent.getBroadcast( myContext, requestCode, Intent(myContext, MyBroadcastReceiver::class.java), PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) share = Intent.createChooser(share, null, pi.intentSender)
Java
Intent share = new Intent(ACTION_SEND); ... PendingIntent pi = PendingIntent.getBroadcast(myContext, requestCode, new Intent(myContext, MyBroadcastReceiver.class), PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); share = Intent.createChooser(share, null, pi.getIntentSender());
Recibe la devolución de llamada en MyBroadcastReceiver
y busca en Intent.EXTRA_CHOSEN_COMPONENT
:
Kotlin
override fun onReceive(context: Context, intent: Intent) { ... val clickedComponent : ComponentName = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT); }
Java
@Override public void onReceive(Context context, Intent intent) { ... ComponentName clickedComponent = intent.getParcelableExtra(EXTRA_CHOSEN_COMPONENT); }
Cómo agregar acciones personalizadas a la hoja compartida
En Android 14 (nivel de API 34) y versiones posteriores, las apps pueden agregar acciones personalizadas a Android Sharesheet.
Crea un ChooserAction
con ChooserAction.Builder
.
Puedes especificar un PendingIntent
como la acción invocada cuando se hace clic en el ícono. Crea un array que contenga todas tus acciones personalizadas y especifícalo como EXTRA_CHOOSER_CUSTOM_ACTIONS
del recurso compartido Intent
.
Kotlin
val sendIntent = Intent(Intent.ACTION_SEND) .setType("text/plain") .putExtra(Intent.EXTRA_TEXT, text) val shareIntent = Intent.createChooser(sendIntent, null) val customActions = arrayOf( ChooserAction.Builder( Icon.createWithResource(context, R.drawable.ic_custom_action), "Custom", PendingIntent.getBroadcast( context, 1, Intent(Intent.ACTION_VIEW), PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_CANCEL_CURRENT ) ).build() ) shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, customActions) context.startActivity(shareIntent)
Java
Intent sendIntent = new Intent(Intent.ACTION_SEND) .setType("text.plain") .putExtra(Intent.EXTRA_TEXT, text); Intent shareIntent = Intent.createChooser(sendIntent, null); ChooserAction[] actions = new ChooserAction[]{ new ChooserAction.Builder( Icon.createWithResource(context, R.drawable.ic_custom_action), "Custom", PendingIntent.getBroadcast( context, 1, new Intent(Intent.ACTION_VIEW), PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_CANCEL_CURRENT ) ).build() }; shareIntent.putExtra(Intent.EXTRA_CHOOSER_CUSTOM_ACTIONS, actions); context.startActivity(shareIntent);
Cómo usar el agente de resolución de intent de Android
El agente de resolución de intent de Android se usa mejor cuando se envían datos a otra app como parte de un flujo de tareas bien definido.
Para usar el agente de resolución de intent de Android, crea un intent y agrega extras como lo harías con el nombre de Android Sharesheet. Sin embargo, no llames a Intent.createChooser()
.
Si hay varias aplicaciones instaladas con filtros que coinciden con ACTION_SEND
y el tipo de MIME, el sistema mostrará un diálogo de desambiguación llamado agente de resolución de intents que le permite al usuario elegir un destino para compartir el contenido. Si una sola aplicación coincide, se ejecuta.
A continuación, se muestra un ejemplo de cómo usar el agente de resolución de intent de Android para enviar texto:
Kotlin
val sendIntent: Intent = Intent().apply { action = Intent.ACTION_SEND putExtra(Intent.EXTRA_TEXT, "This is my text to send.") type = "text/plain" } startActivity(sendIntent)
Java
Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send."); sendIntent.setType("text/plain"); startActivity(sendIntent);
Más información
Para obtener más información sobre el envío de datos, consulta Intents y filtros de intents.