Richiedi autorizzazioni di runtime

Ogni app Android viene eseguita in una sandbox con 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 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 esecuzione 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 è necessario completare i passaggi rimanenti in questa pagina.

Principi di base

I principi di base per la richiesta di autorizzazioni in fase di esecuzione sono i seguenti:

  • Chiedi un'autorizzazione contestuale quando l'utente inizia a interagire con la funzionalità che la richiede.
  • Non bloccare l'utente. Fornisci sempre l'opzione per annullare un flusso della UI didattico, ad esempio un flusso che spiega il motivo 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 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 compaiano 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 mostrate 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 è necessario. 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 concludi che la tua app deve dichiarare e richiedere autorizzazioni di runtime, completa i seguenti 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 siano associate a autorizzazioni di runtime specifiche. Comunica agli utenti quali azioni potrebbero richiedere la concessione dell'autorizzazione per consentire 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 specifici dati privati dell'utente. A quel punto, la tua app può richiedere l'autorizzazione di runtime necessaria per accedere ai dati.
  4. Verifica 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 di disporre di un'autorizzazione ogni volta che esegui un'operazione che richiede l'autorizzazione.

  5. Verifica se la tua app deve mostrare una motivazione all'utente, spiegando perché ha bisogno 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 dell'interfaccia utente.

    Tuttavia, se il sistema stabilisce che la tua app deve mostrare una motivazione, presentala all'utente in un elemento dell'interfaccia utente. In questa motivazione, spiega chiaramente a quali dati sta tentando di accedere la tua app e quali vantaggi l'app può offrire all'utente se concede l'autorizzazione di runtime. Dopo che l'utente ha confermato la motivazione, vai al passaggio successivo.

  6. Richiedi l'autorizzazione di runtime necessaria alla tua app per accedere ai dati utente privati. Il sistema mostra un prompt per l'autorizzazione di runtime, come quello mostrato nella pagina Panoramica delle autorizzazioni.

  7. Controlla la risposta dell'utente, ovvero 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 privati dell'utente. Se invece l'utente ha negato l'autorizzazione, riduci la tua esperienza con l'app in modo da fornire all'utente la funzionalità senza le informazioni protette da quell'autorizzazione.

La figura 1 mostra il flusso di lavoro e l'insieme di decisioni associate a questo procedura:

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 una determinata autorizzazione, passala al metodo ContextCompat.checkSelfPermission(). Questo metodo restituisce PERMISSION_GRANTED o PERMISSION_DENIED, a seconda che la tua 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 quale autorizzazione richiede la tua app, ma non lo fa per quale motivo. In alcuni casi, l'utente potrebbe trovare questa situazione sconcertante. È buona norma spiegare all'utente perché la tua app richiede le autorizzazioni prima di chiamare requestPermissions().

Gli studi dimostrano che gli utenti sono molto più a loro agio con le richieste di autorizzazione se sanno perché l'app le richiede, ad esempio se l'autorizzazione è necessaria per supportare una funzionalità di base 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 esplicitamente quali 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 alla tua 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, è buona norma informare l'utente utilizzando un'icona di notifica da qualche parte nell'app o nella barra delle notifiche (se l'app è in esecuzione in background), in modo che non sembri che tu stia raccogliendo i dati di nascosto.

In definitiva, se devi richiedere un'autorizzazione per far funzionare qualcosa nella tua app, ma il motivo non è chiaro per l'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 il motivo per cui la funzionalità che l'utente vuole attivare 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é la tua app ha bisogno dell'accesso a queste informazioni.

Richiedi autorizzazioni

Dopo che l'utente ha visualizzato un'interfaccia utente informativa o se il valore restituito di shouldShowRequestPermissionRationale() indica che non è necessario mostrare un'interfaccia utente informativa, richiedi l'autorizzazione. Gli utenti visualizzano una finestra di dialogo per le 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 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 per le autorizzazioni.

Consenti al sistema di gestire il codice di richiesta di autorizzazione

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

Puoi quindi utilizzare una delle seguenti classi:

I passaggi riportati di seguito mostrano 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(). ActivityResultCallback definisce in che modo la tua 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, se necessario, chiama il metodo launch() sull'istanza di ActivityResultLauncher che hai salvato 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 all'utente maggiori informazioni o un contesto più ampio, modifica l'interfaccia utente 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, puoi modificare il testo del 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 mostra la procedura consigliata per verificare la presenza di un'autorizzazione e per 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);
}

Gestire autonomamente il codice di 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 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 invoca l'implementazione di onRequestPermissionsResult() della tua app. Il sistema passa la risposta dell'utente alla finestra di dialogo delle autorizzazioni, nonché il codice di richiesta che hai definito, come mostrato nello snippet di codice seguente:

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 il modo in cui vengono richieste dipendono dai requisiti di accesso alla posizione 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 solo una 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 corrente del dispositivo in una delle seguenti situazioni:

  • È visibile un'attività che appartiene alla tua app.
  • La tua app esegue un servizio in primo piano. Quando è in esecuzione un servizio in primo piano, il sistema avvisa l'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 disattiva 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 nel seguente snippet di codice. Nelle versioni precedenti di Android, è consigliabile 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 di 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 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 utilizzi la posizione in background se accede alla posizione corrente del dispositivo in qualsiasi situazione diversa da quelle descritte nella sezione sulla 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 l'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 dell'autorizzazione

Se l'utente nega una richiesta di autorizzazione, la tua app deve aiutarlo a comprendere le implicazioni della mancata autorizzazione. In particolare, la tua app deve informare gli utenti delle funzionalità che non funzionano a causa della mancanza dell'autorizzazione. A questo scopo, tieni presenti le seguenti best practice:

  • Guida 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.
  • Fornisci informazioni specifiche. Non mostrare un messaggio generico. Indica invece chiaramente 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 impedisca 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 vita dell'installazione dell'app su un dispositivo, non vedrà 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 non avessero precedentemente 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 chiedere agli utenti le autorizzazioni solo quando devono 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 debba fare nulla. Un'autorizzazione può anche essere concessa automaticamente. È importante non dare nulla per scontato in merito al comportamento automatico. Ogni volta che la tua app deve accedere a funzionalità che richiedono un'autorizzazione, controlla che l'autorizzazione sia ancora concessa all'app.

Per offrire la migliore esperienza utente quando chiedi le autorizzazioni per le app, consulta anche le best practice per le autorizzazioni per le app.

Controllare lo stato del rifiuto durante i test e il debug

Per identificare se a un'app sono state negate definitivamente 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 sono contrassegnate da USER_SET. Le autorizzazioni che sono state rifiutate definitivamente 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 di tre pulsanti nella dialog.
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 rivolta all'utente contiene un'opzione denominata Solo questa volta, come mostrato nella figura 2. Se l'utente seleziona questa opzione nella dialog, 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:

  • Quando 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 la tua 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 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 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ù necessarie. Quando aggiorni l'app, esegui questo passaggio in modo che gli utenti siano più propensi a capire perché la tua app continua a richiedere autorizzazioni specifiche. Queste conoscenze contribuiscono a aumentare la fiducia degli utenti nei confronti della tua app.

Per rimuovere l'accesso a un'autorizzazione di runtime, passa il nome dell'autorizzazione in revokeSelfPermissionOnKill(). Per rimuovere contemporaneamente l'accesso a un gruppo di autorizzazioni di runtime, passa una raccolta di nomi di autorizzazione a 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 interrompere queste procedure. In genere, il sistema attende fino a quando l'app non è in esecuzione per un periodo di tempo prolungato in background invece che in primo piano.

Per informare l'utente che la tua app non richiede più l'accesso a autorizzazioni di runtime specifiche, mostra una finestra di dialogo alla successiva apertura 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 aveva concesso alla tua app. Scopri di più nella guida sull'ibernazione delle app.

Se necessario, richiedi di diventare il gestore predefinito

Alcune app dipendono dall'accesso a informazioni sensibili dell'utente relative a registri chiamate e messaggi 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 indicazioni su come mostrare 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, consulta i campioni di autorizzazioni

Puoi anche completare questo codelab che mostra le migliori pratiche per la privacy.