Richiedi autorizzazioni di runtime

Ogni app per Android viene eseguita in una sandbox ad accesso limitato. Se la tua app deve utilizzare risorse o informazioni al di fuori della 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 la procedura descritta in questa guida.

Se non dichiari autorizzazioni pericolose o se la tua app è installata su un dispositivo che esegue Android 5.1 (livello API 22) o versioni precedenti, le autorizzazioni vengono concesse automaticamente e non è necessario completare nessuno dei passaggi rimanenti in questa pagina.

Principi di base

I principi di base per richiedere le 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 dell'interfaccia utente didattica, ad esempio un flusso che spieghi il motivo per cui richiedi le autorizzazioni.
  • Se l'utente nega o revoca un'autorizzazione necessaria per una funzionalità, esegui la riduzione controllata dell'app in modo che l'utente possa continuare a utilizzarla, 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 appartengano allo stesso gruppo di autorizzazioni. Un gruppo di autorizzazioni consente semplicemente al sistema di ridurre al minimo il numero di finestre di dialogo di sistema presentate all'utente quando un'app richiede autorizzazioni strettamente correlate.

Flusso di lavoro per la richiesta di autorizzazioni

Prima di dichiarare e richiedere autorizzazioni di runtime nell'app, valuta se l'app deve farlo. Puoi soddisfare molti casi d'uso nell'app, ad esempio scattare foto, mettere in pausa la riproduzione di contenuti multimediali e pubblicare annunci pertinenti, senza dover dichiarare alcuna autorizzazione.

Se ritieni che la tua app debba dichiarare e richiedere autorizzazioni di runtime, completa questi passaggi:

  1. Nel file manifest dell'app, dichiara le autorizzazioni che l'app potrebbe dover richiedere.
  2. Progetta l'UX della tua app in modo che azioni specifiche nell'app siano associate ad autorizzazioni di runtime specifiche. Fai sapere agli utenti quali azioni potrebbero richiedere alla tua app di accedere ai dati utente privati.
  3. Attendi che l'utente richiami l'attività o l'azione nella tua app che richiede l'accesso a dati privati dell'utente specifici. A quel punto, l'app può richiedere l'autorizzazione di runtime necessaria per accedere a questi dati.
  4. Verifica se l'utente ha già concesso l'autorizzazione di runtime richiesta dalla tua app. In tal caso, la tua app può accedere ai dati privati dell'utente. In caso contrario, vai al passaggio successivo.

    Devi verificare se disponi di un'autorizzazione ogni volta che esegui un'operazione che la richiede.

  5. Verifica se la tua app deve mostrare una motivazione all'utente, spiegando perché è necessario che l'utente conceda una determinata autorizzazione di runtime. Se il sistema stabilisce che la tua app non deve mostrare una motivazione, vai direttamente al passaggio successivo senza mostrare un elemento UI.

    Se il sistema stabilisce che la tua app deve mostrare una motivazione, fornisci una motivazione per l'utente in un elemento UI. In questa motivazione, spiega chiaramente a quali dati sta cercando di accedere la tua app e quali vantaggi può offrire all'utente se concede l'autorizzazione di runtime. Dopo che l'utente ha compreso la motivazione, vai al passaggio successivo.

  6. Richiedi l'autorizzazione di runtime richiesta dalla tua app per accedere ai dati privati dell'utente. Il sistema visualizza una richiesta di autorizzazione di runtime, come quella mostrata nella pagina della panoramica delle autorizzazioni.

  7. Controlla la risposta dell'utente, se ha scelto di concedere o negare l'autorizzazione di runtime.

  8. Se l'utente ha concesso l'autorizzazione alla tua app, puoi accedere ai dati utente privati. Se l'utente ha invece negato l'autorizzazione, riduci automaticamente la tua esperienza con la tua app in modo che fornisca funzionalità all'utente senza le informazioni protette da tale autorizzazione.

La Figura 1 illustra il flusso di lavoro e l'insieme di decisioni associate a questo processo:

Figura 1. Diagramma che mostra il flusso di lavoro per dichiarare e richiedere le autorizzazioni di runtime su Android.

Determinare se all'app è già stata concessa l'autorizzazione

Per verificare se l'utente ha già concesso alla tua app un'autorizzazione specifica, trasmettila 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 la tua app ha bisogno dell'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 sconvolgente. Ti consigliamo di spiegare all'utente perché la tua app richiede le autorizzazioni prima di chiamare requestPermissions().

La ricerca dimostra che gli utenti si sentono molto più a proprio agio con le richieste di autorizzazioni se sanno perché l'app le 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, è utile elencare in modo esplicito quali di queste autorizzazioni stai utilizzando e perché. Ad esempio, se utilizzi solo la posizione approssimativa, comunicalo all'utente nella descrizione dell'app o negli articoli del Centro assistenza relativi alla tua 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, ti consigliamo di informare l'utente tramite un'icona di notifica in un punto qualsiasi dell'app o nella barra delle notifiche (se l'applicazione è in esecuzione in background), in modo che l'applicazione non stia raccogliendo i dati in modo subdolo.

In definitiva, se devi richiedere un'autorizzazione per far funzionare qualcosa nella tua app, ma il motivo non è chiaro all'utente, puoi trovare un modo per fargli sapere perché hai bisogno delle autorizzazioni più sensibili.

Se il metodo ContextCompat.checkSelfPermission() restituisce PERMISSION_DENIED, chiama shouldShowRequestPermissionRationale(). Se questo metodo restituisce true, mostra all'utente un'interfaccia utente didattica. In questa UI, descrivi perché la funzionalità che l'utente vuole attivare richiede una specifica 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 un'interfaccia utente didattica o che il valore restituito da shouldShowRequestPermissionRationale() indica che non è necessario mostrare un'interfaccia utente didattica, 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.

A questo scopo, utilizza il contratto RequestPermission, incluso in una libreria AndroidX, in 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, laddove possibile. Tuttavia, se necessario, puoi anche gestire autonomamente un codice di richiesta come parte della richiesta di autorizzazione e includere questo codice di richiesta nella logica di callback delle autorizzazioni.

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 nelle seguenti librerie nel file build.gradle del modulo:

Puoi quindi utilizzare una delle seguenti classi:

I passaggi seguenti spiegano come usare il contratto RequestPermission. La procedura è quasi la stessa per il contratto RequestMultiplePermissions.

  1. Nella logica di inizializzazione del tuo frammento o attività, passa un'implementazione di ActivityResultCallback in una chiamata a registerForActivityResult(). L'elemento ActivityResultCallback definisce il modo in cui l'app gestisce la risposta dell'utente alla richiesta di autorizzazione.

    Mantieni un riferimento al valore restituito di registerForActivityResult(), che è di tipo ActivityResultLauncher.

  2. Per visualizzare la finestra di dialogo delle autorizzazioni di sistema quando necessario, chiama il metodo launch() per l'istanza di ActivityResultLauncher salvata nel passaggio precedente.

    Dopo la chiamata di launch(), viene visualizzata la finestra di dialogo delle autorizzazioni di sistema. Quando l'utente fa una scelta, il sistema richiama in modo asincrono la tua implementazione di ActivityResultCallback, che hai definito nel passaggio precedente.

    Nota : la tua app non può personalizzare la finestra di dialogo visualizzata quando chiami launch(). Per fornire ulteriori informazioni o contesto all'utente, modifica l'UI della tua app in modo che sia più facile per gli utenti capire perché una funzionalità dell'app richiede una determinata autorizzazione. Ad esempio, puoi modificare il testo nel pulsante che abilita 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 facilitare la facilità d'uso del sistema e la tua app non deve dipendere dal fatto che le autorizzazioni siano all'interno o all'esterno di un gruppo di autorizzazioni specifico.

Il seguente snippet di codice mostra come gestire la risposta relativa alle autorizzazioni:

Kotlin

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher. You can use either a val, as shown in this snippet,
// or a lateinit var in your onAttach() or onCreate() method.
val requestPermissionLauncher =
    registerForActivityResult(RequestPermission()
    ) { isGranted: Boolean ->
        if (isGranted) {
            // 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.
        }
    }

Java

// Register the permissions callback, which handles the user's response to the
// system permissions dialog. Save the return value, an instance of
// ActivityResultLauncher, as an instance variable.
private ActivityResultLauncher<String> requestPermissionLauncher =
    registerForActivityResult(new RequestPermission(), isGranted -> {
        if (isGranted) {
            // 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.
        }
    });

Questo snippet di codice mostra la procedura consigliata per verificare la presenza di un'autorizzazione e richiedere un'autorizzazione all'utente quando 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 della richiesta di autorizzazione, puoi gestire autonomamente il codice della richiesta di autorizzazione. Per farlo, includi il codice di richiesta in una chiamata al numero 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);
}

Quando l'utente risponde alla finestra di dialogo delle autorizzazioni di sistema, il sistema richiama l'implementazione di onRequestPermissionsResult() nell'app. Il sistema trasmette la risposta dell'utente alla finestra di dialogo di autorizzazione, nonché il codice della richiesta da te 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 autorizzazioni di accesso alla posizione

Quando richiedi le autorizzazioni di accesso alla posizione, segui le stesse best practice previste per 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 richieste e le modalità di richiesta dipendono dai requisiti della località per il caso d'uso della tua app.

Posizione in primo piano

Se la tua app contiene una funzionalità che condivide o riceve informazioni sulla posizione solo una volta o per un periodo di tempo definito, tale funzionalità richiede l'accesso alla posizione in primo piano. Tra gli esempi di tali prodotti o servizi figurano:

  • In un'app di navigazione è presente una funzione che consente agli utenti di ricevere indicazioni stradali passo passo.
  • All'interno di un'app di messaggistica, una funzionalità consente agli utenti di condividere la loro posizione attuale con un altro utente.

Il sistema considera che la tua app utilizza la posizione in primo piano se una funzionalità dell'app accede alla posizione attuale del dispositivo in una delle seguenti situazioni:

  • Un'attività appartenente alla tua app è visibile.
  • La tua app esegue un servizio in primo piano. Quando un servizio in primo piano è in esecuzione, il sistema aumenta la consapevolezza degli utenti mostrando una notifica persistente. L'app conserva l'accesso quando è posizionata in background, ad esempio quando l'utente preme il pulsante Home sul proprio 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 pari a location, come mostrato nel seguente snippet di codice. 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à della posizione in primo piano quando l'app richiede l'autorizzazione ACCESS_COARSE_LOCATION o ACCESS_FINE_LOCATION, come mostrato nello snippet seguente:

<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 se utilizza l'API Geofencing. Ecco alcuni esempi:

  • In un'app di condivisione della posizione in 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 dispositivi per la casa in modo che si spengano quando l'utente esce di casa e si riaccendano quando l'utente torna a casa.

Il sistema considera che la tua app utilizza 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 posizione in background corrisponde alla precisione della posizione in primo piano, che dipende dalle autorizzazioni di accesso alla posizione dichiarate dall'app.

Su Android 10 (livello API 29) e versioni successive, per richiedere l'accesso alla posizione in background in fase di runtime devi dichiarare l'autorizzazione ACCESS_BACKGROUND_LOCATION nel file manifest dell'app. 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>

Gestire il rifiuto delle autorizzazioni

Se l'utente nega una richiesta di autorizzazione, la tua app deve aiutare gli utenti a comprendere le implicazioni del rifiuto dell'autorizzazione. In particolare, l'app deve informare gli utenti delle funzionalità che non funzionano a causa dell'autorizzazione mancante. Quando esegui questa operazione, tieni presente le seguenti best practice:

  • Indirizza l'attenzione dell'utente. Evidenzia una parte specifica dell'interfaccia utente della tua app in cui la funzionalità è limitata, perché l'app non dispone dell'autorizzazione necessaria. Ecco alcuni esempi di cosa puoi fare:

    • Mostra un messaggio in cui sarebbero stati mostrati i risultati o i dati dell'elemento.
    • Visualizza un pulsante diverso contenente un'icona e un colore di errore.
  • Scrivi in modo dettagliato. Non visualizzare un messaggio generico. Chiarisci invece quali funzionalità non sono disponibili perché la tua app non dispone dell'autorizzazione necessaria.

  • Non bloccare l'interfaccia utente. In altre parole, non mostrare un messaggio di avviso a schermo intero che impedisce agli utenti di continuare a utilizzare l'app.

Allo stesso tempo, la tua app deve rispettare la decisione dell'utente di negare un'autorizzazione. A partire da Android 11 (livello API 30), se l'utente tocca Rifiuta per una specifica autorizzazione più di una volta durante il periodo di installazione dell'app su un dispositivo, l'utente non vede la finestra di dialogo delle autorizzazioni di sistema se l'app richiede di nuovo l'autorizzazione. L'azione dell'utente implica "Non chiedermelo più". Nelle versioni precedenti, gli utenti vedevano la finestra di dialogo delle autorizzazioni di sistema ogni volta che la tua app richiedeva un'autorizzazione, a meno che in precedenza non avessero selezionato una casella di controllo o un'opzione "Non chiedermelo più".

Se un utente nega una richiesta di autorizzazione più di una volta, il rifiuto viene considerato permanente. È molto importante richiedere le autorizzazioni agli utenti solo quando hanno bisogno di accedere a una funzionalità specifica, altrimenti potresti perdere inavvertitamente la possibilità di richiedere nuovamente le autorizzazioni.

In alcune situazioni, l'autorizzazione potrebbe essere negata automaticamente senza che l'utente intraprenda alcuna azione. Anche un'autorizzazione potrebbe essere concessa automaticamente. È importante non dare per certo ad alcun comportamento automatico. Ogni volta che la tua app deve accedere a funzionalità che richiedono un'autorizzazione, verifica che all'app venga comunque concessa l'autorizzazione in questione.

Per offrire la migliore esperienza utente quando richiedi autorizzazioni app, consulta anche le best practice relative alle autorizzazioni app.

Ispeziona lo stato di rifiuto durante i test e il debug

Per identificare se a un'app sono state negate in modo permanente le autorizzazioni (a scopo 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 che hanno il seguente aspetto:

...
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 negate una volta dall'utente vengono segnalate da USER_SET. Le autorizzazioni che sono state negate in modo permanente selezionando Rifiuta due volte vengono contrassegnate da USER_FIXED.

Per assicurarti che i tester vedano la finestra di dialogo della richiesta durante il test, reimposta questi flag al termine del debug dell'app. A tale scopo, 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.

Per visualizzare un elenco completo delle autorizzazioni per le app per Android, visita la pagina di riferimento dell'API per le autorizzazioni.

Autorizzazioni una tantum

L&#39;opzione &quot;Solo questa volta&quot; è il secondo dei tre pulsanti della finestra di dialogo.
Figura 2. Finestra di dialogo di sistema che viene visualizzata quando un'app richiede un'autorizzazione 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à dell'app è visibile, l'app può accedere ai dati.
  • Se l'utente invia la tua 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 fino all'interruzione del servizio in primo piano.

Il processo dell'app termina quando l'autorizzazione viene revocata

Se l'utente revoca l'autorizzazione una tantum, ad esempio nelle impostazioni di sistema, l'app non può accedere ai dati, a prescindere dal fatto che tu abbia avviato o meno 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 interrotto.

La volta successiva che l'utente aprirà l'app e una funzionalità dell'app richiede l'accesso alla posizione, al microfono o alla fotocamera, all'utente verrà chiesta di nuovo l'autorizzazione.

Reimposta le autorizzazioni inutilizzate

Android offre diversi modi per reimpostare le autorizzazioni di runtime inutilizzate allo stato predefinito e negato:

Rimuovi l'accesso delle app

Su Android 13 (livello API 33) e versioni successive, puoi rimuovere l'accesso dell'app alle autorizzazioni di runtime che non sono più necessarie. Quando aggiorni la tua app, esegui questo passaggio in modo che gli utenti capiscano più facilmente perché la tua app continua a richiedere autorizzazioni specifiche. Queste informazioni aiutano a conquistare la fiducia degli utenti nella tua app.

Per rimuovere l'accesso a un'autorizzazione di runtime, passa il nome di tale autorizzazione a revokeSelfPermissionOnKill(). Per rimuovere contemporaneamente l'accesso a un gruppo di autorizzazioni di runtime, trasferisci una raccolta di nomi delle autorizzazioni in revokeSelfPermissionsOnKill(). Il processo di rimozione delle autorizzazioni avviene in modo asincrono e termina tutti i processi associati all'UID dell'app.

Affinché il sistema possa rimuovere l'accesso delle autorizzazioni dell'app, tutti i processi collegati alla tua app devono essere terminati. Quando chiami l'API, il sistema determina quando è possibile terminare questi processi. In genere, il sistema attende che l'app venga eseguita per un lungo periodo di tempo in background anziché in primo piano.

Per comunicare all'utente che la tua app non richiede più l'accesso a autorizzazioni di runtime specifiche, mostra una finestra di dialogo la volta successiva che l'utente avvia l'app. La finestra 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 ha concesso all'app. Scopri di più nella guida all'ibernazione delle app.

Richiedi per 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 autorizzazioni specifiche per registri chiamate e SMS e pubblicare la tua app sul Play Store, devi chiedere all'utente di impostare l'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 istruzioni su come mostrare agli utenti una richiesta di 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 nel seguente snippet di codice:

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, esamina gli esempi di autorizzazioni

Puoi anche completare questo codelab per dimostrare le best practice relative alla privacy.