Um dos recursos mais importantes do Android é a capacidade do app de direcionar o usuário para outro app com base em uma “ação” que ele gostaria de realizar. Por exemplo, caso seu app tenha o endereço de uma empresa que você gostaria de mostrar em um mapa, não será necessário criar uma atividade no seu app que mostre um mapa. Em vez disso, é possível criar uma solicitação para exibir o endereço usando uma Intent
. O sistema Android inicia um app capaz de mostrar o endereço em um mapa.
Como explicado na primeira lição, Como criar seu primeiro app, use intents para navegar entre atividades no próprio app. Em geral, isso é feito com intents explícitas, que definem o nome exato da classe do componente que você quer iniciar. No entanto, quando quiser que um app separado execute uma ação, como "ver um mapa", use uma intent implícita.
Esta lição mostra como criar uma intent implícita para uma ação específica e como usá-la para iniciar uma atividade que realize a ação em outro app. Veja também o vídeo incorporado aqui para entender por que é importante incluir verificações de tempo de execução para suas intents implícitas.
Criar uma intent implícita
Intents implícitas não declaram o nome da classe do componente que será iniciado, mas sim uma ação a ser executada. A ação especifica o que precisa ser feito, como ver, editar, enviar ou receber algo.
Associar ações da intent aos dados
As intents geralmente também incluem dados associados à ação, por exemplo, o endereço que você quer ver ou a mensagem de e-mail que quer enviar.
Dependendo da intent que você quer criar, os dados podem ser um Uri
,
um dos vários outros tipos de dados, ou a intent talvez não precise de dados.
Se os dados forem um Uri
, use este construtor de Intent()
simples para definir a ação e os dados.
Este é um exemplo de como criar uma intent para iniciar uma chamada telefônica usando os dados do Uri
para especificar o número de telefone:
Kotlin
val callIntent: Intent = Uri.parse("tel:5551234").let { number -> Intent(Intent.ACTION_DIAL, number) }
Java
Uri number = Uri.parse("tel:5551234"); Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
Quando seu app invoca essa intent chamando startActivity()
, o app Telefone inicia uma chamada para o número especificado.
Estas são algumas outras intents, bem como as ações e os pares de dados Uri
delas:
Ver um mapa
Kotlin
// Map point based on address val mapIntent: Intent = Uri.parse( "geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California" ).let { location -> // Or map point based on latitude/longitude // val location: Uri = Uri.parse("geo:37.422219,-122.08364?z=14") // z param is zoom level Intent(Intent.ACTION_VIEW, location) }
Java
// 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 uma página da Web
Kotlin
val webIntent: Intent = Uri.parse("https://www.android.com").let { webpage -> Intent(Intent.ACTION_VIEW, webpage) }
Java
Uri webpage = Uri.parse("https://www.android.com"); Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
Adicionar extras a uma intent
Outros tipos de intents implícitas exigem dados "extras" que fornecem diferentes tipos de dados, como uma string. Você pode adicionar um ou mais dados extras usando vários métodos putExtra()
.
Por padrão, o sistema determina o tipo MIME adequado que uma intent exige com base nos dados de Uri
incluídos. Se você não incluir um Uri
na intent, sempre use setType()
para especificar o tipo de dado associado à intent. Definir o tipo MIME especifica melhor que tipos de atividade receberão a intent.
Estas são mais algumas intents que adicionam dados extras para especificar a ação visada:
Enviar um e-mail com um anexo
Kotlin
Intent(Intent.ACTION_SEND).apply { // The intent does not have a URI, so declare the "text/plain" MIME type type = "text/plain" putExtra(Intent.EXTRA_EMAIL, arrayOf("jan@example.com")) // recipients putExtra(Intent.EXTRA_SUBJECT, "Email subject") putExtra(Intent.EXTRA_TEXT, "Email message text") putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment")) // You can also attach multiple items by passing an ArrayList of Uris }
Java
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[] {"jan@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
Criar um evento na agenda
Observação: essa intent para evento da agenda é compatível apenas com a API de nível 14 e mais recentes.
Kotlin
// Event is on January 23, 2021 -- from 7:30 AM to 10:30 AM. Intent(Intent.ACTION_INSERT, Events.CONTENT_URI).apply { val beginTime: Calendar = Calendar.getInstance().apply { set(2021, 0, 23, 7, 30) } val endTime = Calendar.getInstance().apply { set(2021, 0, 23, 10, 30) } putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.timeInMillis) putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.timeInMillis) putExtra(Events.TITLE, "Ninja class") putExtra(Events.EVENT_LOCATION, "Secret dojo") }
Java
// Event is on January 23, 2021 -- from 7:30 AM to 10:30 AM. Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI); Calendar beginTime = Calendar.getInstance(); beginTime.set(2021, 0, 23, 7, 30); Calendar endTime = Calendar.getInstance(); endTime.set(2021, 0, 23, 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");
Observação: é importante que você defina a Intent
para ser o mais específica possível. Por exemplo, se você quiser exibir uma imagem usando a intent ACTION_VIEW
, especifique o tipo de MIME como image/*
. Isso evita que apps que podem aplicar a ação "ver" para outros tipos de dados (como um app de mapa) sejam acionados pela intent.
Iniciar uma atividade com a intent
Depois de criar sua Intent
e definir as informações extras, chame startActivity()
para enviá-la ao sistema:
Kotlin
startActivity(intent)
Java
startActivity(intent);
Lidar com a situação em que nenhum app pode receber uma intent
Embora muitas intents sejam processadas por outro app instalado
no dispositivo, como um app de telefone, e-mail ou agenda, seu app precisa estar preparado
para a situação em que nenhuma atividade possa processar a intent do app. Sempre que você
invocar uma intent, esteja pronto para capturar um
ActivityNotFoundException
,
que ocorre quando não há outra atividade que pode lidar com a intent do seu app:
Kotlin
try { startActivity(intent) } catch (e: ActivityNotFoundException) { // Define what your app should do if no activity can handle the intent. }
Java
try { startActivity(intent); } catch (ActivityNotFoundException e) { // Define what your app should do if no activity can handle the intent. }
Depois de capturar essa exceção, decida o que o app fará em seguida. A próxima etapa depende das características específicas da intent que você tentou invocar. Por exemplo, caso você conheça um app específico que processa a intent, forneça um link para que o usuário faça o download dele. Saiba mais sobre como incluir links para seu produto no Google Play.
Caixa de diálogo de desambiguação
Se o sistema identificar mais de uma atividade que possa processar a intent, uma caixa de diálogo (às vezes chamada de "caixa de diálogo de desambiguação") será exibida para que o usuário selecione qual app usar, como mostrado na Figura 1. Se existir apenas uma atividade que possa processar a intent, o sistema a iniciará imediatamente.
Exemplo completo
Este é um exemplo completo que mostra como criar uma intent para mostrar um mapa, verificar se há um app para processar a intent e iniciá-la:
Kotlin
// Build the intent. val location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California") val mapIntent = Intent(Intent.ACTION_VIEW, location) // Try to invoke the intent. try { startActivity(mapIntent) } catch (e: ActivityNotFoundException) { // Define what your app should do if no activity can handle the intent. }
Java
// 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); // Try to invoke the intent. try { startActivity(mapIntent); } catch (ActivityNotFoundException e) { // Define what your app should do if no activity can handle the intent. }
Mostrar um seletor de app
Observe que, ao iniciar uma atividade transmitindo a Intent
para startActivity()
e quando há mais de um app que responde
à intent, o usuário poderá selecionar qual app usar por padrão (marcando uma caixa de seleção na parte inferior
da caixa de diálogo, conforme mostrado na Figura 1). Isso é bom ao realizar uma ação para qual o usuário
geralmente quer usar o mesmo app todas as vezes, por exemplo, ao abrir uma página da Web (o usuário
geralmente usa apenas um navegador) ou tirar uma foto (o usuário costuma preferir uma câmera).
Contudo, se a ação a ser realizada puder ser processada por vários apps e o usuário preferir um diferente a cada vez, como a ação "compartilhar", em que os usuários podem ter vários apps para compartilhar um item, você precisará exibir explicitamente uma caixa de diálogo seletora conforme mostrado na Figura 2. A caixa de diálogo seletora força o usuário a selecionar qual app usar para a ação todas as vezes. Não é possível selecionar um app padrão para a ação.
Para mostrar o seletor, crie uma Intent
usando createChooser()
e transmita-o para startActivity()
. Exemplo:
Kotlin
val intent = Intent(Intent.ACTION_SEND) // Create intent to show chooser val chooser = Intent.createChooser(intent, /* title */ null) // Try to invoke the intent. try { startActivity(chooser) } catch (e: ActivityNotFoundException) { // Define what your app should do if no activity can handle the intent. }
Java
Intent intent = new Intent(Intent.ACTION_SEND); // Create intent to show chooser Intent chooser = Intent.createChooser(intent, /* title */ null); // Try to invoke the intent. try { startActivity(chooser); } catch (ActivityNotFoundException e) { // Define what your app should do if no activity can handle the intent. }
Isso mostra uma caixa de diálogo com uma lista de apps que respondem à intent transmitida
ao método
createChooser()
. O parâmetro title
poderá ser
fornecido se a ação não for
ACTION_SEND
ou
ACTION_SEND_MULTIPLE
.