Intents comunes

Un intent te permite iniciar una actividad en otra app describiendo una acción que deseas realizar, como "ver un mapa" o "tomar una foto", en un objeto Intent. Este tipo de intent se denomina intent implícito porque no especifica el componente de la app que se iniciará, sino que especifica una acción y proporciona algunos datos con los que se realizará la acción.

Cuando llamas a startActivity() o startActivityForResult() y le pasas un intent implícito, el sistema resuelve el intent en una app que puede controlarlo y, luego, inicia su Activity correspondiente. Si hay más de una app que puede controlar el intent, el sistema le presenta al usuario un diálogo para que elija qué app usar.

En esta página, se describen varios intents implícitos que puedes usar para realizar acciones comunes, organizados por el tipo de app que controla el intent. En cada sección, también se muestra cómo puedes crear un filtro de intents para anunciar la capacidad de tu app de realizar la acción.

Precaución: Si no hay apps en el dispositivo que puedan recibir un intent implícito, se detendrá una app cuando llame a startActivity(). Para verificar primero que existe una app para recibir el intent, llama a resolveActivity() en tu objeto Intent. Si el resultado no es nulo, hay al menos una app que puede controlar el intent, y es seguro llamar a startActivity(). Si el resultado es nulo, no uses el intent y, si es posible, inhabilita la función que lo invoca.

Si no sabes cómo crear intents o filtros de intents, primero lee Intents y filtros de intents.

Para obtener información sobre cómo activar los intents que se indican en esta página desde tu host de desarrollo, consulta la sección Verifica intents con Android Debug Bridge.

Google Voice Actions

Acciones de Google Voice activa algunos de los intents que se indican en esta página en respuesta a comandos por voz. Para obtener más información, consulta Cómo comenzar a usar las acciones de voz del sistema.

Despertador

A continuación, se indican las acciones comunes para las apps de reloj despertador, incluida la información que necesitas para crear un filtro de intents que anuncie la capacidad de tu app para realizar cada acción.

Crear una alarma

Google Voice Actions

  • "Establece una alarma para las 7 a.m."

Para crear una alarma nueva, usa la acción ACTION_SET_ALARM y especifica los detalles de la alarma, como la hora y el mensaje, con los siguientes elementos adicionales.

Nota: Solo la hora, los minutos y los elementos adicionales del mensaje están disponibles en Android 2.3 (nivel de API 9) y versiones anteriores. Los otros extras están disponibles en versiones superiores de la plataforma.

Acción
ACTION_SET_ALARM
URI de datos
Ninguno
Tipo de MIME
Ninguno
Adicional
EXTRA_HOUR
La hora de la alarma.
EXTRA_MINUTES
Los minutos de la alarma.
EXTRA_MESSAGE
Es un mensaje personalizado para identificar la alarma.
EXTRA_DAYS
Un ArrayList que incluye cada día de la semana en el que se repite esta alarma. Cada día se debe declarar con un número entero de la clase Calendar, como MONDAY.

Para una alarma única, no especifiques este parámetro adicional.

EXTRA_RINGTONE
Un URI de content: que especifica un tono de llamada para usar con la alarma o VALUE_RINGTONE_SILENT si no se desea usar un tono de llamada.

Para usar el tono predeterminado, no especifiques este elemento adicional.

EXTRA_VIBRATE
Es un valor booleano que especifica si se debe vibrar para esta alarma.
EXTRA_SKIP_UI
Un valor booleano que especifica si la app que responde debe omitir su IU cuando se configura la alarma. Si es verdadero, la app debe omitir cualquier IU de confirmación y configurar la alarma especificada.

Ejemplo de intención:

Kotlin

fun createAlarm(message: String, hour: Int, minutes: Int) {
    val intent = Intent(AlarmClock.ACTION_SET_ALARM).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_HOUR, hour)
        putExtra(AlarmClock.EXTRA_MINUTES, minutes)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void createAlarm(String message, int hour, int minutes) {
    Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_HOUR, hour)
            .putExtra(AlarmClock.EXTRA_MINUTES, minutes);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
Nota:

Para invocar el intent ACTION_SET_ALARM, tu app debe tener el permiso SET_ALARM:

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SET_ALARM" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Crear un temporizador

Google Voice Actions

  • “Establece un temporizador de 5 minutos”

Para crear un temporizador de cuenta regresiva, usa la acción ACTION_SET_TIMER y especifica los detalles del temporizador, como la duración, con los siguientes parámetros adicionales.

Nota: Este intent está disponible en Android 4.4 (nivel de API 19) y versiones posteriores.

Acción
ACTION_SET_TIMER
URI de datos
Ninguno
Tipo de MIME
Ninguno
Adicional
EXTRA_LENGTH
Es la duración del temporizador en segundos.
EXTRA_MESSAGE
Es un mensaje personalizado para identificar el temporizador.
EXTRA_SKIP_UI
Un valor booleano que especifica si la app que responde debe omitir su IU cuando se configura el temporizador. Si es verdadero, la app debe omitir cualquier IU de confirmación y comenzar el temporizador especificado.

Ejemplo de intención:

Kotlin

fun startTimer(message: String, seconds: Int) {
    val intent = Intent(AlarmClock.ACTION_SET_TIMER).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_LENGTH, seconds)
        putExtra(AlarmClock.EXTRA_SKIP_UI, true)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void startTimer(String message, int seconds) {
    Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_LENGTH, seconds)
            .putExtra(AlarmClock.EXTRA_SKIP_UI, true);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
Nota:

Para invocar el intent ACTION_SET_TIMER, tu app debe tener el permiso SET_ALARM:

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SET_TIMER" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Mostrar todas las alarmas

Para mostrar la lista de alarmas, usa la acción ACTION_SHOW_ALARMS.

Si bien no muchas apps invocan este intent, ya que lo usan principalmente las apps del sistema, cualquier app que se comporte como un reloj despertador puede implementar este filtro de intents y responder mostrando la lista de alarmas actuales.

Nota: Este intent está disponible en Android 4.4 (nivel de API 19) y versiones posteriores.

Acción
ACTION_SHOW_ALARMS
URI de datos
Ninguno
Tipo de MIME
Ninguno

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SHOW_ALARMS" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Calendario

Agregar un evento es una acción común para las apps de calendario. Crea un filtro de intents para anunciar la capacidad de tu app de realizar esta acción con la información de la siguiente sección.

Agregar un evento de calendario

Para agregar un evento nuevo al calendario del usuario, usa la acción ACTION_INSERT y especifica el URI de datos con Events.CONTENT_URI. Luego, puedes especificar varios detalles del evento con los siguientes elementos adicionales.

Acción
ACTION_INSERT
URI de datos
Events.CONTENT_URI
Tipo de MIME
"vnd.android.cursor.dir/event"
Adicional
EXTRA_EVENT_ALL_DAY
Es un valor booleano que especifica si se trata de un evento que dura todo el día.
EXTRA_EVENT_BEGIN_TIME
Es la hora de inicio del evento (milisegundos desde la época).
EXTRA_EVENT_END_TIME
Es la hora de finalización del evento (milisegundos desde la época).
TITLE
Es el título del evento.
DESCRIPTION
Descripción del evento.
EVENT_LOCATION
Ubicación del evento.
EXTRA_EMAIL
Lista separada por comas de las direcciones de correo electrónico que especifican a los invitados.

Se pueden especificar muchos más detalles del evento con las constantes definidas en la clase CalendarContract.EventsColumns.

Ejemplo de intención:

Kotlin

fun addEvent(title: String, location: String, begin: Long, end: Long) {
    val intent = Intent(Intent.ACTION_INSERT).apply {
        data = Events.CONTENT_URI
        putExtra(Events.TITLE, title)
        putExtra(Events.EVENT_LOCATION, location)
        putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
        putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void addEvent(String title, String location, long begin, long end) {
    Intent intent = new Intent(Intent.ACTION_INSERT)
            .setData(Events.CONTENT_URI)
            .putExtra(Events.TITLE, title)
            .putExtra(Events.EVENT_LOCATION, location)
            .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
            .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.INSERT" />
        <data android:mimeType="vnd.android.cursor.dir/event" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Cámara

A continuación, se indican las acciones comunes para las apps de cámara, incluida la información que necesitas para crear un filtro de intents que anuncie la capacidad de tu app para realizar cada acción.

Capturar y mostrar una imagen o video

Para abrir una app de cámara y recibir la foto o el video resultante, usa la acción ACTION_IMAGE_CAPTURE o ACTION_VIDEO_CAPTURE. También debes especificar la ubicación del URI en la que deseas que la cámara guarde la foto o el video en el elemento EXTRA_OUTPUT extra.

Acción
ACTION_IMAGE_CAPTURE o
ACTION_VIDEO_CAPTURE
Esquema de URI de datos
Ninguno
Tipo de MIME
Ninguno
Adicional
EXTRA_OUTPUT
Es la ubicación del URI en la que la app de la cámara guarda el archivo de foto o video (como un objeto Uri).

Cuando la app de cámara devuelve correctamente el enfoque a tu actividad (en otras palabras, tu app recibe la devolución de llamada onActivityResult()), puedes acceder a la foto o el video en el URI que especificaste con el valor EXTRA_OUTPUT.

Nota: Cuando usas ACTION_IMAGE_CAPTURE para capturar una foto, es posible que la cámara también devuelva una copia reducida o una miniatura de la foto en el resultado Intent, guardada como un Bitmap en un campo adicional llamado "data".

Ejemplo de intención:

Kotlin

const val REQUEST_IMAGE_CAPTURE = 1
val locationForPhotos: Uri = ...

fun capturePhoto(targetFilename: String) {
    val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
        putExtra(MediaStore.EXTRA_OUTPUT, Uri.withAppendedPath(locationForPhotos, targetFilename))
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
        val thumbnail: Bitmap = data.getParcelableExtra("data")
        // Do other work with full size photo saved in locationForPhotos.
        ...
    }
}

Java

static final int REQUEST_IMAGE_CAPTURE = 1;
static final Uri locationForPhotos;

public void capturePhoto(String targetFilename) {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.withAppendedPath(locationForPhotos, targetFilename));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelableExtra("data");
        // Do other work with full size photo saved in locationForPhotos.
        ...
    }
}

Para ello, cuando trabajes en Android 12 (nivel de API 31) o versiones posteriores, consulta el siguiente ejemplo de intent.

Ejemplo de intención:

Kotlin

val REQUEST_IMAGE_CAPTURE = 1

private fun dispatchTakePictureIntent() {
    val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    try {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
    } catch (e: ActivityNotFoundException) {
        // Display error state to the user.
    }
}

Java

static final int REQUEST_IMAGE_CAPTURE = 1;

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    try {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
    } catch (ActivityNotFoundException e) {
        // Display error state to the user.
    }
}
</section></div>

Para obtener más información sobre cómo usar esta intención para capturar una foto, incluido cómo crear un Uri adecuado para la ubicación de salida, consulta Cómo tomar fotos o Cómo grabar videos.

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.IMAGE_CAPTURE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Cuando controlas este intent, haz que tu actividad verifique el elemento EXTRA_OUTPUT adicional en el Intent entrante, luego guarda la imagen o el video capturados en la ubicación especificada por ese elemento adicional y llama a setResult() con un Intent que incluya una miniatura comprimida en un elemento adicional llamado "data".

Iniciar una aplicación de cámara en modo de imagen detenida

Google Voice Actions

  • "Toma una foto".

Para abrir una app de cámara en modo de imagen fija, usa la acción INTENT_ACTION_STILL_IMAGE_CAMERA.

Acción
INTENT_ACTION_STILL_IMAGE_CAMERA
Esquema de URI de datos
Ninguno
Tipo de MIME
Ninguno
Adicional
Ninguno

Ejemplo de intención:

Kotlin

private fun dispatchTakePictureIntent() {
    val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    try {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
    } catch (e: ActivityNotFoundException) {
        // Display error state to the user.
    }
}

Java

public void capturePhoto(String targetFilename) {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.withAppendedPath(locationForPhotos, targetFilename));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.STILL_IMAGE_CAMERA" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Iniciar una aplicación de cámara en modo de video

Google Voice Actions

  • "Graba un video".

Para abrir una app de cámara en modo de video, usa la acción INTENT_ACTION_VIDEO_CAMERA.

Acción
INTENT_ACTION_VIDEO_CAMERA
Esquema de URI de datos
Ninguno
Tipo de MIME
Ninguno
Adicional
Ninguno

Ejemplo de intención:

Kotlin

fun capturePhoto() {
    val intent = Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA)
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
    }
}

Java

public void capturePhoto() {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.VIDEO_CAMERA" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

App de Contactos o Personas

A continuación, se indican las acciones comunes para las apps de administración de contactos, incluida la información que necesitas para crear un filtro de intents que anuncie la capacidad de tu app para realizar cada acción.

Elige un contacto

Para que el usuario seleccione un contacto y le proporcione a tu app acceso a toda la información de contacto, usa la acción ACTION_PICK y especifica el tipo de MIME como Contacts.CONTENT_TYPE.

El resultado Intent que se entrega a tu devolución de llamada onActivityResult() contiene el URI content: que apunta al contacto seleccionado. La respuesta otorga a tu app permisos temporales para leer ese contacto con la API del Proveedor de contactos, incluso si tu app no incluye el permiso READ_CONTACTS.

Nota: Si solo necesitas acceder a un dato de contacto específico, como un número de teléfono o una dirección de correo electrónico, consulta la siguiente sección sobre cómo seleccionar datos de contacto específicos.

Acción
ACTION_PICK
Esquema de URI de datos
Ninguno
Tipo de MIME
Contacts.CONTENT_TYPE

Ejemplo de intención:

Kotlin

const val REQUEST_SELECT_CONTACT = 1

fun selectContact() {
    val intent = Intent(Intent.ACTION_PICK).apply {
        type = ContactsContract.Contacts.CONTENT_TYPE
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_SELECT_CONTACT)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
        val contactUri: Uri = data.data
        // Do something with the selected contact at contactUri.
        //...
    }
}

Java

static final int REQUEST_SELECT_CONTACT = 1;

public void selectContact() {
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_SELECT_CONTACT);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
        Uri contactUri = data.getData();
        // Do something with the selected contact at contactUri.
        ...
    }
}

Para obtener información sobre cómo recuperar los detalles de un contacto una vez que tengas su URI, consulta Cómo obtener detalles de un contacto.

Cuando recuperas el URI de contacto con este intent, por lo general, no necesitas el permiso READ_CONTACTS para leer los detalles básicos de ese contacto, como el nombre visible y si el contacto está destacado. Sin embargo, si intentas leer datos más específicos sobre un contacto determinado, como su número de teléfono o dirección de correo electrónico, necesitas el permiso READ_CONTACTS.

Seleccionar datos de un contacto específico

Para que el usuario seleccione un dato específico de un contacto, como un número de teléfono, una dirección de correo electrónico o algún otro tipo de dato, usa la acción ACTION_PICK y especifica el tipo de MIME en uno de los siguientes tipos de contenido, como CommonDataKinds.Phone.CONTENT_TYPE para obtener el número de teléfono del contacto.

Nota: En muchos casos, tu app debe tener el permiso READ_CONTACTS para ver información específica sobre un contacto en particular.

Si solo necesitas recuperar un tipo de datos de un contacto, esta técnica con un CONTENT_TYPE de las clases ContactsContract.CommonDataKinds es más eficiente que usar Contacts.CONTENT_TYPE, como se muestra en la sección anterior. El resultado te brinda acceso directo a los datos deseados sin necesidad de que realices una consulta más compleja al Proveedor de contactos.

El resultado Intent que se entrega a tu devolución de llamada onActivityResult() contiene el URI content: que apunta a los datos de contacto seleccionados. La respuesta otorga a tu app permisos temporales para leer los datos de ese contacto, incluso si tu app no incluye el permiso READ_CONTACTS.

Acción
ACTION_PICK
Esquema de URI de datos
Ninguno
Tipo de MIME
CommonDataKinds.Phone.CONTENT_TYPE
Elige entre los contactos que tienen un número de teléfono.
CommonDataKinds.Email.CONTENT_TYPE
Elige entre los contactos que tengan una dirección de correo electrónico.
CommonDataKinds.StructuredPostal.CONTENT_TYPE
Elige entre los contactos con una dirección postal.

O uno de muchos otros valores de CONTENT_TYPE en ContactsContract.

Ejemplo de intención:

Kotlin

const val REQUEST_SELECT_PHONE_NUMBER = 1

fun selectContact() {
    // Start an activity for the user to pick a phone number from contacts.
    val intent = Intent(Intent.ACTION_PICK).apply {
        type = CommonDataKinds.Phone.CONTENT_TYPE
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == Activity.RESULT_OK) {
        // Get the URI and query the content provider for the phone number.
        val contactUri: Uri = data.data
        val projection: Array<String> = arrayOf(CommonDataKinds.Phone.NUMBER)
        contentResolver.query(contactUri, projection, null, null, null).use { cursor ->
            // If the cursor returned is valid, get the phone number.
            if (cursor.moveToFirst()) {
                val numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER)
                val number = cursor.getString(numberIndex)
                // Do something with the phone number.
                ...
            }
        }
    }
}

Java

static final int REQUEST_SELECT_PHONE_NUMBER = 1;

public void selectContact() {
    // Start an activity for the user to pick a phone number from contacts.
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType(CommonDataKinds.Phone.CONTENT_TYPE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == RESULT_OK) {
        // Get the URI and query the content provider for the phone number.
        Uri contactUri = data.getData();
        String[] projection = new String[]{CommonDataKinds.Phone.NUMBER};
        Cursor cursor = getContentResolver().query(contactUri, projection,
                null, null, null);
        // If the cursor returned is valid, get the phone number.
        if (cursor != null && cursor.moveToFirst()) {
            int numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER);
            String number = cursor.getString(numberIndex);
            // Do something with the phone number.
            //...
        }
    }
}

Ver un contacto

Para mostrar los detalles de un contacto conocido, usa la acción ACTION_VIEW y especifica el contacto con un URI content: como datos del intent.

Existen dos formas principales de recuperar inicialmente el URI del contacto:

Acción
ACTION_VIEW
Esquema de URI de datos
content:<URI>
Tipo de MIME
Ninguno. El tipo se infiere del URI de contacto.

Ejemplo de intención:

Kotlin

fun viewContact(contactUri: Uri) {
    val intent = Intent(Intent.ACTION_VIEW, contactUri)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void viewContact(Uri contactUri) {
    Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Editar un contacto existente

Para editar un contacto conocido, usa la acción ACTION_EDIT, especifica el contacto con un URI de content: como los datos de la intent y, luego, incluye cualquier información de contacto conocida en los elementos adicionales especificados por las constantes en ContactsContract.Intents.Insert.

Existen dos formas principales de recuperar inicialmente el URI de contacto:

Acción
ACTION_EDIT
Esquema de URI de datos
content:<URI>
Tipo de MIME
El tipo se infiere del URI de contacto.
Adicional
Uno o más de los elementos adicionales definidos en ContactsContract.Intents.Insert para que puedas completar los campos de los detalles de contacto.

Ejemplo de intención:

Kotlin

fun editContact(contactUri: Uri, email: String) {
    val intent = Intent(Intent.ACTION_EDIT).apply {
        data = contactUri
        putExtra(ContactsContract.Intents.Insert.EMAIL, email)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void editContact(Uri contactUri, String email) {
    Intent intent = new Intent(Intent.ACTION_EDIT);
    intent.setData(contactUri);
    intent.putExtra(Intents.Insert.EMAIL, email);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Para obtener más información sobre cómo editar un contacto, consulta Cómo modificar contactos con intents.

Insertar un contacto

Para insertar un contacto nuevo, usa la acción ACTION_INSERT, especifica Contacts.CONTENT_TYPE como el tipo de MIME y, luego, incluye la información de contacto conocida en los elementos adicionales especificados por las constantes en ContactsContract.Intents.Insert.

Acción
ACTION_INSERT
Esquema de URI de datos
Ninguno
Tipo de MIME
Contacts.CONTENT_TYPE
Adicional
Uno o más de los elementos adicionales definidos en ContactsContract.Intents.Insert.

Ejemplo de intención:

Kotlin

fun insertContact(name: String, email: String) {
    val intent = Intent(Intent.ACTION_INSERT).apply {
        type = ContactsContract.Contacts.CONTENT_TYPE
        putExtra(ContactsContract.Intents.Insert.NAME, name)
        putExtra(ContactsContract.Intents.Insert.EMAIL, email)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void insertContact(String name, String email) {
    Intent intent = new Intent(Intent.ACTION_INSERT);
    intent.setType(Contacts.CONTENT_TYPE);
    intent.putExtra(Intents.Insert.NAME, name);
    intent.putExtra(Intents.Insert.EMAIL, email);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Para obtener más información sobre cómo insertar un contacto, consulta Cómo modificar contactos con intents.

Correo electrónico

Redactar un correo electrónico con archivos adjuntos opcionales es una acción común para las apps de correo electrónico. Crea un filtro de intents para anunciar la capacidad de tu app de realizar esta acción con la información de la siguiente sección.

Redactar un correo electrónico con archivos adjuntos opcionales

Para redactar un correo electrónico, usa una de las siguientes acciones según si incluirás archivos adjuntos o no, y agrega detalles del correo electrónico, como el destinatario y el asunto, con las teclas adicionales que se indican.

Acción
ACTION_SENDTO (para ningún archivo adjunto) o
ACTION_SEND (para un archivo adjunto) o
ACTION_SEND_MULTIPLE (para varios archivos adjuntos)
Esquema de URI de datos
Ninguno
Tipo de MIME
"text/plain"
"*/*"
Adicional
Intent.EXTRA_EMAIL
Es un array de cadenas de todas las direcciones de correo electrónico de los destinatarios en el campo "Para".
Intent.EXTRA_CC
Es un array de cadenas de todas las direcciones de correo electrónico de los destinatarios en "CC".
Intent.EXTRA_BCC
Es un array de cadenas de todas las direcciones de correo electrónico de los destinatarios en "Cco".
Intent.EXTRA_SUBJECT
Es una cadena que incluye el asunto del correo electrónico.
Intent.EXTRA_TEXT
Es una cadena que incluye el cuerpo del correo electrónico.
Intent.EXTRA_STREAM
Un Uri que apunta al archivo adjunto. Si usas la acción ACTION_SEND_MULTIPLE, en su lugar, se trata de un ArrayList que contiene varios objetos Uri.

Ejemplo de intención:

Kotlin

fun composeEmail(addresses: Array<String>, subject: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SEND).apply {
        type = "*/*"
        putExtra(Intent.EXTRA_EMAIL, addresses)
        putExtra(Intent.EXTRA_SUBJECT, subject)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void composeEmail(String[] addresses, String subject, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("*/*");
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Si quieres asegurarte de que tu intent solo se controle con una app de correo electrónico y no con una app de mensajería de texto o social, usa la acción ACTION_SENDTO y, luego, incluye el esquema de datos "mailto:", como se muestra en el siguiente ejemplo:

Kotlin

fun composeEmail(addresses: Array<String>, subject: String) {
    val intent = Intent(Intent.ACTION_SENDTO).apply {
        data = Uri.parse("mailto:") // Only email apps handle this.
        putExtra(Intent.EXTRA_EMAIL, addresses)
        putExtra(Intent.EXTRA_SUBJECT, subject)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void composeEmail(String[] addresses, String subject) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // Only email apps handle this.
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="*/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SENDTO" />
        <data android:scheme="mailto" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Almacenamiento de archivos

A continuación, se indican las acciones comunes para las apps de almacenamiento de archivos, incluida la información que necesitas para crear un filtro de intents y anunciar la capacidad de tu app para realizar cada acción.

Recuperar un tipo específico de archivo

Para solicitar que el usuario seleccione un archivo, como un documento o una foto, y devolver una referencia a tu app, usa la acción ACTION_GET_CONTENT y especifica el tipo de MIME que desees. La referencia de archivo que se devuelve a tu app es transitoria para el ciclo de vida actual de tu actividad, por lo que, si quieres acceder a ella más adelante, debes importar una copia que puedas leer más tarde.

Esta intención también permite que el usuario cree un archivo nuevo en el proceso. Por ejemplo, en lugar de seleccionar una foto existente, el usuario puede capturar una nueva con la cámara.

El intent de resultado que se entrega a tu método onActivityResult() incluye datos con un URI que apunta al archivo. El URI puede ser cualquiera, como un URI de http:, un URI de file: o un URI de content:. Sin embargo, si deseas restringir los archivos seleccionables solo a aquellos a los que se puede acceder desde un proveedor de contenido (un URI de content:) y que están disponibles como un flujo de archivos con openFileDescriptor(), agrega la categoría CATEGORY_OPENABLE a tu intent.

En Android 4.3 (nivel de API 18) y versiones posteriores, también puedes permitir que el usuario seleccione varios archivos agregando EXTRA_ALLOW_MULTIPLE al intent, establecido en true. Luego, puedes acceder a cada uno de los archivos seleccionados en un objeto ClipData que devuelve getClipData().

Acción
ACTION_GET_CONTENT
Esquema de URI de datos
Ninguno
Tipo de MIME
Es el tipo de MIME correspondiente al tipo de archivo que el usuario debe seleccionar.
Adicional
EXTRA_ALLOW_MULTIPLE
Es un valor booleano que declara si el usuario puede seleccionar más de un archivo a la vez.
EXTRA_LOCAL_ONLY
Es un valor booleano que declara si el archivo devuelto debe estar disponible directamente desde el dispositivo, en lugar de requerir una descarga desde un servicio remoto.
Categoría (opcional)
CATEGORY_OPENABLE
Para devolver solo los archivos "abribles" que se pueden representar como un flujo de archivos con openFileDescriptor().

Ejemplo de intención para obtener una foto:

Kotlin

const val REQUEST_IMAGE_GET = 1

fun selectImage() {
    val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
        type = "image/*"
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == Activity.RESULT_OK) {
        val thumbnail: Bitmap = data.getParcelableExtra("data")
        val fullPhotoUri: Uri = data.data
        // Do work with photo saved at fullPhotoUri.
        ...
    }
}

Java

static final int REQUEST_IMAGE_GET = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelable("data");
        Uri fullPhotoUri = data.getData();
        // Do work with photo saved at fullPhotoUri.
        ...
    }
}

Ejemplo de filtro de intents para devolver una foto:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- The OPENABLE category declares that the returned file is accessible
             from a content provider that supports OpenableColumns
             and ContentResolver.openFileDescriptor(). -->
        <category android:name="android.intent.category.OPENABLE" />
    </intent-filter>
</activity>

Abrir un tipo específico de archivo

En lugar de recuperar una copia de un archivo que debes importar a tu app, con la acción ACTION_GET_CONTENT, cuando se ejecuta en Android 4.4 o versiones posteriores, puedes solicitar abrir un archivo que administra otra app con la acción ACTION_OPEN_DOCUMENT y especificar un tipo de MIME. Para permitir que el usuario cree un documento nuevo en el que tu app pueda escribir, usa la acción ACTION_CREATE_DOCUMENT.

Por ejemplo, en lugar de seleccionar entre documentos PDF existentes, el intent ACTION_CREATE_DOCUMENT permite a los usuarios seleccionar dónde desean crear un documento nuevo, por ejemplo, dentro de otra app que administra el almacenamiento del documento. Luego, tu app recibe la ubicación del URI en la que puede escribir el documento nuevo.

Mientras que el intent que se entrega a tu método onActivityResult() desde la acción ACTION_GET_CONTENT puede devolver un URI de cualquier tipo, el intent de resultado de ACTION_OPEN_DOCUMENT y ACTION_CREATE_DOCUMENT siempre especifica el archivo elegido como un URI content: respaldado por un DocumentsProvider. Puedes abrir el archivo con openFileDescriptor() y consultar sus detalles con las columnas de DocumentsContract.Document.

El URI que se devuelve le otorga a tu app acceso de lectura a largo plazo al archivo, y también es posible que le otorgue acceso de escritura. La acción ACTION_OPEN_DOCUMENT es particularmente útil cuando deseas leer un archivo existente sin hacer una copia en tu app o cuando deseas abrir y editar un archivo en su lugar.

También puedes permitir que el usuario seleccione varios archivos agregando EXTRA_ALLOW_MULTIPLE al intent y configurándolo como true. Si el usuario selecciona solo un elemento, puedes recuperarlo de getData(). Si el usuario selecciona más de un elemento, getData() devuelve nulo y, en su lugar, debes recuperar cada elemento de un objeto ClipData que devuelve getClipData().

Nota: Tu intent debe especificar un tipo de MIME y debe declarar la categoría CATEGORY_OPENABLE. Si es apropiado, puedes especificar más de un tipo de MIME agregando un array de tipos de MIME con el elemento adicional EXTRA_MIME_TYPES. Si lo haces, debes establecer el tipo de MIME principal en setType() como "*/*".

Acción
ACTION_OPEN_DOCUMENT o
ACTION_CREATE_DOCUMENT
Esquema de URI de datos
Ninguno
Tipo de MIME
Es el tipo de MIME correspondiente al tipo de archivo que el usuario debe seleccionar.
Adicional
EXTRA_MIME_TYPES
Es un array de tipos de MIME que corresponden a los tipos de archivos que solicita tu app. Cuando uses este parámetro adicional, debes establecer el tipo de MIME principal en setType() como "*/*".
EXTRA_ALLOW_MULTIPLE
Es un valor booleano que declara si el usuario puede seleccionar más de un archivo a la vez.
EXTRA_TITLE
Para usar con ACTION_CREATE_DOCUMENT y especificar un nombre de archivo inicial.
EXTRA_LOCAL_ONLY
Es un valor booleano que declara si el archivo devuelto debe estar disponible directamente desde el dispositivo, en lugar de requerir una descarga desde un servicio remoto.
Categoría
CATEGORY_OPENABLE
Para devolver solo los archivos "abribles" que se pueden representar como un flujo de archivos con openFileDescriptor().

Ejemplo de intención para obtener una foto:

Kotlin

const val REQUEST_IMAGE_OPEN = 1

fun selectImage2() {
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
        type = "image/*"
        addCategory(Intent.CATEGORY_OPENABLE)
    }
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == Activity.RESULT_OK) {
        val fullPhotoUri: Uri = data.data
        // Do work with full size photo saved at fullPhotoUri.
        ...
    }
}

Java

static final int REQUEST_IMAGE_OPEN = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.setType("image/*");
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) {
        Uri fullPhotoUri = data.getData();
        // Do work with full size photo saved at fullPhotoUri.
        ...
    }
}

Las apps de terceros no pueden responder a un intent con la acción ACTION_OPEN_DOCUMENT. En cambio, el sistema recibe esta intención y muestra todos los archivos disponibles de varias apps en una interfaz de usuario unificada.

Para proporcionar los archivos de tu app en esta IU y permitir que otras apps los abran, debes implementar un DocumentsProvider y, luego, incluir un filtro de intents para PROVIDER_INTERFACE ("android.content.action.DOCUMENTS_PROVIDER"), como se muestra en el siguiente ejemplo:

<provider ...
    android:grantUriPermissions="true"
    android:exported="true"
    android:permission="android.permission.MANAGE_DOCUMENTS">
    <intent-filter>
        <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
    </intent-filter>
</provider>

Para obtener más información sobre cómo hacer que los archivos que administra tu app se puedan abrir desde otras apps, consulta Cómo abrir archivos con el marco de trabajo de acceso al almacenamiento.

Acciones locales

Llamar a un automóvil es una acción local común. Crea un filtro de intents para anunciar la capacidad de tu app de realizar esta acción con la información de la siguiente sección.

Llamar un taxi

Google Voice Actions

  • "Consígueme un taxi".
  • "Pídeme un auto".

(Solo Wear OS)

Para llamar un taxi, usa la acción ACTION_RESERVE_TAXI_RESERVATION.

Nota: Las apps deben solicitar la confirmación del usuario antes de completar esta acción.

Acción
ACTION_RESERVE_TAXI_RESERVATION
URI de datos
Ninguno
Tipo de MIME
Ninguno
Adicional
Ninguno

Ejemplo de intención:

Kotlin

fun callCar() {
    val intent = Intent(ReserveIntents.ACTION_RESERVE_TAXI_RESERVATION)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void callCar() {
    Intent intent = new Intent(ReserveIntents.ACTION_RESERVE_TAXI_RESERVATION);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="com.google.android.gms.actions.RESERVE_TAXI_RESERVATION" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Maps

Mostrar una ubicación en un mapa es una acción común en las apps de mapas. Crea un filtro de intents para anunciar la capacidad de tu app de realizar esta acción con la información de la siguiente sección.

Mostrar una ubicación en un mapa

Para abrir un mapa, usa la acción ACTION_VIEW y especifica la información de ubicación en los datos de la intención con uno de los siguientes esquemas.

Acción
ACTION_VIEW
Esquema de URI de datos
geo:latitude,longitude
Muestra el mapa en la longitud y latitud determinadas.

Ejemplo: "geo:47.6,-122.3"

geo:latitude,longitude?z=zoom
Muestra el mapa en la longitud y latitud determinadas con un cierto nivel de zoom. Un nivel de zoom de 1 muestra toda la Tierra, centrada en los valores de lat y lng dados. El nivel de zoom más alto (más cercano) es 23.

Ejemplo: "geo:47.6,-122.3?z=11"

geo:0,0?q=lat,lng(label)
Muestra el mapa en la longitud y latitud determinadas con una etiqueta de cadena.

Ejemplo: "geo:0,0?q=34.99,-106.61(Treasure)"

geo:0,0?q=my+street+address
Mostrar la ubicación de "mi dirección", que puede ser una dirección específica o una búsqueda de ubicación

Ejemplo: "geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA"

Nota: Todas las cadenas que se pasan en el URI geo deben estar codificadas. Por ejemplo, la cadena 1st & Pike, Seattle se convierte en 1st%20%26%20Pike%2C%20Seattle. Los espacios de la cadena se codifican con %20 o se reemplazan con el signo más (+).

Tipo de MIME
Ninguno

Ejemplo de intención:

Kotlin

fun showMap(geoLocation: Uri) {
    val intent = Intent(Intent.ACTION_VIEW).apply {
        data = geoLocation
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void showMap(Uri geoLocation) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(geoLocation);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="geo" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Música o video

A continuación, se indican las acciones comunes para las apps de música y video, incluida la información que necesitas para crear un filtro de intents y anunciar la capacidad de tu app para realizar cada acción.

Reproducir un archivo multimedia

Para reproducir un archivo de música, usa la acción ACTION_VIEW y especifica la ubicación del URI del archivo en los datos del intent.

Acción
ACTION_VIEW
Esquema de URI de datos
file:<URI>
content:<URI>
http:<URL>
Tipo de MIME
"audio/*"
"application/ogg"
"application/x-ogg"
"application/itunes"
O cualquier otro que requiera tu app.

Ejemplo de intención:

Kotlin

fun playMedia(file: Uri) {
    val intent = Intent(Intent.ACTION_VIEW).apply {
        data = file
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void playMedia(Uri file) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(file);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:type="audio/*" />
        <data android:type="application/ogg" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Reproducir música según una consulta de búsqueda

Google Voice Actions

  • "Reproduce Billie Jean de Michael Jackson".

Para reproducir música según una búsqueda, usa el intent INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH. Una app puede activar este intent en respuesta al comando por voz del usuario para reproducir música. La app receptora de este intent realiza una búsqueda en su inventario para encontrar contenido existente que coincida con la búsqueda determinada y comienza a reproducir ese contenido.

En este intent, incluye el elemento adicional de cadena EXTRA_MEDIA_FOCUS, que especifica el modo de búsqueda previsto. Por ejemplo, el modo de búsqueda puede especificar si la búsqueda es por el nombre de un artista o el nombre de una canción.

Acción
INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
Esquema de URI de datos
Ninguno
Tipo de MIME
Ninguno
Adicional
MediaStore.EXTRA_MEDIA_FOCUS (obligatorio)

Indica el modo de búsqueda: si el usuario busca un artista, un álbum, una canción o una playlist en particular. La mayoría de los modos de búsqueda requieren extras adicionales. Por ejemplo, si el usuario quiere escuchar una canción en particular, el intent podría tener tres elementos adicionales: el título de la canción, el artista y el álbum. Esta intención admite los siguientes modos de búsqueda para cada valor de EXTRA_MEDIA_FOCUS:

Cualquiera: "vnd.android.cursor.item/*"

Reproducir cualquier canción. La app receptora reproduce música según una elección inteligente, como la última playlist que escuchó el usuario.

Extras adicionales:

  • QUERY (obligatorio): Una cadena vacía. Este elemento adicional siempre se proporciona para garantizar la retrocompatibilidad. Las apps existentes que no conocen los modos de búsqueda pueden procesar este intent como una búsqueda no estructurada.

Sin estructurar: "vnd.android.cursor.item/*"

Reproducir una canción, un álbum o un género en particular a partir de una búsqueda no estructurada Las apps pueden generar un intent con este modo de búsqueda cuando no pueden identificar el tipo de contenido que el usuario quiere escuchar. Cuando sea posible, usa modos de búsqueda más específicos.

Extras adicionales:

  • QUERY (obligatorio): Es una cadena que contiene cualquier combinación del artista, el álbum, el nombre de la canción o el género.

Género:Audio.Genres.ENTRY_CONTENT_TYPE

Reproducir música de un género en particular.

Extras adicionales:

  • "android.intent.extra.genre" (obligatorio): Es el género.
  • QUERY (obligatorio): Es el género. Este elemento adicional siempre se proporciona para garantizar la retrocompatibilidad. Las apps existentes que no conocen los modos de búsqueda pueden procesar este intent como una búsqueda no estructurada.

Artista: Audio.Artists.ENTRY_CONTENT_TYPE

Reproducir música de un artista en particular.

Extras adicionales:

  • EXTRA_MEDIA_ARTIST (obligatorio): Es el artista.
  • "android.intent.extra.genre": Es el género.
  • QUERY (obligatorio): Es una cadena que contiene cualquier combinación del artista o el género. Este elemento adicional siempre se proporciona para la retrocompatibilidad. Las apps existentes que no conocen los modos de búsqueda pueden procesar este intent como una búsqueda no estructurada.

Álbum: Audio.Albums.ENTRY_CONTENT_TYPE

Reproducir música de un álbum en particular.

Extras adicionales:

  • EXTRA_MEDIA_ALBUM (obligatorio): El álbum.
  • EXTRA_MEDIA_ARTIST: El artista.
  • "android.intent.extra.genre": Es el género.
  • QUERY (obligatorio): Es una cadena que contiene cualquier combinación del álbum o el artista. Este elemento adicional siempre se proporciona para la retrocompatibilidad. Las apps existentes que no conocen los modos de búsqueda pueden procesar este intent como una búsqueda no estructurada.

Canción: "vnd.android.cursor.item/audio"

Reproducir una canción en particular.

Extras adicionales:

  • EXTRA_MEDIA_ALBUM: El álbum.
  • EXTRA_MEDIA_ARTIST: El artista.
  • "android.intent.extra.genre": Es el género.
  • EXTRA_MEDIA_TITLE (obligatorio): Es el nombre de la canción.
  • QUERY (obligatorio): Es una cadena que contiene cualquier combinación del álbum, el artista, el género o el título. Este objeto adicional siempre se proporciona para la retrocompatibilidad. Las apps existentes que no conocen los modos de búsqueda pueden procesar este intent como una búsqueda no estructurada.

Playlist: Audio.Playlists.ENTRY_CONTENT_TYPE

Reproducir una playlist en particular o una que coincida con algunos criterios especificados por extras adicionales

Extras adicionales:

  • EXTRA_MEDIA_ALBUM: El álbum.
  • EXTRA_MEDIA_ARTIST: El artista.
  • "android.intent.extra.genre": Es el género.
  • "android.intent.extra.playlist": Es la playlist.
  • EXTRA_MEDIA_TITLE: Es el nombre de la canción en la que se basa la playlist.
  • QUERY (obligatorio): Es una cadena que contiene cualquier combinación del álbum, el artista, el género, la playlist o el título. Este elemento adicional siempre se proporciona para garantizar la retrocompatibilidad. Las apps existentes que no conocen los modos de búsqueda pueden procesar este intent como una búsqueda no estructurada.

Ejemplo de intención:

Si el usuario quiere escuchar música de un artista en particular, una app de búsqueda podría generar el siguiente intent:

Kotlin

fun playSearchArtist(artist: String) {
    val intent = Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH).apply {
        putExtra(MediaStore.EXTRA_MEDIA_FOCUS, MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE)
        putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist)
        putExtra(SearchManager.QUERY, artist)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void playSearchArtist(String artist) {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH);
    intent.putExtra(MediaStore.EXTRA_MEDIA_FOCUS,
                    MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE);
    intent.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist);
    intent.putExtra(SearchManager.QUERY, artist);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

Cuando administres este intent en tu actividad, verifica el valor del elemento adicional EXTRA_MEDIA_FOCUS en el Intent entrante para determinar el modo de búsqueda. Una vez que tu actividad haya identificado el modo de búsqueda, lee los valores de los elementos adicionales para ese modo de búsqueda en particular. Con esta información, tu app puede realizar la búsqueda en su inventario para reproducir el contenido que coincida con la búsqueda. Esto se muestra en el siguiente ejemplo.

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    if (intent.action.compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) {

        val mediaFocus: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS)
        val query: String? = intent.getStringExtra(SearchManager.QUERY)

        // Some of these extras might not be available depending on the search mode.
        val album: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM)
        val artist: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST)
        val genre: String? = intent.getStringExtra("android.intent.extra.genre")
        val playlist: String? = intent.getStringExtra("android.intent.extra.playlist")
        val title: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE)

        // Determine the search mode and use the corresponding extras.
        when {
            mediaFocus == null -> {
                // 'Unstructured' search mode (backward compatible)
                playUnstructuredSearch(query)
            }
            mediaFocus.compareTo("vnd.android.cursor.item/*") == 0 -> {
                if (query?.isNotEmpty() == true) {
                    // 'Unstructured' search mode.
                    playUnstructuredSearch(query)
                } else {
                    // 'Any' search mode.
                    playResumeLastPlaylist()
                }
            }
            mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Genre' search mode.
                playGenre(genre)
            }
            mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Artist' search mode.
                playArtist(artist, genre)
            }
            mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Album' search mode.
                playAlbum(album, artist)
            }
            mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0 -> {
                // 'Song' search mode.
                playSong(album, artist, genre, title)
            }
            mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Playlist' search mode.
                playPlaylist(album, artist, genre, playlist, title)
            }
        }
    }
}

Java

protected void onCreate(Bundle savedInstanceState) {
    //...
    Intent intent = this.getIntent();
    if (intent.getAction().compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) {

        String mediaFocus = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS);
        String query = intent.getStringExtra(SearchManager.QUERY);

        // Some of these extras might not be available depending on the search mode.
        String album = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM);
        String artist = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST);
        String genre = intent.getStringExtra("android.intent.extra.genre");
        String playlist = intent.getStringExtra("android.intent.extra.playlist");
        String title = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE);

        // Determine the search mode and use the corresponding extras.
        if (mediaFocus == null) {
            // 'Unstructured' search mode (backward compatible).
            playUnstructuredSearch(query);

        } else if (mediaFocus.compareTo("vnd.android.cursor.item/*") == 0) {
            if (query.isEmpty()) {
                // 'Any' search mode.
                playResumeLastPlaylist();
            } else {
                // 'Unstructured' search mode.
                playUnstructuredSearch(query);
            }

        } else if (mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0) {
            // 'Genre' search mode.
            playGenre(genre);

        } else if (mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0) {
            // 'Artist' search mode.
            playArtist(artist, genre);

        } else if (mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0) {
            // 'Album' search mode.
            playAlbum(album, artist);

        } else if (mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0) {
            // 'Song' search mode.
            playSong(album, artist, genre, title);

        } else if (mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0) {
            // 'Playlist' search mode.
            playPlaylist(album, artist, genre, playlist, title);
        }
    }
}

Nueva nota

Crear una nota es una acción común en las apps para tomar notas. Crea un filtro de intents para anunciar la capacidad de tu app de realizar esta acción con la información de la siguiente sección.

Cómo crear una nota

Para crear una nota nueva, usa la acción ACTION_CREATE_NOTE y especifica los detalles de la nota, como el asunto y el texto, con los siguientes elementos adicionales.

Nota: Las apps deben solicitar la confirmación del usuario antes de completar esta acción.

Acción
ACTION_CREATE_NOTE
Esquema de URI de datos
Ninguno
Tipo de MIME
PLAIN_TEXT_TYPE
"*/*"
Adicional
EXTRA_NAME
Cadena que indica el título o el asunto de la nota.
EXTRA_TEXT
Es una cadena que indica el texto de la nota.

Ejemplo de intención:

Kotlin

fun createNote(subject: String, text: String) {
    val intent = Intent(NoteIntents.ACTION_CREATE_NOTE).apply {
        putExtra(NoteIntents.EXTRA_NAME, subject)
        putExtra(NoteIntents.EXTRA_TEXT, text)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void createNote(String subject, String text) {
    Intent intent = new Intent(NoteIntents.ACTION_CREATE_NOTE)
            .putExtra(NoteIntents.EXTRA_NAME, subject)
            .putExtra(NoteIntents.EXTRA_TEXT, text);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="com.google.android.gms.actions.CREATE_NOTE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="*/*" />
    </intent-filter>
</activity>

Teléfono

Iniciar una llamada es una acción común para las apps de teléfono. Crea un filtro de intents para anunciar la capacidad de tu app de realizar esta acción con la información de la siguiente sección.

Iniciar una llamada telefónica

Para abrir la app de teléfono y marcar un número, usa la acción ACTION_DIAL y especifica un número de teléfono con el siguiente esquema de URI. Cuando se abre la app de teléfono, se muestra el número de teléfono y el usuario debe presionar el botón Llamar para iniciar la llamada.

Google Voice Actions

  • "Llama al 555-5555".
  • "Llama a Roberto".
  • "Llamar al buzón de voz"

Para realizar una llamada telefónica directamente, usa la acción ACTION_CALL y especifica un número de teléfono con el siguiente esquema de URI. Cuando se abre la app de Teléfono, comienza la llamada. El usuario no necesita presionar el botón Llamar.

La acción ACTION_CALL requiere que agregues el permiso CALL_PHONE a tu archivo de manifiesto:

<uses-permission android:name="android.permission.CALL_PHONE" />
Acción
  • ACTION_DIAL: Abre la app de Teléfono o el marcador.
  • ACTION_CALL: Realiza una llamada telefónica (requiere el permiso CALL_PHONE).
Esquema de URI de datos
  • tel:<phone-number>
  • voicemail:<phone-number>
Tipo de MIME
Ninguno

Los números de teléfono válidos son los que se definen en IETF RFC 3966. Algunos ejemplos válidos son los siguientes:

  • tel:2125551212
  • tel:(212) 555 1212

El marcador de la app de Teléfono es bueno para normalizar esquemas, como números de teléfono. Por lo tanto, el esquema descrito no es estrictamente necesario en el método Uri.parse(). Sin embargo, si no probaste un esquema o no sabes con certeza si se puede manejar, usa el método Uri.fromParts().

Ejemplo de intención:

Kotlin

fun dialPhoneNumber(phoneNumber: String) {
    val intent = Intent(Intent.ACTION_DIAL).apply {
        data = Uri.parse("tel:$phoneNumber")
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void dialPhoneNumber(String phoneNumber) {
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setData(Uri.parse("tel:" + phoneNumber));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

A continuación, se indican las acciones comunes para las apps de búsqueda, incluida la información que necesitas para crear un filtro de intents y anunciar la capacidad de tu app para realizar cada acción.

Buscar usando una aplicación específica

Google Voice Actions

  • "Busca videos de gatos en mi app de videos".

Para admitir la búsqueda en el contexto de tu app, declara un filtro de intents en tu app con la acción SEARCH_ACTION, como se muestra en el siguiente ejemplo de filtro de intents.

Nota: No recomendamos usar SEARCH_ACTION para la búsqueda en la app. En cambio, implementa la acción GET_THING para aprovechar la compatibilidad integrada del Asistente de Google con la búsqueda en la app. Para obtener más información, consulta la documentación de las acciones de la app del Asistente de Google.

Acción
"com.google.android.gms.actions.SEARCH_ACTION"
Admite búsquedas de Acciones de voz de Google.
Adicional
QUERY
Es una cadena que contiene la búsqueda.

Ejemplo de filtro de intents:

<activity android:name=".SearchActivity">
    <intent-filter>
        <action android:name="com.google.android.gms.actions.SEARCH_ACTION"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

Realizar una búsqueda web

Para iniciar una búsqueda web, usa la acción ACTION_WEB_SEARCH y especifica la cadena de búsqueda en el elemento adicional SearchManager.QUERY.

Acción
ACTION_WEB_SEARCH
Esquema de URI de datos
Ninguno
Tipo de MIME
Ninguno
Adicional
SearchManager.QUERY
Es la cadena de búsqueda.

Ejemplo de intención:

Kotlin

fun searchWeb(query: String) {
    val intent = Intent(Intent.ACTION_WEB_SEARCH).apply {
        putExtra(SearchManager.QUERY, query)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void searchWeb(String query) {
    Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
    intent.putExtra(SearchManager.QUERY, query);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Configuración

Para abrir una pantalla en la app de Configuración del sistema cuando tu app requiera que el usuario cambie algo, usa una de las siguientes acciones de intent:

Acción
ACTION_SETTINGS
ACTION_WIRELESS_SETTINGS
ACTION_AIRPLANE_MODE_SETTINGS
ACTION_WIFI_SETTINGS
ACTION_APN_SETTINGS
ACTION_BLUETOOTH_SETTINGS
ACTION_DATE_SETTINGS
ACTION_LOCALE_SETTINGS
ACTION_INPUT_METHOD_SETTINGS
ACTION_DISPLAY_SETTINGS
ACTION_SECURITY_SETTINGS
ACTION_LOCATION_SOURCE_SETTINGS
ACTION_INTERNAL_STORAGE_SETTINGS
ACTION_MEMORY_CARD_SETTINGS

Para ver otras pantallas de configuración disponibles, consulta la documentación de Settings .

Esquema de URI de datos
Ninguno
Tipo de MIME
Ninguno

Ejemplo de intención:

Kotlin

fun openWifiSettings() {
    val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void openWifiSettings() {
    Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Mensajes de texto

Redactar un mensaje SMS o MMS con un archivo adjunto es una acción común para las apps de mensajería de texto. Crea un filtro de intents para anunciar la capacidad de tu app de realizar esta acción con la información de la siguiente sección.

Redactar un mensaje SMS o MMS con archivos adjuntos

Para iniciar un mensaje de texto SMS o MMS, usa una de las siguientes acciones de intent y especifica los detalles del mensaje, como el número de teléfono, el asunto y el cuerpo del mensaje, con las siguientes claves adicionales.

Acción
ACTION_SENDTO o
ACTION_SEND o
ACTION_SEND_MULTIPLE
Esquema de URI de datos
sms:<phone_number>
smsto:<phone_number>
mms:<phone_number>
mmsto:<phone_number>

Todos estos esquemas se controlan de la misma manera.

Tipo de MIME
"text/plain"
"image/*"
"video/*"
Adicional
"subject"
Es una cadena para el asunto del mensaje (generalmente solo para MMS).
"sms_body"
Es una cadena para el mensaje de texto.
EXTRA_STREAM
Un Uri que apunta a la imagen o el video que se adjuntará. Si se usa la acción ACTION_SEND_MULTIPLE, este extra es un ArrayList de objetos Uri que apuntan a las imágenes o los videos que se adjuntarán.

Ejemplo de intención:

Kotlin

fun composeMmsMessage(message: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SENDTO).apply {
        type = HTTP.PLAIN_TEXT_TYPE
        putExtra("sms_body", message)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setType(HTTP.PLAIN_TEXT_TYPE);
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Si quieres asegurarte de que tu intención solo la controle una app de mensajería de texto y no otras apps de correo electrónico o redes sociales, usa la acción ACTION_SENDTO y, luego, incluye el esquema de datos "smsto:", como se muestra en el siguiente ejemplo:

Kotlin

fun composeMmsMessage(message: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SEND).apply {
        data = Uri.parse("smsto:")  // Only SMS apps respond to this.
        putExtra("sms_body", message)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setData(Uri.parse("smsto:"));  // Only SMS apps respond to this.
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Ejemplo de filtro de intents:

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

Nota: Si desarrollas una app de mensajería SMS/MMS, debes implementar filtros de intents para varias acciones adicionales para que esté disponible como la app de SMS predeterminada en Android 4.4 y versiones posteriores. Para obtener más información, consulta la documentación en Telephony.

Navegador web

Cargar una URL web es una acción común para las apps de navegador web. Crea un filtro de intents para anunciar la capacidad de tu app de realizar esta acción con la información de la siguiente sección.

Cargar una URL web

Google Voice Actions

  • "Abre example.com".

Para abrir una página web, usa la acción ACTION_VIEW y especifica la URL web en los datos del intent.

Acción
ACTION_VIEW
Esquema de URI de datos
http:<URL>
https:<URL>
Tipo de MIME
"text/plain"
"text/html"
"application/xhtml+xml"
"application/vnd.wap.xhtml+xml"

Ejemplo de intención:

Kotlin

fun openWebPage(url: String) {
    val webpage: Uri = Uri.parse(url)
    val intent = Intent(Intent.ACTION_VIEW, webpage)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void openWebPage(String url) {
    Uri webpage = Uri.parse(url);
    Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Ejemplo de filtro de intents:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <!-- Include the host attribute if you want your app to respond
             only to URLs with your app's domain. -->
        <data android:scheme="http" android:host="www.example.com" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- The BROWSABLE category is required to get links from web pages. -->
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>

Sugerencia: Si tu app para Android proporciona una funcionalidad similar a la de tu sitio web, incluye un filtro de intents para las URLs que dirijan a tu sitio web. Luego, si los usuarios tienen instalada tu aplicación, los vínculos de correos electrónicos o de otras páginas web que dirijan a tu sitio web abrirán tu aplicación para Android en lugar de tu página web. Obtén más información en Cómo controlar Android App Links.

A partir de Android 12 (nivel de API 31), un intent web genérico se resuelve en una actividad de la app solo si esta se aprobó para el dominio específico que se incluye en ese intent web. Si no se aprueba la app para el dominio, el intent web se resuelve en la app predeterminada del navegador del usuario.

Verifica intents con Android Debug Bridge

Para verificar que tu app responda a los intents que deseas admitir, puedes usar la herramienta adb para activar intents específicos de la siguiente manera:

  1. Configura un dispositivo Android para el desarrollo o usa un dispositivo virtual.
  2. Instala una versión de tu app que maneje las intents que quieres admitir.
  3. Activa un intent con adb:
    adb shell am start -a <ACTION> -t <MIME_TYPE> -d <DATA> \
      -e <EXTRA_NAME> <EXTRA_VALUE> -n <ACTIVITY>
    

    Por ejemplo:

    adb shell am start -a android.intent.action.DIAL \
      -d tel:555-5555 -n org.example.MyApp/.MyActivity
    
  4. Si defines los filtros de intents requeridos, controla el intent.

Para obtener más información, consulta Cómo emitir comandos del shell.