Questo documento illustra diversi casi d'uso comuni in cui un'app interagisce con altre app. Ogni sezione fornisce indicazioni su come svolgere le funzionalità dell'app con visibilità limitata dei pacchetti, cosa che devi considerare se la tua app ha come target Android 11 (livello API 30) o versioni successive.
Quando un'app che ha come target Android 11 o versioni successive utilizza un intent per
avviare un'attività in un'altra app, l'approccio più semplice è richiamare
l'intent e gestire l'eccezione
ActivityNotFoundException
se non è disponibile nessuna app.
Se parte della tua app dipende dal sapere se la chiamata a startActivity()
può avere esito positivo, ad esempio la visualizzazione di una UI, aggiungi un elemento all'elemento <queries>
del file manifest dell'app. In genere, si tratta di un elemento <intent>
.
Apri URL
Questa sezione descrive vari modi per aprire gli URL in un'app che ha come target Android 11 o versioni successive.
Apri gli URL in un browser o in un'altra app
Per aprire un URL, utilizza un intent che contenga l'azione per intent ACTION_VIEW
, come descritto nella guida al caricamento di un URL web. Dopo aver chiamato startActivity()
utilizzando questo intent, si verifica una delle seguenti situazioni:
- L'URL si apre in un'app di browser web.
- L'URL si apre in un'app che lo supporta come link diretto.
- Viene visualizzata una finestra di dialogo di disambiguazione, che consente all'utente di scegliere quale app apre l'URL.
Un
ActivityNotFoundException
si verifica perché sul dispositivo non è installata un'app in grado di aprire l'URL. (Si tratta di una situazione insolita).È consigliabile che la tua app rilevi e gestisca
ActivityNotFoundException
se si verifica.
Poiché il metodo startActivity()
non richiede la visibilità dei pacchetti per avviare l'attività di un'altra applicazione, non è necessario aggiungere un elemento <queries>
al file manifest dell'app o apportare modifiche a un elemento <queries>
esistente. Questo vale sia per gli intent impliciti che per quelli espliciti che aprono un URL.
Verificare se è disponibile un browser
In alcuni casi, prima di tentare di aprire un URL, l'app potrebbe voler verificare che sia disponibile almeno un browser sul dispositivo o che un browser specifico sia quello predefinito. In questi casi, includi il seguente elemento <intent>
come parte dell'elemento <queries>
nel tuo file manifest:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" /> </intent>
Quando chiami queryIntentActivities()
e passi un intent web come argomento, in alcuni casi l'elenco restituito include le app browser disponibili. L'elenco
non include le app del browser se l'utente ha configurato l'URL per l'apertura
in un'app non correlata al browser per impostazione predefinita.
Apri gli URL nelle schede personalizzate
Le schede personalizzate consentono
a un'app di personalizzare l'aspetto e il design del browser. Puoi aprire un URL in
una scheda personalizzata
senza dover aggiungere o modificare l'elemento <queries>
nel file manifest dell'app.
Tuttavia, potresti voler controllare se il dispositivo ha un browser che supporta le schede personalizzate o selezionare un browser specifico da avviare con le schede personalizzate utilizzando CustomTabsClient.getPackageName()
.
In questi casi, includi il seguente elemento <intent>
come parte
dell'elemento <queries>
nel file manifest:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.support.customtabs.action.CustomTabsService" /> </intent>
Consenti alle app non basate sul browser di gestire gli URL
Anche se la tua app può aprire gli URL utilizzando le schede personalizzate, è consigliabile consentire
a un'app non basata su browser, se possibile, di aprire un URL. Per offrire questa funzionalità nella tua app, prova a effettuare una chiamata a startActivity()
utilizzando un intent che imposti il flag di intent FLAG_ACTIVITY_REQUIRE_NON_BROWSER
. Se il sistema genera un ActivityNotFoundException
, l'app può aprire l'URL in una scheda personalizzata.
Se un intent include questo flag, una chiamata a startActivity()
causa
la generazione di un ActivityNotFoundException
quando si verifica una delle seguenti
condizioni:
- La chiamata avrebbe avviato direttamente un'app browser.
- La chiamata avrebbe mostrato all'utente una finestra di dialogo di disambiguazione in cui le uniche opzioni sono le app del browser.
Il seguente snippet di codice mostra come aggiornare la logica per utilizzare il flag di intent FLAG_ACTIVITY_REQUIRE_NON_BROWSER
:
Kotlin
try { val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply { // The URL should either launch directly in a non-browser app (if it's // the default) or in the disambiguation dialog. addCategory(CATEGORY_BROWSABLE) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER } startActivity(intent) } catch (e: ActivityNotFoundException) { // Only browser apps are available, or a browser is the default. // So you can open the URL directly in your app, for example in a // Custom Tab. openInCustomTabs(url) }
Java
try { Intent intent = new Intent(ACTION_VIEW, Uri.parse(url)); // The URL should either launch directly in a non-browser app (if it's the // default) or in the disambiguation dialog. intent.addCategory(CATEGORY_BROWSABLE); intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER); startActivity(intent); } catch (ActivityNotFoundException e) { // Only browser apps are available, or a browser is the default. // So you can open the URL directly in your app, for example in a // Custom Tab. openInCustomTabs(url); }
Evitare una finestra di dialogo di disambiguazione
Se vuoi evitare di mostrare la finestra di dialogo di disambiguazione che gli utenti potrebbero vedere quando aprono un URL e preferisci gestire personalmente l'URL in queste situazioni, puoi utilizzare un intent che imposti il flag di intent FLAG_ACTIVITY_REQUIRE_DEFAULT
.
Se un intent include questo flag, una chiamata a startActivity()
causa il generazione di un
ActivityNotFoundException
quando la chiamata avrebbe mostrato all'utente una
finestra di dialogo di disambiguazione.
Se un intent include sia questo flag sia il flag di intent FLAG_ACTIVITY_REQUIRE_NON_BROWSER
, una chiamata a startActivity()
determina il lancio di un ActivityNotFoundException
quando si verifica una delle seguenti condizioni:
- La chiamata avrebbe avviato direttamente l'app del browser.
- La chiamata avrebbe mostrato all'utente una finestra di dialogo di disambiguazione.
Il seguente snippet di codice mostra come utilizzare i flag FLAG_ACTIVITY_REQUIRE_NON_BROWSER
e FLAG_ACTIVITY_REQUIRE_DEFAULT
insieme:
Kotlin
val url = URL_TO_LOAD try { // For this intent to be invoked, the system must directly launch a // non-browser app. val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply { addCategory(CATEGORY_BROWSABLE) flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER or FLAG_ACTIVITY_REQUIRE_DEFAULT } startActivity(intent) } catch (e: ActivityNotFoundException) { // This code executes in one of the following cases: // 1. Only browser apps can handle the intent. // 2. The user has set a browser app as the default app. // 3. The user hasn't set any app as the default for handling this URL. openInCustomTabs(url) }
Java
String url = URL_TO_LOAD; try { // For this intent to be invoked, the system must directly launch a // non-browser app. Intent intent = new Intent(ACTION_VIEW, Uri.parse(url)); intent.addCategory(CATEGORY_BROWSABLE); intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER | FLAG_ACTIVITY_REQUIRE_DEFAULT); startActivity(intent); } catch (ActivityNotFoundException e) { // This code executes in one of the following cases: // 1. Only browser apps can handle the intent. // 2. The user has set a browser app as the default app. // 3. The user hasn't set any app as the default for handling this URL. openInCustomTabs(url); }
Apri un file
Se l'app gestisce file o allegati, ad esempio per controllare se un dispositivo è in grado di aprire un determinato file, in genere è più facile provare ad avviare un'attività in grado di gestire il file. Per farlo, utilizza un intent che includa l'azione intent ACTION_VIEW
e l'URI che rappresenta il file specifico. Se non è disponibile nessuna app sul dispositivo, la tua app può rilevare ActivityNotFoundException
. Nella logica di gestione delle eccezioni, puoi mostrare un errore o provare a gestire il file personalmente.
Se la tua app deve sapere in anticipo se un'altra app può aprire un determinato file, includi l'elemento <intent>
nel seguente snippet di codice come parte dell'elemento <queries>
nel file manifest. Includi il tipo di file se sai già
cosa è al momento della compilazione.
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.VIEW" /> <!-- If you don't know the MIME type in advance, set "mimeType" to "*/*". --> <data android:mimeType="application/pdf" /> </intent>
Puoi quindi verificare se un'app è disponibile chiamando resolveActivity()
con il tuo intent.
Concedi accesso URI
Nota:la dichiarazione delle autorizzazioni di accesso URI come descritto in questa sezione è obbligatoria per le app destinate ad Android 11 (livello API 30) o versioni successive e consigliata per tutte le app, indipendentemente dalla versione dell'SDK di destinazione e dal fatto che vengano esportati dai propri fornitori di contenuti.
Per le app destinate ad Android 11 o versioni successive per
accedere all'URI dei contenuti, l'intent dell'app deve dichiarare le autorizzazioni
di accesso tramite URI
impostando uno o entrambi i seguenti flag di intent:
FLAG_GRANT_READ_URI_PERMISSION
e
FLAG_GRANT_WRITE_URI_PERMISSION
.
Su Android 11 e versioni successive, le autorizzazioni di accesso all'URI concedono le seguenti funzionalità all'app che riceve l'intent:
- Leggono o scrivono in base ai dati rappresentati dall'URI dei contenuti, a seconda delle autorizzazioni URI concesse.
- Ottieni visibilità nell'app contenente il fornitore di contenuti che corrisponde all'autorità URI. L'app che include il fornitore di contenuti potrebbe essere diversa da quella che invia l'intent.
Il seguente snippet di codice mostra come aggiungere un flag di intent delle autorizzazioni URI in modo che un'altra app che ha come target Android 11 o versioni successive possa visualizzare i dati nell'URI dei contenuti:
Kotlin
val shareIntent = Intent(Intent.ACTION_VIEW).apply { flags = Intent.FLAG_GRANT_READ_URI_PERMISSION data = CONTENT_URI_TO_SHARE_WITH_OTHER_APP }
Java
Intent shareIntent = new Intent(Intent.ACTION_VIEW); shareIntent.setFlags(FLAG_GRANT_READ_URI_PERMISSION); shareIntent.setData(CONTENT_URI_TO_SHARE_WITH_OTHER_APP);
Connessione ai servizi
Se la tua app deve interagire con un servizio non visibile
automaticamente, puoi dichiarare
l'azione di intent appropriata all'interno di un elemento <queries>
. Le sezioni seguenti forniscono esempi di utilizzo dei servizi a cui si accede comunemente.
Connettiti a un motore di sintesi vocale
Se la tua app interagisce con un motore di sintesi vocale, includi il seguente
elemento <intent>
nell'elemento <queries>
nel file manifest:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.TTS_SERVICE" /> </intent>
Connettersi a un servizio di riconoscimento vocale
Se la tua app interagisce con un servizio di riconoscimento vocale, includi il seguente
elemento <intent>
nell'elemento <queries>
nel file manifest:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.speech.RecognitionService" /> </intent>
Connettersi a servizi di browser multimediali
Se la tua app è un'app browser multimediale
client, includi
il seguente elemento <intent>
nell'elemento <queries>
nel
file manifest:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.media.browse.MediaBrowserService" /> </intent>
Fornire funzionalità personalizzate
Se la tua app deve eseguire azioni personalizzabili o mostrare informazioni personalizzabili in base alle sue interazioni con altre app, puoi rappresentare tale comportamento personalizzato utilizzando le firme del filtro di intent come parte dell'elemento <queries>
nel tuo manifest. Le sezioni seguenti forniscono indicazioni dettagliate per diversi scenari comuni.
Query per le app SMS
Se la tua app ha bisogno di informazioni sul gruppo di app SMS installate su un
dispositivo, ad esempio per verificare quale app è il gestore SMS predefinito del dispositivo,
include il seguente elemento <intent>
come parte dell'elemento <queries>
nel
tuo file manifest:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.SENDTO"/> <data android:scheme="smsto" android:host="*" /> </intent>
Crea un foglio di condivisione personalizzato
Se possibile, utilizza un foglio di condivisione
fornito dal sistema. In alternativa,
Includi il seguente elemento <intent>
come parte dell'elemento <queries>
nel
tuo file manifest:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.SEND" /> <!-- Replace with the MIME type that your app works with, if needed. --> <data android:mimeType="image/jpeg" /> </intent>
Il processo di creazione del foglio di condivisione nella logica della tua app, ad esempio la chiamata a
queryIntentActivities()
, per il resto rimane invariato rispetto alle
versioni di Android precedenti ad Android 11.
Mostra azioni di selezione del testo personalizzate
Quando gli utenti selezionano testo nell'app, una barra degli strumenti di selezione del testo mostra l'insieme di possibili operazioni da eseguire sul testo selezionato. Se questa barra degli strumenti mostra azioni personalizzate di altre app, includi il seguente elemento <intent>
nell'elemento <queries>
nel file manifest:
<!-- Place inside the <queries> element. --> <intent> <action android:name="android.intent.action.PROCESS_TEXT" /> <data android:mimeType="text/plain" /> </intent>
Mostra righe di dati personalizzate per un contatto
Le app possono aggiungere righe di dati personalizzate al provider di contatti. Affinché un'app Contatti possa mostrare questi dati personalizzati, deve essere in grado di:
- Leggi il file
contacts.xml
dalle altre app. - Carica un'icona corrispondente al tipo MIME personalizzato.
Se la tua app è un'app per i contatti, includi i seguenti elementi <intent>
nell'elemento
<queries>
nel file manifest:
<!-- Place inside the <queries> element. --> <!-- Lets the app read the contacts.xml file from other apps. --> <intent> <action android:name="android.accounts.AccountAuthenticator" /> </intent> <!-- Lets the app load an icon corresponding to the custom MIME type. --> <intent> <action android:name="android.intent.action.VIEW" /> <data android:scheme="content" android:host="com.android.contacts" android:mimeType="vnd.android.cursor.item/*" /> </intent>