Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Cómo permitir que otras apps inicien tu actividad

Si tu app puede realizar una acción que podría ser útil desde otra app, debe estar preparada para responder a las solicitudes de acción especificando el filtro de intents apropiado en tu actividad.

Por ejemplo, si compilas una app social que puede compartir mensajes o fotos con los amigos del usuario, debes admitir el intent ACTION_SEND. Luego, cuando los usuarios inician una acción de "compartir" desde otra app, tu app aparece como una opción en el diálogo del selector (también conocido como "diálogo de desambiguación"), como se muestra en la figura 1.

Figura 1: Diálogo del selector

Para permitir que otras apps inicien tu actividad de esta forma, debes agregar un elemento <intent-filter> en tu archivo de manifiesto para el elemento <activity> correspondiente.

Si tu app está instalada en un dispositivo, el sistema identifica tus filtros de intents y agrega la información a un catálogo interno de intents admitidos por todas las apps instaladas. Cuando una app invoca a startActivity() o a startActivityForResult() con un intent implícito, el sistema comprueba qué actividad (o actividades) puede responder al intent.

Cómo agregar un filtro de intents

Con el fin de definir de manera adecuada los intents que tu actividad puede controlar, cada filtro de intents que agregues debe ser lo más específico posible en cuanto al tipo de acción y los datos que la actividad acepta.

El sistema puede enviar un Intent determinado a una actividad si esa actividad tiene un filtro de intents según los siguientes criterios del objeto Intent:

Acción
Se trata de una string que indica la acción por realizar. Por lo general, es uno de los valores definidos por la plataforma, como ACTION_SEND o ACTION_VIEW.

Especifica esto en tu filtro de intents con el elemento <action>. El valor que especifiques en este elemento debe ser el nombre completo de la string para la acción, en lugar de la constante de la API (consulta los ejemplos que aparecen a continuación).

Data
Es una descripción de los datos asociados con el intent.

Especifica esto en tu filtro de intents con el elemento <data>. Si usas uno o más atributos en este elemento, puedes especificar solo el tipo de MIME, solo un prefijo de URI, solo un esquema de URI, o una combinación de estos y otros atributos con el fin de indicar los tipos de datos aceptados.

Nota: Si no necesitas declarar datos específicos sobre el Uri de datos (por ejemplo, cuando tu actividad controla otro tipo de datos "adicionales" en lugar de un URI), solo debes especificar el atributo android:mimeType para declarar el tipo de datos que tu actividad maneja, como text/plain o image/jpeg.

Category
Es una forma adicional de caracterizar la actividad que controla el intent, en general, relacionada con el gesto del usuario o la ubicación desde la que se inicia. El sistema admite varias categorías diferentes, pero la mayoría se usan muy poco. Sin embargo, todos los intents implícitos se definen con CATEGORY_DEFAULT de forma predeterminada.

Especifica esto en tu filtro de intents con el elemento <category>.

En tu filtro de intents, puedes incluir cada uno de los criterios con los elementos XML correspondientes anidados en el elemento <intent-filter> para declarar los criterios que tu actividad acepta.

Por ejemplo, esta es una actividad con un filtro de intents que controla el intent ACTION_SEND cuando el tipo de datos es texto o una imagen:

    <activity android:name="ShareActivity">
        <intent-filter>
            <action android:name="android.intent.action.SEND"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:mimeType="text/plain"/>
            <data android:mimeType="image/*"/>
        </intent-filter>
    </activity>
    

Sugerencia: Si quieres que el ícono en el diálogo del selector sea diferente del ícono predeterminado de tu actividad, agrega android:icon en el elemento <intent-filter>.

Cada intent entrante especifica solo una acción y un tipo de datos, pero está bien declarar varias instancias de los elementos <action>, <category> y <data> en cada <intent-filter>.

Si existen dos pares de acción y datos que son mutuamente excluyentes en tus comportamientos, debes crear filtros de intents separados para especificar qué acciones son aceptables cuando están sincronizadas con determinados tipos de datos.

Por ejemplo, supongamos que tu actividad maneja texto e imágenes para los intents ACTION_SEND y ACTION_SENDTO. En este caso, debes definir dos filtros de intents separados para las dos acciones porque un intent ACTION_SENDTO debe usar el Uri de datos para especificar la dirección del destinatario con el esquema de URI send o sendto. Por ejemplo:

    <activity android:name="ShareActivity">
        <!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
        <intent-filter>
            <action android:name="android.intent.action.SENDTO"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:scheme="sms" />
            <data android:scheme="smsto" />
        </intent-filter>
        <!-- filter for sending text or images; accepts SEND action and text or image data -->
        <intent-filter>
            <action android:name="android.intent.action.SEND"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:mimeType="image/*"/>
            <data android:mimeType="text/plain"/>
        </intent-filter>
    </activity>
    

Nota: Para recibir intents implícitos, debes incluir la categoría CATEGORY_DEFAULT en el filtro de intents. Los métodos startActivity() y startActivityForResult() tratan a todos los intents como si declararan la categoría CATEGORY_DEFAULT. Si no la declaras en el filtro de intents, no se resolverá ningún intent implícito en la actividad.

Para obtener más información sobre el envío y la recepción de intents ACTION_SEND relacionados con comportamientos sociales y uso compartido, consulta la lección Cómo recibir datos simples de otras apps. También puedes encontrar información útil sobre cómo compartir datos en Cómo compartir datos simples y Cómo compartir archivos.

Cómo controlar el intent en tu actividad

A fin de decidir la acción que debe realizarse en tu actividad, puedes leer el Intent que se usó para iniciarla.

Al iniciar tu actividad, llama a getIntent() para recuperar el Intent que inició la actividad. Puedes hacerlo en cualquier momento del ciclo de vida de la actividad, pero generalmente debes hacerlo durante las primeras devoluciones de llamadas, como onCreate() o onStart().

Por ejemplo:

Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(R.layout.main)

        val data: Uri? = intent?.data

        // Figure out what to do based on the intent type
        if (intent?.type?.startsWith("image/") == true) {
            // Handle intents with image data ...
        } else if (intent?.type == "text/plain") {
            // Handle intents with text ...
        }
    }
    

Java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        // Get the intent that started this activity
        Intent intent = getIntent();
        Uri data = intent.getData();

        // Figure out what to do based on the intent type
        if (intent.getType().indexOf("image/") != -1) {
            // Handle intents with image data ...
        } else if (intent.getType().equals("text/plain")) {
            // Handle intents with text ...
        }
    }
    

Cómo mostrar un resultado

Si quieres mostrar un resultado a la actividad que invocó la tuya, simplemente llama al setResult() para especificar el código y el Intent de resultado. Cuando la operación finalice y el usuario deba volver a la actividad original, llama al finish() para cerrar (y destruir) tu actividad. Por ejemplo:

Kotlin

    // Create intent to deliver some kind of result data
    Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")).also { result ->
        setResult(Activity.RESULT_OK, result)
    }
    finish()
    

Java

    // Create intent to deliver some kind of result data
    Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"));
    setResult(Activity.RESULT_OK, result);
    finish();
    

Siempre debes especificar un código de resultado con el resultado. En general, es RESULT_OK o RESULT_CANCELED. Luego, puedes proporcionar datos adicionales con un Intent, según sea necesario.

Nota: El resultado se establece en RESULT_CANCELED de forma predeterminada. De este modo, si el usuario presiona el botón Atrás antes de completar la acción y antes de que establezcas el resultado, la actividad original recibirá el resultado de "cancelada".

Si solo necesitas mostrar un valor entero que indique una de varias opciones de resultado, puedes establecer el código de resultado en cualquier valor superior a 0. Si usas el código de resultado para entregar un entero y no necesitas incluir el Intent, puedes llamar al setResult() y transferir solo un código de resultado. Por ejemplo:

Kotlin

    setResult(RESULT_COLOR_RED)
    finish()
    

Java

    setResult(RESULT_COLOR_RED);
    finish();
    

En este caso, solo puede haber unos pocos resultados posibles, de modo que el código de resultado es un número entero definido localmente (mayor que 0). Esto funciona bien cuando muestras un resultado a una actividad en tu propia app, porque la actividad que recibe el resultado puede hacer referencia a la constante pública que determina el valor del código de resultado.

Nota: No es necesario verificar si tu actividad se inició con startActivity() o startActivityForResult(). Simplemente llama a setResult() si el intent que inició tu actividad puede esperar un resultado. Si la actividad inicial llama a startActivityForResult(), el sistema mostrará el resultado que proporciones a setResult(); de lo contrario, se ignorará el resultado.