Cómo enviar datos simples a otras apps

Android usa intents y su contenido adicional asociado para compartir información con sus apps favoritas de forma rápida y sencilla.

Los usuarios pueden compartir contenido en Android de dos formas:

  • Android Sharesheet, que se diseñó para enviar contenido fuera de la app o directamente a otro usuario (por ejemplo, para compartir una URL con un amigo)
  • El agente de resolución de intent de Android, ideal para pasar datos a la próxima etapa de una tarea bien definida (por ejemplo, abrir un PDF desde la app y permitir a los usuarios seleccionar el visor preferido)

Cuando construyes un intent, debes especificar la acción que quieres que lleve a cabo. Android usa la acción ACTION_SEND para enviar datos de una actividad a otra, incluso entre límites de procesos. Debes especificar los datos y su tipo. El sistema automáticamente identifica las actividades compatibles que pueden recibir los datos y las muestra al usuario. En el caso del agente de resolución de intent, si solo una actividad puede controlar el intent, esa actividad se inicia de inmediato.

Por qué debes usar Android Sharesheet

Recomendamos usar Android Sharesheet para mantener la coherencia de las apps entre tus usuarios. Las apps no deben mostrar su propia lista de destinos de uso compartido ni crear sus propias variaciones de Sharesheet.

Android Sharesheet brinda a los usuarios la capacidad de compartir información con la persona adecuada, mediante sugerencias relevantes de la app, con solo presionar la pantalla una vez. Sharesheet puede sugerir destinos no disponibles para soluciones personalizadas y con una clasificación coherente. Esto se debe a que Sharesheet puede tener en cuenta información sobre la app y la actividad 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:

Cómo usar Android Sharesheet

Para todos los tipos de uso compartido, crea un intent y configura la acción en Intent.ACTION_SEND. Para mostrar Android Sharesheet, debes llamar a Intent.createChooser() y pasarle el objeto Intent. Se mostrará una versión de tu intent que siempre estará disponible en Android Sharesheet.

Cómo enviar contenido de texto

El uso más simple y común de Android Sharesheet es el envío de contenido de texto desde una actividad a otra. Por ejemplo, en la mayoría de los navegadores, se puede compartir la URL de la página que se muestra como texto mediante otra app. Este recurso es útil para compartir un artículo o un 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 o 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 servicios adicionales, como EXTRA_EMAIL y EXTRA_CC. Usa putExtra(String, String[]) para agregarlos a tu intent.

Cómo enviar contenido binario

Comparte los datos binarios con la acción ACTION_SEND. Define el tipo de MIME adecuado y coloca una URI en los datos del EXTRA_STREAM adicional. En general, se usa para compartir una imagen, pero se puede utilizar para compartir cualquier tipo de contenido binario:

Kotlin

    val shareIntent: Intent = Intent().apply {
        action = Intent.ACTION_SEND
        putExtra(Intent.EXTRA_STREAM, uriToImage)
        type = "image/jpeg"
    }
    startActivity(Intent.createChooser(shareIntent, resources.getText(R.string.send_to)))
    

Java

    Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
    shareIntent.setType("image/jpeg");
    startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
    

La aplicación receptora necesita permiso para acceder a los datos a los que apunta la Uri. Estas son las maneras recomendadas de hacerlo:

  • Almacena los datos en tu ContentProvider y asegúrate de que otras apps tengan el permiso adecuado para acceder a tu proveedor. El mecanismo preferido para acceder es usar permisos por URI, que son temporales y solo otorgan acceso a la aplicación receptora. Una manera fácil de crear una clase ContentProvider como esta es usar la clase auxiliar FileProvider.
  • Usa la clase MediaStore del sistema. MediaStore es principalmente para video, tipos MIME de imágenes y audio; sin embargo, a partir de Android 3.0 (API nivel 11), también puede almacenar tipos que no son multimedia (consulta MediaStore.Files para obtener más información). Los archivos se pueden insertar en MediaStore mediante scanFile(). Luego, se pasa una content:// de estilo Uri adecuada para uso compartido a la devolución de llamada onScanCompleted() proporcionada. Ten en cuenta que, una vez que se agregue MediaStore al sistema, cualquier app del dispositivo podrá acceder al contenido.

Cómo usar el tipo de MIME adecuado

Debes proporcionar el tipo de MIME más específico para los datos que envías. Por ejemplo, debes usar text/plain cuando compartes texto sin formato. Estos son algunos tipos de MIME comunes cuando envías datos simples en Android.

  • text/plain, text/rtf, text/html y text/json; se deben registrar receptores para text/*.
  • image/jpg, image/png y image/gif; se deben registrar receptores para image/*.
  • video/mp4 y video/3gp; se deben registrar receptores para video/*.
  • application/pdf; se deben registrar receptores para las extensiones de archivos compatibles.
  • Aunque puedes usar un tipo de MIME */*, esto no se recomienda, porque solo se encontrarán coincidencias de actividades que pueden controlar flujos de datos genéricos.

Android Sharesheet también puede mostrar una vista previa de contenido sobre la base del tipo de MIME proporcionado. Algunas funciones de vista previa solo están disponibles para tipos específicos.

Consulta el registro oficial de IANA de los tipos multimedia de MIME.

Cómo compartir varios contenidos

Para compartir varios contenidos, 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, el tipo será "image/jpg". En el caso de una combinación de tipos de imágenes, será "image/*" para coincidir con una actividad que controle cualquier tipo de imagen. Si bien es posible compartir una combinación de tipos, no se recomienda, ya que no es claro para el receptor qué se pretende enviar. Si es necesario enviar varios tipos, usa "*/*". Corresponde a la aplicación receptora analizar y procesar los 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, "Share images to.."))
    

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, "Share images to.."));
    

Asegúrate de que las URIs proporcionadas 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 (API nivel 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. Te recomendamos compartir una URL compleja, como https://www.google.com/search?ei=2rRVXcLkJajM0PEPoLy7oA4. Una vista previa enriquecida ayudará a los usuarios a comprender 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(). Agrega una miniatura relevante mediante ClipData.

Nota: En general, la URI del contenido de la imagen se debe proporcionar desde una <cache-path> configurada en FileProvider. Consulta Cómo compartir archivos. Asegúrate de otorgar a Sharesheet los permisos adecuados para leer cualquier imagen que quieras usar como miniatura. 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 we're setting the title of the content
          putExtra(Intent.EXTRA_TITLE, "Introducing content previews")

          // (Optional) Here we'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, "Hello!");

    // (Optional) Here we're setting the title of the content
    sendIntent.putExtra(Intent.EXTRA_TITLE, "Send message");

    // (Optional) Here we'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 es similar a esta:

Cómo agregar orientaciones personalizadas

Android Sharesheet te permite especificar un número limitado de objetos ChooserTarget que se muestran antes de los accesos directos de uso compartido y los ChooserTargets cargados desde ChooserTargetServices. También puedes especificar un número limitado de intents que apunten a actividades enumeradas 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

    val share = Intent.createChooser(myShareIntent, 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 personalizado que agregas reduce la cantidad que sugiere el sistema. En general, no se recomienda agregar orientaciones personalizadas. Una forma apropiada de agregar Intent.EXTRA_INITIAL_INTENTS es proporcionar acciones adicionales que los usuarios puedan llevar a cabo en el contenido compartido. Por ejemplo, un usuario comparte imágenes y se usa Intent.EXTRA_INITIAL_INTENTS para otorgarles a los usuarios la capacidad de 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 orientaciones específicas, proporciona Intent.EXTRA_EXCLUDE_COMPONENTS., que se utiliza solo para eliminar las orientaciones que controlas. Un caso práctico común es ocultar los destinos de uso compartido de la app cuando los usuarios comparten contenido desde la app, ya que es probable que su intent comparta desde afuera de la app.

Agrega Intent.EXTRA_EXCLUDE_COMPONENTS a tu intent después de llamar a Intent.createChooser().

Kotlin

    val share = Intent.createChooser(myShareIntent, null).apply {
      // Only use components you have control over
      share.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, myComponentArray)
    }
    

Java

    share = Intent.createChooser(myShareIntent, null);
    // Only use components you have control over
    share.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, myComponentArray);
    

Cómo obtener información sobre el uso compartido

Puede ser útil saber cuándo los usuarios comparten y qué destino seleccionan. Para ello, Android Sharesheet proporciona el ComponentName de los destinos en los que tus usuarios hacen clic mediante una instancia de IntentSender.

Primero, crea un PendingIntent para un BroadcastReceiver y proporciona su IntentSender en Intent.createChooser().

Kotlin

    var share = new Intent(Intent.ACTION_SEND);
    ...
    val pi = PendingIntent.getBroadcast(myContext, requestCode, Intent(myContext, MyBroadcastReceiver.class),
    Intent.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),
                    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 usar el agente de resolución de intent de Android

Captura de pantalla del agente de resolución de intent de ACTION_SEND.

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 servicios adicionales como si llamaras a Android Sharesheet. Sin embargo, no debes llamar 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, denominado agente de resolución de intent, que permite al usuario elegir un destino donde compartir. Si se encuentra una aplicación, se ejecutará.

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 cómo enviar datos, consulta Intents y filtros de intents.