Cómo recibir datos simples de otras apps

Así como una app puede enviar datos a otras apps, también puede recibirlos de ellas. Piensa en cómo los usuarios interactúan con tu aplicación y qué tipos de datos deseas recibir de otras aplicaciones. Por ejemplo, una aplicación de red social podría estar interesada en recibir de otra app contenido de texto, como una URL web interesante.

Los usuarios de otras apps suelen enviar datos a tu app a través de Android Sharesheet o el agente de resolución de intents. Las apps que envían datos a tu app deben establecer un tipo de MIME para esos datos. Tu app puede recibir datos que envía otra app de las siguientes maneras:

  • Un elemento Activity con una etiqueta intent-filter correspondiente en el manifiesto
  • Accesos directos de uso compartido publicados por tu app,

Los destinos de Direct Share son vínculos directos a una actividad específica dentro de tu app. Suelen representar a una persona o un grupo, y Android Sharesheet los muestra. Por ejemplo, una app de mensajería puede proporcionar un objetivo de Direct Share para una persona que establezca un vínculo directo a una conversación con esa persona. Consulta Cómo proporcionar objetivos de Direct Share para obtener instrucciones detalladas.

Compatibilidad con tipos de MIME

Idealmente, una app debe poder recibir la mayor variedad posible de tipos de MIME. Por ejemplo, una app de mensajería diseñada para enviar texto, imágenes y video debería poder recibir text/*, image/* y video/*. Estos son algunos tipos de MIME comunes para enviar y recibir datos simples en Android.

Los receptores se registran para Los remitentes envían
text/*
  • text/plain
  • text/rtf
  • text/html
  • text/json
`image/*`
  • image/jpg
  • image/png
  • image/gif
video/*
  • video/mp4
  • video/3gp
Extensiones de archivo compatibles application/pdf

Consulta el registro oficial de IANA de tipos de medios MIME.

Cómo crear grandes objetivos de uso compartido

Cuando un usuario presiona un objetivo de uso compartido asociado con una actividad específica, debería poder confirmar y editar el contenido compartido antes de usarlo. Esto resulta particularmente importante para datos de texto.

Cómo recibir datos con una actividad

Recibir datos con una actividad implica actualizar tu manifiesto, controlar el contenido entrante y asegurarte de que el usuario reconozca tu app.

Actualiza tu manifiesto

Los filtros de intents informan al sistema qué intents acepta un componente de la app. Así como construiste un intent con una acción ACTION_SEND en la lección Cómo enviar datos simples a otras apps, puedes crear filtros de intents para recibir intents con esta acción. El filtro de intents se define en tu manifiesto con el elemento <intent-filter>. Por ejemplo, si tu app puede recibir 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" >
    <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 intente compartir cualquiera de estos elementos construyendo un intent y pasándolo a startActivity(), tu app aparecerá como opción en Android Sharesheet o el agente de resolución de intents. Si el usuario selecciona tu app, se inicia la actividad correspondiente (.ui.MyActivity en el ejemplo anterior). Luego, dependerá de ti que manejes correctamente el contenido dentro de tu IU y código.

Cómo administrar el contenido entrante

Para controlar el contenido publicado por un Intent, llama a getIntent() para obtener el objeto Intent. Cuando lo tengas, podrás examinar su contenido para determinar qué hacer luego. Si esta actividad puede iniciarse desde otras partes del sistema (como el selector), tenlo en cuenta cuando examines el intent.

Presta especial atención a revisar los datos entrantes, ya que nunca se sabe qué podría enviarte otra aplicación. Por ejemplo, podría estar configurado el tipo de MIME incorrecto o la imagen enviada podría ser extremadamente grande. También recuerda procesar los datos binarios en un subproceso independiente, en lugar de hacerlo en el subproceso principal ("IU").

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    when {
        intent?.action == Intent.ACTION_SEND -> {
            if ("text/plain" == intent.type) {
                handleSendText(intent) // Handle text being sent
            } else if (intent.type?.startsWith("image/") == true) {
                handleSendImage(intent) // Handle single image being sent
            }
        }
        intent?.action == Intent.ACTION_SEND_MULTIPLE
                && 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 to reflect text being shared
    }
}

private fun handleSendImage(intent: Intent) {
    (intent.getParcelableExtra<Parcelable>(Intent.EXTRA_STREAM) as? Uri)?.let {
        // Update UI to reflect image being shared
    }
}

private fun handleSendMultipleImages(intent: Intent) {
    intent.getParcelableArrayListExtra<Parcelable>(Intent.EXTRA_STREAM)?.let {
        // Update UI to reflect multiple images being shared
    }
}

Java

void onCreate (Bundle savedInstanceState) {
    ...
    // Get intent, action and MIME type
    Intent intent = getIntent();
    String action = intent.getAction();
    String type = intent.getType();

    if (Intent.ACTION_SEND.equals(action) && type != null) {
        if ("text/plain".equals(type)) {
            handleSendText(intent); // Handle text being sent
        } else if (type.startsWith("image/")) {
            handleSendImage(intent); // Handle single image being sent
        }
    } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) && type != null) {
        if (type.startsWith("image/")) {
            handleSendMultipleImages(intent); // Handle multiple images being sent
        }
    } else {
        // Handle other intents, such as being started from the home screen
    }
    ...
}

void handleSendText(Intent intent) {
    String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);
    if (sharedText != null) {
        // Update UI to reflect text being shared
    }
}

void handleSendImage(Intent intent) {
    Uri imageUri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
    if (imageUri != null) {
        // Update UI to reflect image being shared
    }
}

void handleSendMultipleImages(Intent intent) {
    ArrayList<Uri> imageUris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
    if (imageUris != null) {
        // Update UI to reflect multiple images being shared
    }
}

La actualización de la IU después de recibir los datos puede ser tan simple como completar un elemento EditText o puede resultar más complicada, como aplicar un filtro de foto interesante a una imagen. Lo que ocurra a continuación depende de tu app.

Cómo asegurarte de que los usuarios reconozcan tu app

La app se representa con el ícono y la etiqueta en Android Sharesheet y en el agente de resolución de intents. Ambos se definen en el manifiesto. Puedes establecer etiquetas de filtros de intent o actividad para brindar más contexto.

A partir de Android 10 (nivel de API 29), Android Sharesheet solo usa íconos configurados en el manifiesto en tu etiqueta application. Android ignora los íconos establecidos en las etiquetas intent-filter y activity.