Solicitar permissões do app

Cada app Android é executado em um sandbox com acesso limitado. Se um app precisar usar recursos ou informações fora do próprio sandbox, ele precisará solicitar a permissão apropriada. Você declara que seu app precisa de uma permissão listando-a no manifesto do app. Depois disso, é necessário solicitar que o usuário aprove cada permissão no tempo de execução (no Android 6.0 e versões posteriores).

Esta página descreve como usar a Biblioteca de Suporte do Android para verificar e solicitar permissões. O framework do Android oferece métodos semelhantes a partir do Android 6.0 (nível de API 23), mas usar a biblioteca de suporte facilita a compatibilidade com versões mais antigas do Android.

Adicionar permissões ao manifesto

Em todas as versões do Android, , para declarar que seu app precisa de uma permissão, insira um elemento <uses-permission> no manifesto como um elemento filho de alto nível<manifest>. Por exemplo, um app que precisa acessar a Internet teria a seguinte linha no manifesto:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
            package="com.example.snazzyapp">

        <uses-permission android:name="android.permission.INTERNET"/>
        <!-- other permissions go here -->

        <application ...>
            ...
        </application>
    </manifest>
    

O comportamento do sistema após a declaração de uma permissão depende da importância dela. Algumas permissões são consideradas "normais" ", então o sistema as concede na instalação." Outras permissões são consideradas "perigosas", então o usuário precisa conceder acesso ao app explicitamente. Para mais informações sobre os diferentes tipos de permissão, consulte Níveis de proteção.

Verificar permissões

Se seu app precisar de uma permissão perigosa, você precisará verificar se tem essa permissão sempre que realizar uma ação que precise dela. A partir do Android 6.0 (nível de API 23), os usuários podem revogar permissões de qualquer app a qualquer momento, mesmo que o app seja destinado a um nível de API anterior. Portanto, mesmo que o app tenha usado a câmera ontem, ele não pode presumir que ainda tenha essa permissão hoje.

Para verificar se você tem uma permissão, chame o método ContextCompat.checkSelfPermission(). Por exemplo, este snippet mostra como verificar se a atividade tem permissão para escrever no calendário:

Kotlin

    if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission is not granted
    }
    

Java

    if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_CALENDAR)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission is not granted
    }
    

Se o app tiver a permissão, o método retornará PERMISSION_GRANTED e o app poderá continuar com a operação. Se o app não tiver a permissão, o método retornará PERMISSION_DENIED e o app precisará solicitar a permissão do usuário explicitamente.

Solicitar permissões

Quando seu app recebe PERMISSION_DENIED de checkSelfPermission(), é necessário solicitar essa permissão ao usuário. O Android oferece vários métodos que podem ser usados para solicitar uma permissão, como requestPermissions(), conforme mostrado no snippet de código abaixo. Chamar esses métodos exibe uma caixa de diálogo padrão do Android que não pode ser personalizada.

A forma como isso será exibido para o usuário depende da versão do dispositivo Android e da versão de destino do seu aplicativo, como descrito em Visão geral de permissões.

Explicar por que o app precisa das permissões

Em algumas circunstâncias, pode ser necessário ajudar o usuário a entender por que seu app precisa de uma permissão. Por exemplo, se um usuário iniciar um app de fotografia, ele provavelmente não se surpreenderá se o app solicitar permissão para usar a câmera, mas talvez não entenda por que o app quer acessar a localização ou os contatos do usuário. Antes de solicitar uma permissão, considere fornecer uma explicação ao usuário. Lembre-se de não sobrecarregar o usuário com explicações. Se você fornecer explicações demais, o usuário poderá achar o app frustrante e removê-lo.

Uma possível abordagem é fornecer uma explicação apenas se o usuário já tiver negado uma solicitação de permissão. O Android tem um método utilitário, shouldShowRequestPermissionRationale(), que retornará true se o usuário tiver negado a solicitação. O método retornará false se um usuário tiver negado uma permissão e selecionado a opção Não perguntar novamente na caixa de diálogo ou se uma política do dispositivo proibir a permissão.

Se um usuário continua tentando usar um recurso que precisa de uma permissão, mas recusa a solicitação de permissão, isso provavelmente indica que o usuário não entende por que o app precisa dessa permissão para utilizar o recurso em questão. Em uma situação como essa, é recomendável fornecer uma explicação.

Veja mais orientações sobre como criar uma boa experiência de usuário ao pedir permissões em Práticas recomendadas de permissões do app.

Pedir para se tornar o gerenciador padrão, se necessário

Alguns apps dependem do acesso a informações confidenciais do usuário relacionadas a registros de chamadas e mensagens SMS. Se você quiser solicitar permissões especificamente para registros de chamadas e mensagens SMS e publicar seu app na Play Store, precisará solicitar que o usuário configure seu app como o gerenciador padrão de uma função principal do sistema antes de solicitar permissões no momento da execução.

Para ver mais informações sobre gerenciadores padrão, incluindo orientações sobre como mostrar uma solicitação de gerenciador padrão para o usuário, consulte o guia sobre permissões usadas somente em gerenciadores padrão.

Solicitar as permissões necessárias

Se seu app ainda não tiver a permissão de que precisa, ele precisa chamar um dos métodos requestPermissions() para solicitar as permissões adequadas. Seu app passa as permissões desejadas e um código de solicitação na forma de um número inteiro que você especifica para identificar a solicitação de permissão. Esse método funciona de forma assíncrona: ele retorna imediatamente e, depois que o usuário responde à notificação, o sistema chama o método de callback do app com os resultados, passando o mesmo código de solicitação que o app passou para requestPermissions().

O código a seguir verifica se o app tem permissão para ler os contatos do usuário. Se não houver permissão, ele verificará a necessidade de exibir uma explicação para a solicitação e, se nenhuma explicação for necessária, ele solicitará a permissão:

Kotlin

    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.READ_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {

        // Permission is not granted
        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.READ_CONTACTS)) {
            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
        } else {
            // No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(thisActivity,
                    arrayOf(Manifest.permission.READ_CONTACTS),
                    MY_PERMISSIONS_REQUEST_READ_CONTACTS)

            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    } else {
        // Permission has already been granted
    }
    

Java

    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(thisActivity,
            Manifest.permission.READ_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {

        // Permission is not granted
        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.READ_CONTACTS)) {
            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
        } else {
            // No explanation needed; request the permission
            ActivityCompat.requestPermissions(thisActivity,
                    new String[]{Manifest.permission.READ_CONTACTS},
                    MY_PERMISSIONS_REQUEST_READ_CONTACTS);

            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    } else {
        // Permission has already been granted
    }
    

A solicitação exibida pelo sistema descreve o grupo de permissões que seu app precisa acessar, não a permissão específica.

Observação: quando seu app chama requestPermissions(), o sistema mostra uma caixa de diálogo padrão ao usuário. Seu app não pode configurar ou alterar essa caixa de diálogo. Se precisar fornecer informações ou explicações ao usuário, faça isso antes de chamar requestPermissions(), conforme descrito na seção Explique por que o app precisa das permissões.

Lidar com a resposta de solicitação de permissões

Quando o usuário responde à solicitação de permissão do seu app, o sistema invoca o método onRequestPermissionsResult() do app, passando a ele a resposta do usuário. Seu app precisa substituir esse método para descobrir se a permissão foi concedida. O callback recebe o mesmo código de solicitação passado para requestPermissions(). Por exemplo, se um app solicita o acesso READ_CONTACTS, ele pode ter o seguinte método de callback:

Kotlin

    override fun onRequestPermissionsResult(requestCode: Int,
            permissions: Array<String>, grantResults: IntArray) {
        when (requestCode) {
            MY_PERMISSIONS_REQUEST_READ_CONTACTS -> {
                // If request is cancelled, the result arrays are empty.
                if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
                } else {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                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 MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
                } else {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request.
        }
    }
    

A caixa de diálogo mostrada pelo sistema descreve o grupo de permissões que seu app precisa acessar. Ela não lista a permissão específica. Por exemplo, se você solicitar a permissão READ_CONTACTS, a caixa de diálogo do sistema simplesmente dirá que seu app precisa acessar os contatos do dispositivo. O usuário só precisa conceder essa permissão uma vez para cada grupo de permissões. Se seu app solicitar qualquer outra permissão do grupo em questão (que esteja listada no manifesto do app), o sistema a concederá automaticamente. Quando você solicita a permissão, o sistema chama seu método de callback onRequestPermissionsResult() e passa PERMISSION_GRANTED, da mesma forma que faria se o usuário tivesse concedido sua solicitação explicitamente pela caixa de diálogo do sistema.

Observação: seu app ainda precisa solicitar explicitamente todas as permissões de que precisa, mesmo que o usuário já tenha concedido outra permissão do mesmo grupo. Além disso, a organização de permissões em grupo poderá mudar em versões futuras do Android. Seu código não pode depender da suposição de que permissões específicas estejam ou não no mesmo grupo.

Por exemplo, suponha que você liste READ_CONTACTS e WRITE_CONTACTS no manifesto do seu app. Se você solicitar READ_CONTACTS e o usuário conceder a permissão e você, depois disso, solicitar WRITE_CONTACTS, o sistema concederá essa permissão imediatamente, sem interagir com o usuário.

Se o usuário negar uma solicitação de permissão, seu app precisará executar a ação apropriada. Por exemplo, ele pode mostrar uma caixa de diálogo explicando por que não conseguiu executar a ação solicitada pelo usuário que precisa da permissão em questão.

Quando o sistema pede para que o usuário conceda uma permissão, o usuário tem a opção de dizer ao sistema para que não peça essa permissão novamente. Nesse caso, sempre que um app usar requestPermissions() para solicitar essa permissão, o sistema negará imediatamente. O sistema chamará seu método de callback onRequestPermissionsResult() e passará PERMISSION_DENIED, da mesma forma que faria se o usuário tivesse rejeitado explicitamente a solicitação novamente. O método também retornará false se as políticas do dispositivo proibirem o app de ter a permissão. Isso significa que, ao chamar requestPermissions(), você não pode presumir que tenha ocorrido qualquer interação direta com o usuário.

Para oferecer a melhor experiência do usuário ao solicitar permissões do app, consulte também as Práticas recomendadas de permissões do app.

Declarar permissões por nível de API

Para declarar uma permissão apenas em dispositivos compatíveis com permissões no tempo de execução, ou seja, dispositivos com Android 6.0 (API de nível 23) ou versões posteriores, inclua a tag uses- permission-sdk-23, em vez de uses-permission.

Ao usar uma dessas tags, você poderá definir o atributo maxSdkVersion para especificar que, em dispositivos com uma versão mais nova, uma permissão específica não será necessária.

Outros recursos

Para mais informações sobre permissões, leia estes artigos:

Para saber mais sobre solicitação de permissões, faça o download destes apps de exemplo: