Una delle funzionalità più importanti di Android è la possibilità di un'app di indirizzare l'utente a un'altra app
in base a un'"azione" che desidera eseguire. Ad esempio, se
la tua app abbia l'indirizzo di un'attività che vuoi mostrare su una mappa, non devi creare
un'attività nella tua app che mostra una mappa. Puoi invece creare una richiesta per visualizzare l'indirizzo
utilizzando un Intent
. Il sistema Android avvia quindi un'app in grado di mostrare
l'indirizzo su una mappa.
Come spiegato nella prima lezione, Creare La tua prima app, devi utilizzare gli intent per navigare tra le attività all'interno dell'app. Tu generalmente mediante un intent esplicito, che definisce il nome esatto della classe che vuoi avviare. Se però vuoi che un'app separata esegua un'azione, come come "visualizza una mappa" devi utilizzare un intent implicito.
Questa lezione mostra come creare un intent implicito per una determinata azione e come utilizzarlo per avviare un'attività che esegue l'azione in un'altra app. Vedi anche il video incorporato qui per capire perché è importante includere controlli di runtime per gli intent impliciti.
Costruire un intent implicito
Gli intent impliciti non dichiarano il nome della classe del componente per iniziare, ma dichiarano un dell'azione da eseguire. L'azione specifica l'operazione che vuoi eseguire, ad esempio view, edit, send (invia) o get qualcosa.
Associare le azioni intent ai dati
Gli intent includono spesso anche dati associati
con l'azione, ad esempio l'indirizzo che vuoi visualizzare o il messaggio email che vuoi inviare.
A seconda dell'intento che vuoi creare, i dati potrebbero essere Uri
,
uno dei numerosi altri tipi di dati, oppure l'intento potrebbe non aver bisogno di dati.
Se i dati sono di tipo Uri
, puoi utilizzare un semplice costruttore Intent()
per definire l'azione e
e i dati di Google Cloud.
Ad esempio, ecco come creare un intent per avviare una telefonata utilizzando i dati di Uri
per specificare il numero di telefono:
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 la tua app richiama questo intent chiamando il numero startActivity()
, l'app Telefono avvia una chiamata al numero di telefono specificato.
Ecco un paio di altri intent con le relative azioni e i dati di Uri
coppie:
Visualizzare una mappa
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);
Visualizzare una pagina 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);
Aggiungere extra a un intent
Altri tipi di intent impliciti richiedono "extra" che forniscono tipi di dati diversi,
come una stringa. Puoi aggiungere uno o più dati aggiuntivi utilizzando i vari metodi di putExtra()
.
Per impostazione predefinita, il sistema determina il tipo MIME appropriato richiesto da un intent in base al
Uri
di dati inclusi. Se non includi un valore Uri
nei
intent, in genere dovresti usare setType()
per specificare il tipo
di dati associati all'intento. L'impostazione del tipo MIME specifica ulteriormente i tipi di
devono ricevere l'intento.
Di seguito sono riportati alcuni intent che aggiungono ulteriori dati per specificare l'azione desiderata:
Inviare un'email con un allegato
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
Creare un evento nel calendario
Nota: questo intent per un evento di calendario è supportato solo con l'API livello 14 e livelli successivi.
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");
Nota: è importante definire Intent
in modo che sia il più specifico possibile. Ad esempio, se vuoi visualizzare un'immagine
utilizzando l'intent ACTION_VIEW
, devi specificare un tipo MIME
image/*
. In questo modo le app che possono "visualizzare" altri tipi di dati (come un'app di mappe)
attivati dall'intento.
Avviare un'attività con l'intento
Dopo aver creato Intent
e aver impostato le informazioni aggiuntive, chiama startActivity()
per inviarle al sistema:
Kotlin
startActivity(intent)
Java
startActivity(intent);
Gestisci la situazione in cui nessuna app può ricevere un intent
Anche se molti intent vengono gestiti correttamente da un'altra app installata
sul dispositivo, ad esempio un'app di smartphone, email o calendario, l'app dovrebbe essere predisposta
nei casi in cui nessuna attività possa gestire l'intenzione dell'app. Ogni volta che
richiamare un intent, essere pronti a rilevare
ActivityNotFoundException
,
che si verifica se non ci sono altre attività in grado di gestire l'intento della tua 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. }
Dopo aver individuato l'eccezione, decidi cosa deve fare la tua app. Questo prossimo dipende dalle caratteristiche specifiche dell'intenzione che hai provato a richiamare. Ad esempio, se conosci un'app specifica in grado di gestire l'intent, fornire all'utente un link per scaricare l'app. Scopri di più su come eseguire il collegamento al prodotto su Google Play.
Finestra di dialogo di disambiguazione
Se il sistema identifica più attività in grado di gestire l'intento, visualizza una finestra di dialogo (anche nota come "finestra di disambiguazione") per all'utente di selezionare l'app da utilizzare, come mostrato nella figura 1. Se è presente un solo elemento dell'attività che gestisce l'intent, il sistema la avvia immediatamente.
![Viene visualizzato un riquadro
nella parte inferiore dello schermo. Questo riquadro elenca le diverse app che possono
gestire l'intento.](https://developer.android.com/static/images/training/basics/intents-choice.png?authuser=0000&hl=it)
Figura 1. Esempio della selezione che viene visualizzata quando più app sono in grado di gestire un intent.
Esempio completo
Ecco un esempio completo che mostra come creare un intent per visualizzare una mappa, verificare che dell'app esiste per gestire l'intent, quindi avviala:
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. }
Mostra un selettore di app
![](https://developer.android.com/static/images/training/basics/intent-chooser.png?authuser=0000&hl=it)
Figura 2. Una finestra di dialogo di selezione.
Tieni presente che quando inizi un'attività passando Intent
a startActivity()
e sono presenti più app che rispondono
l'intent, l'utente può selezionare l'app da utilizzare per impostazione predefinita (selezionando una casella di controllo in basso
della finestra di dialogo; vedi figura 1). È utile quando si esegue un'azione per la quale l'utente
in genere vuole utilizzare la stessa app ogni volta, ad esempio quando apre una pagina web (gli utenti
probabilmente usano un solo browser web) o per scattare una foto (gli utenti probabilmente preferiscono una sola fotocamera).
Tuttavia, se l'azione da eseguire potrebbe essere gestita da più app e l'utente potrebbe preferiscono un'app diversa ogni volta, ad esempio una condivisione per la quale gli utenti potrebbero avere diverse app con cui potrebbero condividere un elemento; devi mostrare esplicitamente una finestra di dialogo di selezione come mostrato nella Figura 2. La finestra di dialogo del selettore obbliga l'utente a selezionare ogni volta quale app utilizzare per l'azione (l'utente non può selezionare un app predefinita per l'azione).
Per mostrare il selettore, crea un Intent
utilizzando createChooser()
e passalo a startActivity()
. Ad esempio:
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. }
Viene visualizzata una finestra di dialogo con un elenco di app che rispondono all'intent passato
al metodo
createChooser()
. Il parametro title
può essere
specificato se l'azione non è
ACTION_SEND
o
ACTION_SEND_MULTIPLE