X

Trasladar al Usuario a otra App

Una de las características más importantes de Android es la capacidad de las apps de poder trasladar al usuario a otra app basándose en una “acción” que quiere realizar. Por ejemplo, si tu app tiene la dirección de un negocio que te gustaría mostrar en un mapa, no necesitas crear una actividad dentro de tu app que muestre un mapa. En su lugar, puedes crear una petición para ver dicha dirección en otra app mediante un Intent. El sistema Android inicia en ese momento la app que es capaz de mostrar la dirección en un mapa.

Como se explico en la primera lección, Crear tu Primera App, debes utilizar las intenciones para navegar entre actividades dentro de tu propia app. Generalmente se utilizan intenciones explícitas, las cuales definen el nombre exacto de la clase del componente que quieres iniciar. Sin embargo, cuando quieres utilizar una app que no es la tuya para realizar una acción, como “mostrar un mapa”, necesitas utilizar intenciones implícitas.

Esta lección te muestra como crear una intención implícita para una acción en particular, y como utilizarla para iniciar una actividad que realizará dicha acción en otra app.

Crear Implicit Intent

Las intenciones implícitas no declaran el nombre de la clase del componente a iniciar, en su lugar declaran una acción a realizar. Ésta especifica que quieres hacer, como puede ser ver, editar, enviarconseguir algo. Las intenciones a menudo también incluyen datos asociados a dicha acción, como puede ser la dirección que quieres ver, o el mensaje de email que quieres enviar. Dependiendo de la intención que quieres crear, los datos pueden ser Uri, uno de los múltiples tipos de datos existentes, o la intención directamente puede no tener ningún dato asociado.

Si tus datos son Uri, hay un constructor simple, Intent(), que puedes utilizar para definir la acción y los datos.

Por ejemplo, así puedes crear una intención para iniciar una llamada de teléfono utilizando datos Uri para especificar el número de teléfono:

Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);

Cuando tu app realiza esta intención mediante startActivity(), la app Teléfono iniciará una llamada utilizando el número de teléfono proporcionado.

A continuación puedes ver otras intenciones y sus respectivas parejas acción-datos Uri.

  • Ver un mapa:
// Map point based on address
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
// Or map point based on latitude/longitude
// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
  • Ver una web:
Uri webpage = Uri.parse("http://www.android.com");
Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);

Otros tipos de intenciones implícitas requieres datos “extra” que proporcionan diferentes tipos de datos, como puede ser un string. Puedes añadir más piezas de datos extra utilizando varios métodos putExtra().

Por defecto, el sistema determina el tipo MIME apropiado mediante una intención basada en datos Uri que están incluidos. Si no quieres incluir datos Uri en la intención, deberías utilizar setType() para especificar el tipo de datos asociado a dicha intención. Ajustar el tipo MIME sirve para especificar que tipo de actividades deberían recibir la intención.

Estos son algunas intenciones que añaden datos extra para especificar la acción deseada:

  • Enviar un email con un adjunto:
Intent emailIntent = new Intent(Intent.ACTION_SEND);
// The intent does not have a URI, so declare the "text/plain" MIME type
emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
// You can also attach multiple items by passing an ArrayList of Uris
  • Crear un evento en el calendario:
Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
calendarIntent.putExtra(Events.TITLE, "Ninja class");
calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");

Nota: Esta intención del evento de calendario solo se soporta en niveles de API 14 o más.

Nota: Es importante que definas tu Intent tan específico como sea posible. Por ejemplo, si quieres mostrar una imagen utilizando la intención ACTION_VIEW, deberías especificar el tipo MIME de /image*. Esto previene que apps que puedan “ver” otros tipos de datos (como una app de mapas) sean activadas mediante esta intención.

Verificar que haya una app que reciba la intención

Aunque la plataforma Android garantice que ciertas intenciones se resolverán con algunas de las apps que vienen con el sistema (como puede ser Teléfono, Email o Calendario), deberías incluir un paso de verificación antes de realizar la intención.

Precaución: Si realizas una intención y no hay una app disponible en el dispositivo que pueda gestionarla, tu aplicación forzará su cierre.

Para verificar que hay una actividad disponible que pueda gestionar dicha intención, utiliza queryIntentActivities() para conseguir una lista de actividades que son capaces de manipular tu Intent. Si la List devuelta no se encuentra vacía, puedes utilizar de forma segura la intención. Por ejemplo:

PackageManager packageManager = getPackageManager();
List activities = packageManager.queryIntentActivities(intent,
        PackageManager.MATCH_DEFAULT_ONLY);
boolean isIntentSafe = activities.size() > 0;

Si IsIntentSafe es true, entonces al menos una app responderá a la intención. Si es false, significa que no hay ninguna app capaz de gestionar la intención.

Nota: Deberías realizar esta comprobación cuando tu actividad se inicie en caso de que necesites deshabilitar la característica que utiliza la intención antes de que el usuario pretenda utilizarla. Si sabes de una app específica que pueda gestionar la intención, puedes proporcionar un enlace al usuario para que la descargue (vincular tu producto en Google Play

Iniciar una Actividad con la Intención

Una vez has creado tu Intent y colocado la información extra, utiliza startActivity() para enviarla al sistema. Si este es capaz de identificar más de una actividad capaz de gestionar la intención, se mostrará un dialogo para que el usuario seleccione que app quiere usar, como se muestra en la figura 1. Si solo hay una actividad que pueda manipularla, el sistema iniciará dicha app inmediatamente.

Este es un ejemplo completo de como crear una intención para ver un mapa, verificar que una app existe para gestionar la intención, e iniciarla:

// Build the intent
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);

// Verify it resolves
PackageManager packageManager = getPackageManager();
List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
boolean isIntentSafe = activities.size() > 0;

// Start an activity if it's safe
if (isIntentSafe) {
    startActivity(mapIntent);
}

Figura 1. Ejemplo de un diálogo de selección que aparece cuando hay más de una app capaz de gestionar la intención

Mostrar un Selector

Fíjate que cuando inicias una actividad mediante tu Intent usando startActivity() y hay más de una app que responda a la intención, el usuario puede seleccionar que aplicación quiere utilizar por defecto. Es fantástico para aquellos que realizan siempre dicha acción con la misma app, como puede ser abrir una página web en un navegador determinado o tomar una foto siempre con la misma app de cámara.

Sin embargo, si la acción realizada puede ser gestionada por muchas apps y el usuario quiere utilizar una app diferente cada vez, como puede ser la acción “compartir”, deberías mostrar de forma explícita un diálogo selector como se puede ver en la figura 2. Este diálogo fuerza al usuario a seleccionar que app quiere utilizar cada vez, no permite seleccionar una app por defecto.

Para mostrar un selector, crea un Intent utilizando createChooser() y pásaselo a startActivity(). Por ejemplo:

Intent intent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show chooser
Intent chooser = Intent.createChooser(intent, title);

// Verify the intent will resolve to at least one activity
if (intent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

Este código muestra un diálogo con una lista de aplicaciones capaces de responder a la intención pasada al método createChooser() y utilizar el texto suministrado como título del diálogo.

Figura 2. Diálogo Selector de Apps.

Puedes ver más información sobre Trasladar al Usuario a otra App en la página oficial de Google en inglés pulsando aquí.

Los comentarios de Disqus están cargando....