Ogni app per Android viene eseguita in una sandbox ad accesso limitato. Se la tua app deve utilizzare risorse o informazioni esterne alla propria sandbox, puoi dichiarare un'autorizzazione di runtime e configurare una richiesta di autorizzazione che fornisca questo accesso. Questi passaggi fanno parte del flusso di lavoro per l'utilizzo delle autorizzazioni.
Se dichiari autorizzazioni pericolose e se la tua app è installata su un dispositivo con Android 6.0 (livello API 23) o versioni successive, devi richiedere le autorizzazioni pericolose in fase di runtime seguendo i passaggi descritti in questa guida.
Se non dichiari autorizzazioni pericolose o se la tua app è installata su un dispositivo con Android 5.1 (livello API 22) o versioni precedenti, le autorizzazioni vengono concesse automaticamente e non devi completare nessuno dei passaggi rimanenti in questa pagina.
Principi di base
I principi di base per la richiesta di autorizzazioni in fase di runtime sono i seguenti:
- Chiedi un'autorizzazione nel contesto, quando l'utente inizia a interagire con la funzionalità che la richiede.
- Non bloccare l'utente. Fornisci sempre l'opzione per annullare un flusso di UI didattica, ad esempio un flusso che spiega la logica alla base della richiesta di autorizzazioni.
- Se l'utente nega o revoca un'autorizzazione necessaria per una funzionalità, applica la riduzione controllata per la tua app in modo che l'utente possa continuare a usarla, eventualmente disattivando la funzionalità che richiede l'autorizzazione.
- Non dare per scontato alcun comportamento del sistema. Ad esempio, non dare per scontato che le autorizzazioni vengano visualizzate nello stesso gruppo di autorizzazioni. Un gruppo di autorizzazioni aiuta semplicemente il sistema a ridurre al minimo il numero di finestre di dialogo di sistema presentate all'utente quando un'app richiede autorizzazioni strettamente correlate.
Workflow per la richiesta delle autorizzazioni
Prima di dichiarare e richiedere le autorizzazioni di runtime nella tua app, valuta se è necessario farlo. Puoi soddisfare molti casi d'uso nella tua app, ad esempio scattare foto, mettere in pausa la riproduzione di contenuti multimediali e mostrare annunci pertinenti, senza dover dichiarare alcuna autorizzazione.
Se ritieni che la tua app debba dichiarare e richiedere autorizzazioni di runtime, completa questi passaggi:
- Dichiara le autorizzazioni che la tua app potrebbe dover richiedere nel file manifest dell'app.
- Progetta la UX dell'app in modo che azioni specifiche nell'app siano associate ad autorizzazioni di runtime specifiche. Comunica agli utenti quali azioni potrebbero richiedere la concessione dell'autorizzazione per l'accesso ai dati utente privati da parte della tua app.
- Attendi che l'utente richiami l'attività o l'azione nella tua app che richiede l'accesso a dati utente privati specifici. In quel momento, l'app può richiedere l'autorizzazione di runtime necessaria per accedere ai dati.
Controlla se l'utente ha già concesso
autorizzazione di runtime richiesta dalla tua app. In questo caso, l'app può accedere ai dati utente privati. In caso contrario, vai al passaggio successivo.
Devi verificare se disponi di un'autorizzazione ogni volta che esegui un'operazione che la richiede.
Verifica se la tua app deve mostrare una motivazione all'utente, spiegando perché l'app richiede all'utente di concedere una determinata autorizzazione di runtime. Se il sistema determina che la tua app non deve mostrare una spiegazione, vai direttamente al passaggio successivo, senza mostrare un elemento UI.
Tuttavia, se il sistema determina che la tua app deve mostrare una spiegazione, presentala all'utente in un elemento UI. In questa motivazione, spiega chiaramente a quali dati la tua app sta tentando di accedere e quali vantaggi può offrire all'utente se concede l'autorizzazione di runtime. Dopo che l'utente ha confermato la motivazione, vai al passaggio successivo.
Richiedi l'autorizzazione di runtime necessaria alla tua app per accedere ai dati utente privati. Il sistema visualizza un prompt di autorizzazione di runtime, come quello mostrato nella pagina Panoramica delle autorizzazioni.
Controlla la risposta dell'utente, ovvero se ha scelto di concedere o negare l'autorizzazione di runtime.
Se l'utente ha concesso l'autorizzazione alla tua app, puoi accedere ai dati utente privati. Se invece l'utente ha negato l'autorizzazione, esegui la riduzione controllata dell'esperienza con l'app in modo che fornisca funzionalità all'utente senza le informazioni protette da questa autorizzazione.
La figura 1 illustra il workflow e l'insieme di decisioni associati a questo processo:
Determina se all'app è già stata concessa l'autorizzazione
Per verificare se l'utente ha già concesso alla tua app una determinata autorizzazione, passa
questa autorizzazione al metodo ContextCompat.checkSelfPermission().
Questo metodo restituisce PERMISSION_GRANTED o PERMISSION_DENIED, a seconda che l'app disponga o meno dell'autorizzazione.
Spiega il motivo per cui l'app richiede l'autorizzazione
La finestra di dialogo delle autorizzazioni mostrata dal sistema quando chiami
requestPermissions() indica l'autorizzazione richiesta dalla tua app, ma non
il motivo. In alcuni casi, l'utente potrebbe trovare la cosa sconcertante. È una buona idea spiegare all'utente perché la tua app richiede le autorizzazioni prima di chiamare requestPermissions().
Le ricerche dimostrano che gli utenti sono molto più propensi ad accettare le richieste di autorizzazione se sanno perché l'app ne ha bisogno, ad esempio se l'autorizzazione è necessaria per supportare una funzionalità principale dell'app o per la pubblicità. Di conseguenza, se utilizzi solo una parte delle chiamate API che rientrano in un gruppo di autorizzazioni, elenca esplicitamente quali di queste autorizzazioni utilizzi e perché. Ad esempio, se utilizzi solo la posizione approssimativa, comunicalo all'utente nella descrizione dell'app o negli articoli del Centro assistenza relativi all'app.
In determinate condizioni, è utile anche informare gli utenti dell'accesso ai dati sensibili in tempo reale. Ad esempio, se accedi alla fotocamera o al microfono, valuta la possibilità di informare l'utente utilizzando un'icona di notifica in un punto dell'app o nella barra delle notifiche (se l'applicazione è in esecuzione in background), in modo che non sembri che tu stia raccogliendo dati di nascosto.
Se devi richiedere un'autorizzazione per il funzionamento di una funzionalità, ma il motivo non è chiaro all'utente, trova un modo per spiegare perché hai bisogno di autorizzazioni sensibili.
Se il metodo ContextCompat.checkSelfPermission() restituisce PERMISSION_DENIED, chiama shouldShowRequestPermissionRationale(). Se questo metodo restituisce true, mostra all'utente una UI informativa. In questa UI, descrivi il motivo per cui la funzionalità che l'utente vuole attivare richiede una determinata autorizzazione.
Inoltre, se la tua app richiede un'autorizzazione relativa alla posizione, al microfono o alla fotocamera, valuta la possibilità di spiegare perché l'app ha bisogno di accedere a queste informazioni.
Richiedi autorizzazioni
Dopo che l'utente ha visualizzato una UI informativa o se il valore restituito di shouldShowRequestPermissionRationale() indica che non è necessario mostrare una UI informativa, richiedi l'autorizzazione. Gli utenti visualizzano una finestra di dialogo delle autorizzazioni di sistema, in cui possono scegliere se concedere o meno una determinata autorizzazione alla tua app.
Per farlo, utilizza il contratto RequestPermission, incluso in una libreria AndroidX, con cui consenti al sistema di gestire il codice della richiesta di autorizzazione per te. Poiché l'utilizzo del contratto RequestPermission semplifica la logica,
è la soluzione consigliata, se possibile. Tuttavia, se necessario, puoi anche gestire autonomamente un codice di richiesta nell'ambito della richiesta di autorizzazione e includerlo nella logica di callback dell'autorizzazione.
Consenti al sistema di gestire il codice della richiesta di autorizzazione
Per consentire al sistema di gestire il codice di richiesta associato a una richiesta di autorizzazione, aggiungi le dipendenze alle seguenti librerie nel file build.gradle del tuo modulo:
androidx.activity, versione 1.2.0 o successiveandroidx.fragment, versione 1.3.0 o successive
Puoi quindi utilizzare una delle seguenti classi:
- Per richiedere una singola autorizzazione, utilizza
RequestPermission. - Per richiedere più autorizzazioni contemporaneamente, utilizza
RequestMultiplePermissions.
I passaggi seguenti mostrano come utilizzare il contratto RequestPermission. Il processo è quasi identico per il contratto RequestMultiplePermissions.
Nella logica di inizializzazione dell'attività o del frammento, passa un'implementazione di
ActivityResultCallbackin una chiamata aregisterForActivityResult().ActivityResultCallbackdefinisce il modo in cui l'app gestisce la risposta dell'utente alla richiesta di autorizzazione.Conserva un riferimento al valore restituito di
registerForActivityResult(), che è di tipoActivityResultLauncher.Per visualizzare la finestra di dialogo delle autorizzazioni di sistema quando necessario, chiama il metodo
launch()sull'istanza diActivityResultLauncherche hai salvato nel passaggio precedente.Dopo la chiamata di
launch(), viene visualizzata la finestra di dialogo delle autorizzazioni di sistema. Quando l'utente effettua una scelta, il sistema richiama in modo asincrono la tua implementazione diActivityResultCallback, che hai definito nel passaggio precedente.Nota : la tua app non può personalizzare la finestra di dialogo visualizzata quando chiami
launch(). Per fornire maggiori informazioni o un contesto all'utente, modifica la UI della tua app in modo che sia più facile per gli utenti capire perché una funzionalità della tua app richiede una determinata autorizzazione. Ad esempio, potresti modificare il testo nel pulsante che attiva la funzionalità.Inoltre, il testo nella finestra di dialogo delle autorizzazioni di sistema fa riferimento al gruppo di autorizzazioni associato all'autorizzazione richiesta. Questo raggruppamento di autorizzazioni è progettato per semplificare l'utilizzo del sistema e la tua app non deve fare affidamento sul fatto che le autorizzazioni si trovino all'interno o all'esterno di un gruppo di autorizzazioni specifico.
Il seguente snippet di codice mostra come gestire la risposta alle autorizzazioni:
Kotlin
when { ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION ) == PackageManager.PERMISSION_GRANTED -> { // You can use the API that requires the permission. performAction(...) } ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION) -> { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...) } else -> { // You can directly ask for the permission. requestPermissions(CONTEXT, arrayOf(Manifest.permission.REQUESTED_PERMISSION), REQUEST_CODE) } }
Java
if (ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION) == PackageManager.PERMISSION_GRANTED) { // You can use the API that requires the permission. performAction(...); } else if (ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION)) { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...); } else { // You can directly ask for the permission. requestPermissions(CONTEXT, new String[] { Manifest.permission.REQUESTED_PERMISSION }, REQUEST_CODE); }
Questo snippet di codice mostra la procedura consigliata per verificare un'autorizzazione e richiederla all'utente, se necessario:
Kotlin
when { ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION ) == PackageManager.PERMISSION_GRANTED -> { // You can use the API that requires the permission. } ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION) -> { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...) } else -> { // You can directly ask for the permission. // The registered ActivityResultCallback gets the result of this request. requestPermissionLauncher.launch( Manifest.permission.REQUESTED_PERMISSION) } }
Java
if (ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION) == PackageManager.PERMISSION_GRANTED) { // You can use the API that requires the permission. performAction(...); } else if (ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION)) { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...); } else { // You can directly ask for the permission. // The registered ActivityResultCallback gets the result of this request. requestPermissionLauncher.launch( Manifest.permission.REQUESTED_PERMISSION); }
Gestisci autonomamente il codice della richiesta di autorizzazione
In alternativa a consentire al sistema di gestire il codice di richiesta di autorizzazione, puoi gestire il codice di richiesta di autorizzazione autonomamente. Per farlo,
includi il codice di richiesta in una chiamata a requestPermissions().
Il seguente snippet di codice mostra come richiedere un'autorizzazione utilizzando un codice di richiesta:
Kotlin
when { ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION ) == PackageManager.PERMISSION_GRANTED -> { // You can use the API that requires the permission. performAction(...) } ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION) -> { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...) } else -> { // You can directly ask for the permission. requestPermissions(CONTEXT, arrayOf(Manifest.permission.REQUESTED_PERMISSION), REQUEST_CODE) } }
Java
if (ContextCompat.checkSelfPermission( CONTEXT, Manifest.permission.REQUESTED_PERMISSION) == PackageManager.PERMISSION_GRANTED) { // You can use the API that requires the permission. performAction(...); } else if (ActivityCompat.shouldShowRequestPermissionRationale( this, Manifest.permission.REQUESTED_PERMISSION)) { // In an educational UI, explain to the user why your app requires this // permission for a specific feature to behave as expected, and what // features are disabled if it's declined. In this UI, include a // "cancel" or "no thanks" button that lets the user continue // using your app without granting the permission. showInContextUI(...); } else { // You can directly ask for the permission. requestPermissions(CONTEXT, new String[] { Manifest.permission.REQUESTED_PERMISSION }, REQUEST_CODE); }
Dopo che l'utente ha risposto alla finestra di dialogo delle autorizzazioni di sistema, il sistema richiama l'implementazione di onRequestPermissionsResult() della tua app. Il sistema trasmette la risposta dell'utente alla finestra di dialogo delle autorizzazioni, nonché il codice di richiesta che hai definito, come mostrato nel seguente snippet di codice:
Kotlin
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) { when (requestCode) { PERMISSION_REQUEST_CODE -> { // If request is cancelled, the result arrays are empty. if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { // Permission is granted. Continue the action or workflow // in your app. } else { // Explain to the user that the feature is unavailable because // the feature requires a permission that the user has denied. // At the same time, respect the user's decision. Don't link to // system settings in an effort to convince the user to change // their decision. } return } // Add other 'when' lines to check for other // permissions this app might request. else -> { // Ignore all other requests. } } }
Java
@Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case PERMISSION_REQUEST_CODE: // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission is granted. Continue the action or workflow // in your app. } else { // Explain to the user that the feature is unavailable because // the feature requires a permission that the user has denied. // At the same time, respect the user's decision. Don't link to // system settings in an effort to convince the user to change // their decision. } return; } // Other 'case' lines to check for other // permissions this app might request. } }
Richiedi le autorizzazioni di accesso alla posizione
Quando richiedi le autorizzazioni di accesso alla posizione, segui le stesse best practice di qualsiasi altra autorizzazione di runtime. Una differenza importante per quanto riguarda le autorizzazioni di accesso alla posizione è che il sistema include più autorizzazioni correlate alla posizione. Le autorizzazioni che richiedi e il modo in cui le richiedi dipendono dai requisiti per le località per il caso d'uso della tua app.
Posizione in primo piano
Se la tua app contiene una funzionalità che condivide o riceve dati sulla posizione una sola volta o per un periodo di tempo definito, questa funzionalità richiede l'accesso alla posizione in primo piano. Ecco alcuni esempi:
- All'interno di un'app di navigazione, una funzionalità consente agli utenti di ricevere indicazioni stradali passo passo.
- All'interno di un'app di messaggistica, una funzionalità consente agli utenti di condividere la propria posizione attuale con un altro utente.
Il sistema considera che la tua app utilizzi la posizione in primo piano se una funzionalità della tua app accede alla posizione attuale del dispositivo in una delle seguenti situazioni:
- Un'attività che appartiene alla tua app è visibile.
La tua app sta eseguendo un servizio in primo piano. Quando un servizio in primo piano è in esecuzione, il sistema aumenta la consapevolezza dell'utente mostrando una notifica persistente. L'app mantiene l'accesso quando viene posizionata in background, ad esempio quando l'utente preme il pulsante Home sul dispositivo o spegne il display del dispositivo.
Su Android 10 (livello API 29) e versioni successive, devi dichiarare un tipo di servizio in primo piano di
location, come mostrato nello snippet di codice seguente. Nelle versioni precedenti di Android, ti consigliamo di dichiarare questo tipo di servizio in primo piano.<!-- Recommended for Android 9 (API level 28) and lower. --> <!-- Required for Android 10 (API level 29) and higher. --> <service android:name="MyNavigationService" android:foregroundServiceType="location" ... > <!-- Any inner elements go here. --> </service>
Dichiari la necessità di accedere alla posizione in primo piano quando la tua app richiede l'autorizzazione ACCESS_COARSE_LOCATION o l'autorizzazione ACCESS_FINE_LOCATION, come mostrato nel seguente snippet:
<manifest ... > <!-- Include this permission any time your app needs location information. --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- Include only if your app benefits from precise location access. --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> </manifest>
Posizione in background
Un'app richiede l'accesso alla posizione in background se una funzionalità al suo interno condivide costantemente la posizione con altri utenti o utilizza l'API Geofencing. Ecco alcuni esempi:
- All'interno di un'app di condivisione della posizione con il gruppo Famiglia, una funzionalità consente agli utenti di condividere continuamente la posizione con i membri del gruppo Famiglia.
- All'interno di un'app IoT, una funzionalità consente agli utenti di configurare i propri dispositivi per la casa in modo che si spegnano quando l'utente esce di casa e si riaccendano quando l'utente torna a casa.
Il sistema considera che la tua app utilizzi la posizione in background se accede alla posizione attuale del dispositivo in qualsiasi situazione diversa da quelle descritte nella sezione Posizione in primo piano. La precisione della localizzazione in background è la stessa della precisione della localizzazione in primo piano, che dipende dalle autorizzazioni di accesso alla posizione dichiarate dalla tua app.
Su Android 10 (livello API 29) e versioni successive, devi dichiarare l'autorizzazione ACCESS_BACKGROUND_LOCATION nel file manifest della tua app per richiedere l'accesso alla posizione in background in fase di runtime. Nelle versioni precedenti di Android, quando la tua app riceve l'accesso alla posizione in primo piano, riceve automaticamente anche l'accesso alla posizione in background.
<manifest ... >
<!-- Required only when requesting background location access on
Android 10 (API level 29) and higher. -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>
Gestisci il rifiuto delle autorizzazioni
Se l'utente nega una richiesta di autorizzazione, l'app deve aiutarlo a comprendere le implicazioni del rifiuto dell'autorizzazione. In particolare, la tua app deve informare gli utenti delle funzionalità che non funzionano a causa dell'autorizzazione mancante. Quando lo fai, tieni presente le seguenti best practice:
- Riduci al minimo la perdita di funzionalità. Gli utenti devono poter accedere all'app nella misura massima possibile senza le autorizzazioni richieste. Se la funzionalità è almeno parzialmente operativa con i dati disponibili, anche se con prestazioni ridotte rispetto a quelle che avrebbe potuto avere con l'autorizzazione, l'opzione migliore è mantenerla attiva.
Guida l'attenzione dell'utente. Evidenzia una parte specifica della UI della tua app in cui la funzionalità è limitata perché l'app non dispone dell'autorizzazione necessaria. Ecco alcuni esempi di ciò che puoi fare:
- Mostra un messaggio nel punto in cui sarebbero apparsi i risultati o i dati della funzionalità.
- Mostra un pulsante diverso che contiene un'icona e un colore di errore.
Fornisci informazioni specifiche. Non mostrare un messaggio generico. Invece, indica chiaramente quali funzionalità non sono disponibili perché l'app non dispone dell'autorizzazione necessaria.
Non bloccare l'interfaccia utente. In altre parole, non mostrare un messaggio di avviso a schermo intero che impedisca agli utenti di continuare a utilizzare l'app.
Accetta la preferenza dell'utente:anche se è consentito comunicare agli utenti in che modo la loro funzionalità è influenzata dalla mancanza di accesso alle autorizzazioni richieste, non devono sentirsi sotto pressione per cambiare idea. È importante informare un utente che non ha accesso completo alle funzionalità quando è opportuno (ad esempio quando tenta di utilizzare una parte dell'app bloccata senza l'autorizzazione), ma le richieste persistenti di riconsiderare la scelta non sono rispettose.
Seguire queste linee guida può contribuire a garantire che gli utenti si sentano in grado di gestire l'accesso ai propri dati privati in modo coerente con i loro valori. La mancata accettazione delle decisioni degli utenti in materia di privacy, che sono molto visibili, danneggia la fiducia e la reputazione non solo della tua app, ma dell'intero ecosistema.
Inoltre, se l'utente tocca Rifiuta per una determinata autorizzazione più di una volta durante il ciclo di vita dell'installazione della tua app su un dispositivo, non vedrà più la finestra di dialogo delle autorizzazioni di sistema se la tua app richiede nuovamente l'autorizzazione. L'azione dell'utente implica "non chiedere più" ed è considerata un rifiuto permanente. È molto importante chiedere agli utenti le autorizzazioni solo quando hanno bisogno di accedere a una funzionalità specifica; in caso contrario, potresti perdere inavvertitamente la possibilità di richiedere nuovamente le autorizzazioni. In alcune situazioni, l'autorizzazione potrebbe essere negata automaticamente, senza che l'utente debba intervenire. (Un'autorizzazione potrebbe anche essere concessa automaticamente.) È importante non dare nulla per scontato in merito al comportamento automatico. Ogni volta che la tua app deve accedere a una funzionalità che richiede un'autorizzazione, verifica che l'autorizzazione sia ancora concessa. Per offrire la migliore esperienza utente quando richiedi le autorizzazioni app, consulta anche le best practice per le autorizzazioni app.
Ispeziona lo stato di rifiuto durante i test e il debug
Per identificare se a un'app sono state negate definitivamente le autorizzazioni (per scopi di debug e test), utilizza il seguente comando:
adb shell dumpsys package PACKAGE_NAME
Dove PACKAGE_NAME è il nome del pacchetto da ispezionare.
L'output del comando contiene sezioni simili alle seguenti:
... runtime permissions: android.permission.POST_NOTIFICATIONS: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED] android.permission.ACCESS_FINE_LOCATION: granted=false, flags=[ USER_SET|USER_FIXED|USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED] android.permission.BLUETOOTH_CONNECT: granted=false, flags=[ USER_SENSITIVE_WHEN_GRANTED|USER_SENSITIVE_WHEN_DENIED] ...
Le autorizzazioni che sono state negate una volta dall'utente sono contrassegnate da USER_SET.
Le autorizzazioni che sono state negate definitivamente selezionando Nega due volte sono contrassegnate da USER_FIXED.
Per assicurarti che i tester visualizzino la finestra di dialogo della richiesta durante i test, reimposta questi flag al termine del debug dell'app. Per farlo, utilizza il comando:
adb shell pm clear-permission-flags PACKAGE_NAME PERMISSION_NAME user-set user-fixed
PERMISSION_NAME è il nome dell'autorizzazione che vuoi reimpostare.
PERMISSION_NAME è il nome dell'autorizzazione che vuoi reimpostare.
Per visualizzare un elenco completo delle autorizzazioni app per Android, visita la pagina di riferimento dell'API Permissions.
Autorizzazioni una tantum
A partire da Android 11 (livello API 30), ogni volta che la tua app richiede un'autorizzazione relativa alla posizione, al microfono o alla fotocamera, la finestra di dialogo delle autorizzazioni rivolta agli utenti contiene un'opzione chiamata Solo questa volta, come mostrato nella figura 2. Se l'utente seleziona questa opzione nella finestra di dialogo, alla tua app viene concessa un'autorizzazione una tantum temporanea.
L'app può quindi accedere ai dati correlati per un periodo di tempo che dipende dal comportamento dell'app e dalle azioni dell'utente:
- Mentre l'attività della tua app è visibile, l'app può accedere ai dati.
- Se l'utente invia l'app in background, l'app può continuare ad accedere ai dati per un breve periodo di tempo.
- Se avvii un servizio in primo piano mentre l'attività è visibile e l'utente sposta l'app in background, l'app può continuare ad accedere ai dati finché il servizio in primo piano non si interrompe.
Il processo dell'app termina quando l'autorizzazione viene revocata
Se l'utente revoca l'autorizzazione una tantum, ad esempio nelle impostazioni di sistema, la tua app non può accedere ai dati, indipendentemente dal fatto che tu abbia avviato un servizio in primo piano. Come per qualsiasi autorizzazione, se l'utente revoca l'autorizzazione una tantum della tua app, il processo dell'app viene terminato.
La volta successiva che l'utente apre l'app e una funzionalità dell'app richiede l'accesso alla posizione, al microfono o alla fotocamera, all'utente viene richiesta nuovamente l'autorizzazione.
Reimposta le autorizzazioni inutilizzate
Android offre diversi modi per reimpostare le autorizzazioni di runtime inutilizzate allo stato predefinito, ovvero negate:
- Un'API con cui puoi rimuovere in modo proattivo l'accesso della tua app a un'autorizzazione di runtime non utilizzata.
- Un meccanismo di sistema che reimposta automaticamente le autorizzazioni delle app inutilizzate.
Rimuovi l'accesso delle app
Su Android 13 (livello API 33) e versioni successive, puoi rimuovere l'accesso della tua app alle autorizzazioni di runtime non più necessarie. Quando aggiorni l'app, esegui questo passaggio in modo che gli utenti abbiano maggiori probabilità di capire perché l'app continua a richiedere autorizzazioni specifiche. Queste informazioni contribuiscono a rafforzare la fiducia degli utenti nella tua app.
Per rimuovere l'accesso a un'autorizzazione di runtime, passa il nome dell'autorizzazione in revokeSelfPermissionOnKill(). Per rimuovere l'accesso a un gruppo di autorizzazioni di runtime contemporaneamente, passa una raccolta di nomi di autorizzazioni in revokeSelfPermissionsOnKill(). La procedura di rimozione delle autorizzazioni avviene in modo asincrono e termina tutti i processi associati all'UID della tua app.
Affinché il sistema rimuova l'accesso della tua app alle autorizzazioni, tutti i processi collegati alla tua app devono essere terminati. Quando chiami l'API, il sistema determina quando è sicuro terminare questi processi. In genere, il sistema attende che l'app venga eseguita per un periodo di tempo prolungato in background anziché in primo piano.
Per informare l'utente che la tua app non richiede più l'accesso a specifiche autorizzazioni di runtime, mostra una finestra di dialogo la prossima volta che l'utente avvia l'app. Questa finestra di dialogo può includere l'elenco delle autorizzazioni.
Reimposta automaticamente le autorizzazioni delle app inutilizzate
Se la tua app ha come target Android 11 (livello API 30) o versioni successive e non viene utilizzata per alcuni mesi, il sistema protegge i dati utente reimpostando automaticamente le autorizzazioni di runtime sensibili che l'utente aveva concesso alla tua app. Scopri di più nella guida sull'ibernazione dell'app.
Richiedi di diventare il gestore predefinito, se necessario
Alcune app dipendono dall'accesso a informazioni utente sensibili relative ai registri chiamate e agli SMS. Se vuoi richiedere le autorizzazioni specifiche per i registri chiamate e i messaggi SMS e pubblicare la tua app sul Play Store, devi chiedere all'utente di impostare la tua app come gestore predefinito per una funzione di sistema di base prima di richiedere queste autorizzazioni di runtime.
Per ulteriori informazioni sui gestori predefiniti, incluse le indicazioni su come mostrare agli utenti un prompt del gestore predefinito, consulta la guida sulle autorizzazioni utilizzate solo nei gestori predefiniti.
Concedi tutte le autorizzazioni di runtime a scopo di test
Per concedere automaticamente tutte le autorizzazioni di runtime quando installi un'app su un emulatore o un dispositivo di test, utilizza l'opzione -g per il comando adb shell install, come mostrato nello snippet di codice seguente:
adb shell install -g PATH_TO_APK_FILE
Risorse aggiuntive
Per ulteriori informazioni sulle autorizzazioni, leggi questi articoli:
Per scoprire di più sulla richiesta di autorizzazioni, consulta gli esempi di autorizzazioni.
Puoi anche completare questo codelab che illustra le best practice per la privacy.