Richiedi autorizzazioni di runtime

Ogni app Android viene eseguita in una sandbox ad accesso limitato. Se l'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 eventuali 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 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 è necessario completare i passaggi rimanenti in questa pagina.

Principi di base

Di seguito sono riportati i principi di base per la richiesta di autorizzazioni in fase di runtime:

  • Chiedi un'autorizzazione nel contesto, quando l'utente inizia a interagire con la funzionalità che la richiede.
  • Non bloccare l'utente. Fornisci sempre la possibilità di annullare un flusso di UI didattico, ad esempio un flusso che spiega la motivazione della richiesta di autorizzazioni.
  • Se l'utente nega o revoca un'autorizzazione necessaria per una funzionalità, degrada delicatamente la tua app in modo che l'utente possa continuare a utilizzarla, magari disattivando la funzionalità che richiede l'autorizzazione.
  • Non dare per scontato alcun comportamento del sistema. Ad esempio, non dare per scontato che le autorizzazioni siano presenti 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.

Flusso di lavoro per la richiesta di autorizzazioni

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

Se concludi che la tua app deve 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'esperienza utente della tua app in modo che azioni specifiche al suo interno siano associate ad specifiche autorizzazioni di runtime. Fai sapere agli utenti quali azioni potrebbero richiedere loro di concedere l'autorizzazione alla tua app per accedere ai dati utente privati.
  3. Attendi che l'utente richiami l'attività o l'azione nella tua app che richiede l'accesso a specifici dati privati dell'utente. A quel punto, la tua app può richiedere l'autorizzazione di runtime necessaria per accedere ai dati.
  4. Controlla se l'utente ha già concesso l'autorizzazione di runtime richiesta dalla tua app. In questo caso, la tua 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.

  5. 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 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, presenta la motivazione all'utente in un elemento dell'interfaccia utente. Per questa logica, spiega chiaramente a quali dati l'app tenta di accedere e quali vantaggi può offrire all'utente se viene concessa l'autorizzazione di runtime. Dopo che l'utente ha accettato la motivazione, vai al passaggio successivo.

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

  7. Verifica 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 invece l'utente ha negato l'autorizzazione, riduci in modo corretto l'esperienza con l'app in modo che fornisca all'utente funzionalità senza le informazioni protette da quell'autorizzazione.

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

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

Determinare se alla tua 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 la tua app disponga o meno dell'autorizzazione.

Spiega perché 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 spiega il motivo. In alcuni casi, l'utente potrebbe trovare questo sconcertante. Ti consigliamo di spiegare all'utente perché la tua app richiede le autorizzazioni prima di chiamare requestPermissions().

La ricerca dimostra che gli utenti sono molto più a loro agio con 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, aiuta a elencare esplicitamente quali di queste autorizzazioni stai utilizzando e perché. Ad esempio, se utilizzi soltanto la posizione approssimativa, comunicalo all'utente nella descrizione dell'app o negli articoli del Centro assistenza relativi all'app.

In determinate condizioni, è anche utile informare gli utenti dell'accesso ai dati sensibili in tempo reale. Ad esempio, se accedi alla fotocamera o al microfono, è una buona idea informare l'utente utilizzando un'icona di notifica da qualche parte dell'app o nella barra delle notifiche (se l'applicazione è in esecuzione in background), in modo che non sembri che tu stia raccogliendo dati in modo furtivo.

In definitiva, se devi richiedere un'autorizzazione per far funzionare qualcosa nella tua app, ma il motivo non è chiaro all'utente, trova 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 formativa. In questa UI, descrivi perché la funzionalità che l'utente vuole abilitare richiede una determinata autorizzazione.

Inoltre, se l'app richiede un'autorizzazione relativa alla posizione, al microfono o alla fotocamera, valuta la possibilità di spiegare perché l'app ha bisogno dell'accesso a queste informazioni.

Richiedi autorizzazioni

Dopo che l'utente ha visualizzato un'interfaccia utente didattica o il valore restituito di shouldShowRequestPermissionRationale() indica che non è necessario mostrare un'interfaccia utente indicativa, richiedi l'autorizzazione. Gli utenti vedono una finestra di dialogo dell'autorizzazione di sistema in cui possono scegliere se concedere 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, se possibile. Tuttavia, se necessario, puoi anche gestire personalmente 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 di richiesta di autorizzazione

Per consentire al sistema di gestire il codice di richiesta associato a una richiesta di autorizzazione, aggiungi le dipendenze delle seguenti librerie nel file build.gradle del modulo:

Puoi quindi utilizzare una delle seguenti classi:

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

  1. Nella logica di inizializzazione dell'attività o del frammento, 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.

    Tieni 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() sull'istanza di ActivityResultLauncher salvata nel passaggio precedente.

    Dopo aver chiamato launch(), viene visualizzata la finestra di dialogo delle autorizzazioni di sistema. Quando l'utente fa una scelta, il sistema richiama in modo asincrono l'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 dell'app in modo che sia più facile comprendere perché una funzionalità dell'app richiede una determinata autorizzazione. Ad esempio, potresti modificare il testo nel pulsante che attiva la funzionalità.

    Inoltre, il testo nella finestra di dialogo dell'autorizzazione di sistema fa riferimento al gruppo di autorizzazioni associato all'autorizzazione richiesta. Questo raggruppamento di autorizzazioni è progettato per la facilità d'uso del sistema e la tua app non deve fare affidamento su autorizzazioni che appartengono 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 illustra 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);
}

Gestire autonomamente il codice della richiesta di autorizzazione

Anziché 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);
}

Dopo che l'utente ha risposto 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 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 autorizzazioni 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 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 informazioni sulla posizione solo una volta o per un determinato periodo di tempo, tale 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 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 utilizzi 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 è in esecuzione un servizio in primo piano, il sistema aumenta la consapevolezza degli utenti 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 disattiva il display del dispositivo.

    Su Android 10 (livello API 29) e versioni successive, devi dichiarare un tipo di servizio in primo piano 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 la tua app richiede l'autorizzazione ACCESS_COARSE_LOCATION o l'autorizzazione 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à all'interno dell'app condivide costantemente la posizione con altri utenti o utilizza l'API Geofencing. Ecco alcuni esempi:

  • All'interno di un'app di condivisione della posizione del gruppo Famiglia, una funzionalità consente agli utenti di condividere continuamente la posizione con i membri del gruppo.
  • 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 rientra.

Il sistema considera che la tua app utilizza la posizione in background se accede alla posizione attuale del dispositivo in qualsiasi situazione diversa da quella descritta nella sezione relativa alla posizione in primo piano. La precisione della posizione in background è uguale alla precisione della posizione 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 dell'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>

Gestire il rifiuto di autorizzazioni

Se l'utente rifiuta una richiesta di autorizzazione, l'app deve aiutare gli utenti a comprendere le implicazioni del rifiuto dell'autorizzazione. In particolare, la tua app deve informare gli utenti delle funzionalità che non funzionano a causa della mancanza dell'autorizzazione. Per farlo, tieni presente le seguenti best practice:

  • Indirizza l'attenzione dell'utente. Evidenzia una parte specifica dell'interfaccia utente dell'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 in cui sarebbero stati visualizzati i risultati o i dati dell'elemento.
    • Mostra un pulsante diverso contenente un'icona e un colore di errore.
  • Scrivi un titolo specifico. Non mostrare un messaggio generico. Indica 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 la tua 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 un'autorizzazione specifica più di una volta durante il ciclo di installazione dell'app su un dispositivo, non vede la finestra di dialogo delle autorizzazioni di sistema se l'app richiede nuovamente 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 l'app richiedeva un'autorizzazione, a meno che in precedenza non avessero selezionato una casella di controllo o un'opzione "Non chiedere più".

Se un utente rifiuta una richiesta di autorizzazione più di una volta, il rifiuto viene considerato permanente. È molto importante richiedere agli utenti le autorizzazioni 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. Potrebbe anche essere concessa automaticamente un'autorizzazione. È importante non dare per scontato alcun comportamento automatico. Ogni volta che la tua app deve accedere a funzionalità che richiede un'autorizzazione, verifica che all'app sia ancora concessa questa autorizzazione.

Per offrire la migliore esperienza utente quando richiedi le autorizzazioni app, vedi anche Best practice per le autorizzazioni app.

Controlla lo stato del 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 simili alla seguente:

...
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 vengono segnalate da USER_SET. Le autorizzazioni che sono state rifiutate in modo permanente selezionando Rifiuta due volte sono contrassegnate da USER_FIXED.

Per assicurarti che i tester vedano la finestra di dialogo di 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 app per Android, visita la pagina di riferimento dell'API permissions.

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 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 rivolte agli utenti contiene un'opzione chiamata Solo questa volta, come mostrata 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 potrà 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 quindi 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 si interrompe quando viene revocata l'autorizzazione

Se l'utente revoca l'autorizzazione una tantum, ad esempio nelle impostazioni di sistema, la tua 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 dell'app, il processo dell'app viene terminato.

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

Reimposta le autorizzazioni inutilizzate

Android offre diversi modi per ripristinare lo stato predefinito delle autorizzazioni di runtime inutilizzate:

Rimuovere l'accesso delle app

Su Android 13 (livello API 33) e versioni successive, puoi rimuovere l'accesso dell'app alle autorizzazioni di runtime non più richieste dall'app. Quando aggiorni l'app, esegui questo passaggio in modo che gli utenti siano più propensi a capire perché l'app continua a richiedere autorizzazioni specifiche. Queste conoscenze contribuiscono a aumentare la fiducia degli utenti verso la tua app.

Per rimuovere l'accesso a un'autorizzazione di runtime, trasmetti il nome di questa autorizzazione in revokeSelfPermissionOnKill(). Per rimuovere contemporaneamente l'accesso a un gruppo di autorizzazioni di runtime, 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 dell'app.

Affinché il sistema rimuova l'accesso dell'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 passi un lungo periodo di tempo in esecuzione 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 al successivo avvio dell'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 ha concesso all'app. Scopri di più nella guida sulla ibernazione delle app.

Richiedi di diventare il gestore predefinito, se necessario

Alcune app dipendono dall'accesso a informazioni sensibili dell'utente 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 principale prima di richiedere queste autorizzazioni di runtime.

Per ulteriori informazioni sui gestori predefiniti, incluse le indicazioni sulla visualizzazione di una richiesta relativa al gestore predefinito agli utenti, 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 che dimostra le best practice relative alla privacy.