Richiedi l'accesso alla posizione in fase di runtime

Quando una funzionalità della tua app richiede l'accesso alla posizione, attendi che l'utente interagisca con la funzionalità prima di effettuare la richiesta di autorizzazione. Questo flusso di lavoro segue la best practice di richiedere le autorizzazioni di runtime nel contesto, come descritto nella guida che spiega come richiedere le autorizzazioni per le app.

La Figura 1 mostra un esempio di come eseguire questa procedura. L'app contiene una funzionalità di "condivisione della posizione" che richiede l'accesso alla posizione in primo piano. Tuttavia, l'app non richiede l'autorizzazione di accesso alla posizione finché l'utente non seleziona il pulsante Condividi posizione.

Dopo che l'utente seleziona il pulsante Condividi posizione, viene visualizzata la finestra di dialogo dell'autorizzazione di accesso alla posizione del sistema
Figura 1. Funzionalità di condivisione della posizione che richiede l'accesso alla posizione in primo piano. La funzionalità viene attivata se l'utente seleziona Consenti solo mentre l'app è in uso.

L'utente può concedere solo la posizione approssimativa

Su Android 12 (livello API 31) o versioni successive, gli utenti possono richiedere che la tua app recuperi solo informazioni sulla posizione approssimative, anche quando richiede l'autorizzazione di runtime ACCESS_FINE_LOCATION.

Per gestire questo potenziale comportamento dell'utente, non richiedere l'autorizzazione ACCESS_FINE_LOCATION da sola. Richiedi invece sia l'autorizzazione ACCESS_FINE_LOCATION che l'autorizzazione ACCESS_COARSE_LOCATION in una singola richiesta di runtime. Se provi a richiedere solo ACCESS_FINE_LOCATION, il sistema ignora la richiesta su alcune release di Android 12. Se la tua app ha come target Android 12 o versioni successive, il sistema registra il seguente messaggio di errore in Logcat:

ACCESS_FINE_LOCATION must be requested with ACCESS_COARSE_LOCATION.

Quando la tua app richiede sia ACCESS_FINE_LOCATION sia ACCESS_COARSE_LOCATION, la finestra di dialogo delle autorizzazioni di sistema include le seguenti opzioni per l'utente:

  • Precisa: consente all'app di ottenere informazioni precise sulla posizione.
  • Approssimativa: consente all'app di ottenere solo informazioni sulla posizione approssimativa.

La Figura 3 mostra che la finestra di dialogo contiene un'indicazione visiva per entrambe le opzioni, per aiutare l'utente a scegliere. Dopo aver scelto la precisione della posizione, l'utente tocca uno dei tre pulsanti per selezionare la durata della concessione dell'autorizzazione.

Su Android 12 e versioni successive, gli utenti possono accedere alle impostazioni di sistema per impostare la precisione della posizione preferita per qualsiasi app, indipendentemente dalla versione dell'SDK di destinazione dell'app. Ciò vale anche quando la tua app è installata su un dispositivo con Android 11 o versioni precedenti e l'utente esegue l'upgrade del dispositivo ad Android 12 o versioni successive.

La finestra di dialogo si riferisce solo alla posizione approssimativa e contiene 3 pulsanti, uno sopra l'altro
Figura 2. Finestra di dialogo delle autorizzazioni di sistema visualizzata quando l'app richiede solo ACCESS_COARSE_LOCATION.
La finestra di dialogo contiene due insiemi di opzioni, una sopra l'altra
Figura 3. Finestra di dialogo delle autorizzazioni di sistema visualizzata quando la tua app richiede sia ACCESS_FINE_LOCATION sia ACCESS_COARSE_LOCATION in una singola richiesta di runtime.

La scelta dell'utente influisce sulle concessioni delle autorizzazioni

La tabella seguente mostra le autorizzazioni concesse dalla piattaforma alla tua app, in base alle opzioni scelte dall'utente nella finestra di dialogo delle autorizzazioni di runtime:

Esatta Approssimativa
Mentre usi l'app ACCESS_FINE_LOCATION e
ACCESS_COARSE_LOCATION
ACCESS_COARSE_LOCATION
Solo questa volta ACCESS_FINE_LOCATION e
ACCESS_COARSE_LOCATION
ACCESS_COARSE_LOCATION
Nega Nessuna autorizzazione di accesso alla posizione Nessuna autorizzazione di accesso alla posizione

Per determinare quali autorizzazioni sono state concesse alla tua app dal sistema, controlla il valore restituito della richiesta di autorizzazione. Puoi utilizzare le librerie Jetpack in un codice simile al seguente oppure puoi utilizzare le librerie della piattaforma, in cui gestisci autonomamente il codice di richiesta di autorizzazione.

Kotlin

@RequiresApi(Build.VERSION_CODES.N)
fun requestPermissions() {
    val locationPermissionRequest = registerForActivityResult(
        ActivityResultContracts.RequestMultiplePermissions()
    ) { permissions ->
        when {
            permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> {
                // Precise location access granted.
            }
            permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> {
                // Only approximate location access granted.
            }
            else -> {
                // No location access granted.
            }
        }
    }

    // Before you perform the actual permission request, check whether your app
    // already has the permissions, and whether your app needs to show a permission
    // rationale dialog. For more details, see Request permissions:
    // https://developer.android.com/training/permissions/requesting#request-permission
    locationPermissionRequest.launch(
        arrayOf(
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
        )
    )
}

Java

private void requestPermissions() {

    ActivityResultLauncher<String[]> locationPermissionRequest =
            registerForActivityResult(new ActivityResultContracts
                            .RequestMultiplePermissions(), result -> {

                Boolean fineLocationGranted = null;
                Boolean coarseLocationGranted = null;

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    fineLocationGranted = result.getOrDefault(
                            Manifest.permission.ACCESS_FINE_LOCATION, false);
                    coarseLocationGranted = result.getOrDefault(
                            Manifest.permission.ACCESS_COARSE_LOCATION,false);
                }

                if (fineLocationGranted != null && fineLocationGranted) {
                    // Precise location access granted.
                } else if (coarseLocationGranted != null && coarseLocationGranted) {
                    // Only approximate location access granted.
                } else {
                    // No location access granted.
                }
            }
        );

    // ...

    // Before you perform the actual permission request, check whether your app
    // already has the permissions, and whether your app needs to show a permission
    // rationale dialog. For more details, see Request permissions.
    locationPermissionRequest.launch(new String[] {
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.ACCESS_COARSE_LOCATION
    });
}

Richiedere un upgrade alla posizione esatta

Puoi chiedere all'utente di eseguire l'upgrade dell'accesso della tua app dalla posizione approssimativa alla posizione precisa. Tuttavia, prima di chiedere all'utente di eseguire l'upgrade dell'accesso della tua app alla posizione esatta, valuta se il caso d'uso della tua app richiede assolutamente questo livello di precisione. Se la tua app deve accoppiare un dispositivo con dispositivi nelle vicinanze tramite Bluetooth o Wi-Fi, ti consigliamo di utilizzare l'accoppiamento di dispositivi companion o le autorizzazioni Bluetooth anziché richiedere l'autorizzazione ACCESS_FINE_LOCATION.

Per richiedere all'utente di eseguire l'upgrade dell'accesso alla posizione della tua app da approssimativo a preciso:

  1. Se necessario, spiega perché la tua app ha bisogno dell'autorizzazione.
  2. Richiedi di nuovo le autorizzazioni ACCESS_FINE_LOCATION e ACCESS_COARSE_LOCATION. Poiché l'utente ha già consentito al sistema di concedere la posizione approssimativa alla tua app, questa volta la finestra di dialogo di sistema è diversa, come mostrato nelle figure 4 e 5:
La finestra di dialogo contiene le opzioni &quot;Modifica per avere una posizione precisa&quot;, &quot;Solo questa volta&quot; e &quot;Rifiuta&quot;.
Figura 4. In precedenza, l'utente aveva selezionato Approssimativa e Durante l'uso dell'app (nella finestra di dialogo della Figura 3).
La finestra di dialogo contiene le opzioni &quot;Solo questa volta&quot; e
         &#39;Rifiuta&quot;.
Figura 5. L'utente ha precedentemente selezionato Approssimativa e Solo questa volta (nella finestra di dialogo della figura 3).

Richiedi inizialmente solo la posizione in primo piano

Anche se diverse funzionalità della tua app richiedono l'accesso alla posizione, è probabile che solo alcune di queste richiedano l'accesso alla posizione in background. Pertanto, è consigliabile che la tua app esegua richieste incrementali per le autorizzazioni di accesso alla posizione, chiedendo prima l'accesso alla posizione in primo piano e poi l'accesso alla posizione in background. Se esegui richieste incrementali, offri agli utenti maggiore controllo e trasparenza, perché possono capire meglio quali funzionalità della tua app richiedono l'accesso alla posizione in background.

La Figura 6 mostra un esempio di app progettata per gestire richieste incrementali. Sia la funzionalità "Mostra posizione attuale" sia la funzionalità "Consiglia luoghi nelle vicinanze" richiedono l'accesso alla posizione in primo piano. Tuttavia, solo la funzionalità "Consiglia luoghi nelle vicinanze" richiede l'accesso alla posizione in background.

Il pulsante che attiva l&#39;accesso alla posizione in primo piano è situato a metà della lunghezza dello schermo rispetto al pulsante che attiva la posizione in background
Figura 6. Entrambe le funzionalità richiedono l'accesso alla posizione, ma solo la funzionalità "Consiglia funzionalità nelle vicinanze" richiede l'accesso alla posizione in background.

La procedura per eseguire richieste incrementali è la seguente:

  1. All'inizio, la tua app deve indirizzare gli utenti alle funzionalità che richiedono l'accesso alla posizione in primo piano, ad esempio la funzionalità "Condividi posizione" nella Figura 1 o la funzionalità "Mostra posizione attuale" nella Figura 2.

    Ti consigliamo di disattivare l'accesso degli utenti alle funzionalità che richiedono l'accesso alla posizione in background finché la tua app non avrà l'accesso alla posizione in primo piano.

  2. In un secondo momento, quando l'utente esplora funzionalità che richiedono l'accesso alla posizione in background, puoi richiedere l'accesso alla posizione in background.

Risorse aggiuntive

Per ulteriori informazioni sulle autorizzazioni di accesso alla posizione in Android, consulta i seguenti materiali:

Codelab

Video

Campioni

  • App di esempio per dimostrare l'utilizzo delle autorizzazioni di accesso alla posizione.