Richiedi autorizzazioni di runtime

Ogni app 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 consenta l'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 runtime seguendo la procedura descritta 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 precedente, 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 l'autorizzazione nel contesto, quando l'utente inizia a interagire con la funzionalità che la richiede.
  • Non bloccare l'utente. Fornisci sempre l'opzione per annullare un flusso di interfaccia utente didattico, ad esempio un flusso che spiega il motivo per cui vuoi richiedere le autorizzazioni.
  • Se l'utente nega o revoca un'autorizzazione necessaria per una funzionalità, esegui una 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 devi presupporre che le autorizzazioni siano incluse nello 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 nella tua app, valuta se l'app deve farlo. Nella tua app puoi adempiere a numerosi casi d'uso, ad esempio scattare foto, mettere in pausa la riproduzione di contenuti multimediali e pubblicare 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 potrebbero dover richiedere l'app.
  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 privati degli utenti.
  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, la tua app può richiedere l'autorizzazione di runtime necessaria per accedere a tali dati.
  4. Verifica se l'utente ha già concesso l'autorizzazione di runtime richiesta dalla tua app. In questo caso, l'app può accedere ai dati privati dell'utente. In caso contrario, vai al passaggio successivo.

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

  5. Controlla se la tua app deve mostrare una motivazione all'utente, spiegando perché è necessario che l'utente conceda una specifica 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.

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

  6. Richiedi l'autorizzazione di runtime necessaria alla 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 per la tua app, puoi accedere ai dati utente privati. Se invece l'utente ha negato l'autorizzazione, riduci automaticamente la tua esperienza nell'app in modo che fornisca funzionalità all'utente senza le informazioni protette da questa 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 la dichiarazione e la richiesta di 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 la tua app abbia l'autorizzazione.

Spiega perché la tua app richiede l'autorizzazione

La finestra di dialogo delle autorizzazioni mostrata dal sistema quando chiami requestPermissions() indica l'autorizzazione richiesta dalla tua app, ma non il motivo. In alcuni casi, l'utente potrebbe trovare quel rompicapo. Prima di chiamare requestPermissions(), è bene spiegare all'utente perché la tua app richiede le autorizzazioni.

Le ricerche dimostrano che gli utenti sono molto più a loro agio con le richieste di autorizzazioni se sanno perché l'app le richiede, 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 esplicitamente quali di queste autorizzazioni stai usando e perché. Ad esempio, se utilizzi solo la posizione approssimativa, informa l'utente nella descrizione dell'app o negli articoli del Centro assistenza.

In determinate condizioni, è utile anche informare in tempo reale gli utenti dell'accesso ai dati sensibili. Ad esempio, se accedi alla fotocamera o al microfono, è consigliabile 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'utente non stia raccogliendo i dati furtivamente.

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é sono necessarie le 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 il motivo per cui la funzionalità che l'utente vuole attivare richiede un'autorizzazione specifica.

Inoltre, se la tua app richiede un'autorizzazione relativa alla posizione, al microfono o alla fotocamera, ti consigliamo di spiegare il motivo per cui l'app deve accedere a queste informazioni.

Richiedi autorizzazioni

Dopo che l'utente ha visualizzato un'interfaccia utente didattica o se il valore restituito 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 un'autorizzazione specifica alla tua app.

A questo scopo, utilizza il contratto RequestPermission, incluso in una libreria AndroidX, in cui consenti al sistema di gestire per te il codice della richiesta di autorizzazione. Poiché l'utilizzo del contratto RequestPermission semplifica la logica, è la soluzione consigliata, quando possibile. Tuttavia, se necessario, puoi anche gestire autonomamente un codice di richiesta come parte della richiesta di autorizzazione e includerlo 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 autorizzazioni, aggiungi dipendenze nelle seguenti librerie nel file build.gradle del modulo:

Successivamente potrai utilizzare una delle seguenti classi:

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

    Dopo la chiamata a launch(), viene visualizzata la finestra di dialogo delle autorizzazioni di sistema. Quando l'utente effettua una scelta, il sistema richiama in modo asincrono la tua implementazione 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 contesto, modifica la UI dell'app in modo che gli utenti capiscano più facilmente perché una funzionalità della tua app richiede una particolare 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 semplificare l'uso del sistema e la tua app non deve basarsi su autorizzazioni associate o esterne a un gruppo di autorizzazioni specifico.

Il seguente snippet di codice mostra come gestire la risposta 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, se necessario:

Kotlin

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.REQUESTED_PERMISSION
            ) == PackageManager.PERMISSION_GRANTED -> {
        // You can use the API that requires the permission.
    }
    shouldShowRequestPermissionRationale(...) -> {
        // 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 (shouldShowRequestPermissionRationale(...)) {
    // 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(...)
    }
    shouldShowRequestPermissionRationale(...) -> {
        // 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 (shouldShowRequestPermissionRationale(...)) {
    // 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 risponde alla finestra di dialogo delle autorizzazioni di sistema, il sistema richiama l'implementazione di onRequestPermissionsResult() dell'app. Il sistema trasmette la risposta dell'utente alla finestra di dialogo dell'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.
    }
}

Richiedere 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 da richiedere e le modalità di richiesta dipendono dai requisiti di località per il caso d'uso dell'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, una funzione 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à 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 viene posizionata in background, ad esempio quando l'utente preme il pulsante Home sul dispositivo o disattiva la visualizzazione 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, è 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à della posizione in primo piano quando la tua app richiede l'autorizzazione ACCESS_COARSE_LOCATION o 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 del 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 e si riaccendano quando l'utente torna a casa.

Il sistema considera che l'app utilizzi la posizione in background se accede alla posizione attuale del dispositivo in situazioni diverse 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, 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 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 dell'app in cui sono disponibili funzionalità limitate, in quanto l'app non dispone dell'autorizzazione necessaria. Ecco alcuni esempi di cosa potresti fare:

    • Mostra un messaggio in cui sarebbero stati visualizzati i risultati o i dati dell'elemento.
    • Visualizza un pulsante diverso contenente un'icona e un colore di errore.
  • Indica dati specifici: Non mostrare 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 Nega per un'autorizzazione specifica più di una volta durante il ciclo di installazione dell'app su un dispositivo, l'utente 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 la tua 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 nega una richiesta di autorizzazione più di una volta, questo viene considerato un rifiuto 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 scontato tutto il comportamento automatico. Ogni volta che la tua app deve accedere a funzionalità che richiedono un'autorizzazione, verifica che all'app venga comunque concessa questa autorizzazione.

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

Controlla 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 scopi di debug e test), utilizza il seguente comando:

adb shell dumpsys package PACKAGE_NAME

dove PACKAGE_NAME è il nome del pacchetto da ispezionare.

L'output del comando contiene sezioni simili 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 negate in modo permanente selezionando Rifiuta due volte vengono segnalate da USER_FIXED.

Per assicurarti che i tester vedano la finestra di dialogo di richiesta durante il test, reimposta questi flag quando hai terminato il debug dell'app. A questo 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 delle autorizzazioni.

Autorizzazioni una tantum

L&#39;opzione &quot;Solo questa volta&quot; è il secondo dei tre pulsanti nella 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 l'app richiede un'autorizzazione relativa alla posizione, al microfono o alla fotocamera, la finestra di dialogo delle autorizzazioni rivolta agli utenti contiene un'opzione denominata 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 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 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 termina quando l'autorizzazione viene revocata

Se l'utente revoca l'autorizzazione una tantum, ad esempio nelle impostazioni di sistema, la tua app non può accedere ai dati, 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 alla tua app, il processo dell'app viene interrotto.

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

Reimposta le autorizzazioni inutilizzate

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

Rimuovere l'accesso delle app

Su Android 13 (livello API 33) e versioni successive, puoi rimuovere l'accesso della tua app alle autorizzazioni di runtime che non sono 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 informazioni aiutano a rafforzare la fiducia degli utenti nei confronti della tua app.

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

Per consentire al sistema di rimuovere l'accesso della tua app alle autorizzazioni, tutti i processi collegati all'app devono essere interrotti. Quando chiami l'API, il sistema determina quando è possibile terminare questi processi in sicurezza. Di solito, 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 ad autorizzazioni di runtime specifiche, mostra una finestra di dialogo la prossima volta che l'utente la avvia. Può includere l'elenco delle autorizzazioni.

Reimpostare automaticamente le autorizzazioni per le 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 alla tua app. Scopri di più nella guida all'ibernazione delle app.

Richiedere 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 i registri chiamate e gli SMS e pubblicare la tua app sul Play Store, devi chiedere all'utente di impostare la tua app come gestore predefinito per una funzione di sistema di base prima di richiedere queste autorizzazioni di runtime.

Per ulteriori informazioni sui gestori predefiniti, incluse le 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, consulta i seguenti articoli:

Per scoprire di più sulla richiesta di autorizzazioni, esamina gli esempi di autorizzazioni

Puoi anche completare questo codelab per dimostrare le best practice in materia di privacy.