Local aproximado

1. Introdução

No Android 12 (API de nível 31) e em versões mais recentes, os usuários têm a opção de controlar a precisão da localização que querem conceder aos apps. Nas versões anteriores do Android, a precisão da localização é controlada implicitamente pela permissão solicitado pelo app: ACCESS_FINE_LOCATION ou ACCESS_COARSE_LOCATION.

Este codelab apresenta orientações e práticas recomendadas para solicitar permissões de localização a apps destinados à versão 31 ou mais recente do SDK.

Pré-requisitos

O que você aprenderá

  • Como solicitar permissões de localização no Android S.
  • Como implementar um fluxo de solicitações de localização ideal para que os usuários possam conceder ao app permissões de localização exata.

Termos

Local exato: a granularidade da localização para a permissão ACCESS_FINE_LOCATION.

Local aproximado: a granularidade da localização para a permissão ACCESS_COARSE_LOCATION.

APIs cobertas

2. Solicitar a permissão ACCESS_FINE_LOCATION

Novo fluxo de interface

Primeiro, vamos analisar a nova interface para conhecer as mudanças na precisão da localização.

As Figuras 1a e 1b abaixo mostram a caixa de diálogo de permissões que aparece quando o app não tem as permissões ACCESS_FINE_LOCATION e ACCESS_COARSE_LOCATION.

7acc5e2fe09d67ca.jpeg a5e9363364fcc9f9.jpeg

Figura 1a: O local exato está selecionado. Figura 1b: O local aproximado está selecionado.

A Figura 2a abaixo mostra a caixa de diálogo de upgrade de permissão que aparece quando o app recebeu a permissão ACCESS_COARSE_LOCATION durante o uso. Essa caixa de diálogo será exibida se o usuário selecionar "Ao usar o app" para a localização aproximada da tela anterior (mostrada na Figura 1b).

2624d89993700ea5.jpeg

Figura 2a

A figura 2b abaixo mostra a caixa de diálogo de upgrade de permissão que aparece quando o app recebeu a permissão ACCESS_COARSE_LOCATION apenas para a sessão atual. Essa caixa de diálogo será exibida se o usuário selecionar "Somente desta vez" na tela anterior (mostrada na Figura 1b).

a2dfb923b8f3548d.jpeg

Figura 2b

3. Implementação de código

Declarar permissões de localização no manifesto do app

Para solicitar a permissão ACCESS_FINE_LOCATION, o sistema exigirá que o app declare ACCESS_FINE_LOCATION e ACCESS_COARSE_LOCATION no manifesto dele. Caso contrário, o sistema ignorará a solicitação e não concederá nenhuma das duas permissões ao app.

<manifest ... >
  <!-- Required when requesting precise location access on Android 12 (API level 31) and higher. -->
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
</manifest>

Solicitar a permissão ACCESS_FINE_LOCATION

MyActivity.kt (Kotlin)

when {
    ContextCompat.checkSelfPermission(
            CONTEXT,
            Manifest.permission.ACCESS_FINE_LOCATION
            ) == 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. In this UI,
        // include a "cancel" or "no thanks" button that allows the user to
        // continue using your app without granting the permission.
        showInContextUI(...)
    }
    else -> {
        // Ask for both the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions.
        requestPermissions(CONTEXT,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION),
                REQUEST_CODE)
    }
}

MyActivity.java (Java)

if (ContextCompat.checkSelfPermission(
        CONTEXT, Manifest.permission.ACCESS_FINE_LOCATION) ==
        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. In this UI,
    // include a "cancel" or "no thanks" button that allows the user to
    // continue using your app without granting the permission.
    showInContextUI(...);
} else {
    // Ask for both the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions.
    requestPermissions(CONTEXT,
            new String[] { Manifest.permission.ACCESS_FINE_LOCATION,
                           Manifest.permission.ACCESS_COARSE_LOCATION },
            REQUEST_CODE);
}

Processar a resposta

MyActivity.kt (Kotlin)

override fun onRequestPermissionsResult(requestCode: Int,
        permissions: Array<String>, grantResults: IntArray) {
    when (requestCode) {
        REQUEST_CODE -> {
            // If the request is cancelled, the result arrays are empty.
            if (grantResults.isNotEmpty()) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // ACCESS_FINE_LOCATION is granted
                } else if (grantResults[1] ==
                               PackageManager.PERMISSION_GRANTED) {
                    // ACCESS_COARSE_LOCATION is granted
                }
            } 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.
        }
    }
}

MyActivity.java (Java)

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
        int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE:
            // If the request is cancelled, the result arrays are empty.
            if (grantResults.length > 0) {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // ACCESS_FINE_LOCATION is granted
                } else if (grantResults[1] ==
                               PackageManager.PERMISSION_GRANTED) {
                    // ACCESS_COARSE_LOCATION is granted
                }
            } 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.
    }
}

4. Solicitar apenas a permissão ACCESS_COARSE_LOCATION

A Figura 4 mostra a caixa de diálogo de permissão que aparece quando o app solicita apenas a permissão ACCESS_COARSE_LOCATION.

9d20729f14673547.jpeg

Figura 4

Para trabalhar apenas com a permissão de localização aproximada, o app precisa declarar e processar apenas a permissão aproximada em todas as etapas.

5. Configurações de localização

A figura 5 abaixo mostra as novas configurações de permissão de localização. Há uma nova chave para os usuários controlarem se o app pode acessar a localização exata ou aproximada.

a9553249c3e2b90c.jpeg

Figura 5

6. Para apps destinados à versão 30 ou anterior do SDK

As novas opções de precisão de localização (exata/aproximada) não ficam visíveis para apps destinados à versão 30 ou anteriores do SDK.

7. Parabéns!

Você aprendeu a solicitar permissões de localização no Android 12 e conheceu vários componentes importantes dessas permissões.

Agora você pode solicitar permissões de localização para diferentes casos de uso para atender às necessidades do seu app.

Saiba mais sobre a localização: