Permissões

Browse sample. Navegue pelo exemplo

Este artigo descreve como você pode usar a classe .NET Multi-platform App UI (.NET MAUI). Permissions Essa classe permite que você verifique e solicite permissões em tempo de execução. O Permissions tipo está disponível no Microsoft.Maui.ApplicationModel namespace.

Permissões disponíveis

O .NET MAUI tenta abstrair o maior número possível de permissões. No entanto, cada sistema operacional tem um conjunto diferente de permissões. Embora a API permita acesso a uma permissão comum, pode haver diferenças entre os sistemas operacionais relacionados a essa permissão. A tabela a seguir descreve as permissões disponíveis:

A tabela a seguir usa ✔️ para indicar que a permissão é suportada e ❌ para indicar que a permissão não é suportada ou não é necessária:

Permissão Android iOS Windows tvOS
Bateria ✔️
CalendárioLeia ✔️ ✔️
CalendarWrite ✔️ ✔️
Câmera ✔️ ✔️
ContatosLeia ✔️ ✔️
ContatosEscrever ✔️ ✔️
Lanterna ✔️
LocationWhenInUse ✔️ ✔️ ✔️
LocalizaçãoSempre ✔️ ✔️
Media ✔️
Microfone ✔️ ✔️
Estado da Rede ✔️
Telefone ✔️ ✔️
Fotos ✔️ ✔️
PhotosAddOnly ✔️ ✔️
Lembretes ✔️
Sensores ✔️ ✔️
SMS ✔️ ✔️
Fala ✔️ ✔️
StorageRead ✔️
StorageWrite ✔️
Vibrar ✔️
Permissão Android iOS Windows tvOS
Bateria ✔️
Bluetooth ✔️
CalendárioLeia ✔️ ✔️
CalendarWrite ✔️ ✔️
Câmera ✔️ ✔️
ContatosLeia ✔️ ✔️
ContatosEscrever ✔️ ✔️
Lanterna ✔️
LocationWhenInUse ✔️ ✔️ ✔️
LocalizaçãoSempre ✔️ ✔️
Media ✔️
Microfone ✔️ ✔️
ProximidadesDispositivos Wi-Fi ✔️
Estado da Rede ✔️
Telefone ✔️ ✔️
Fotos ✔️ ✔️
PhotosAddOnly ✔️ ✔️
Lembretes ✔️
Sensores ✔️ ✔️
SMS ✔️ ✔️
Fala ✔️ ✔️
StorageRead ✔️
StorageWrite ✔️
Vibrar ✔️

Se uma permissão estiver marcada como ❌, ela sempre retornará Granted quando marcada ou solicitada.

Verificando permissões

Para verificar o status atual de uma permissão, use o método Permissions.CheckStatusAsync com a permissão específica para obter o status. O exemplo a seguir verifica o LocationWhenInUse status da permissão:

PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();

A PermissionException será lançado se a permissão necessária não for declarada.

É melhor verificar o status da permissão antes de solicitá-la. Cada sistema operacional retorna um estado padrão diferente, se o usuário nunca tiver sido solicitado. O iOS retorna, enquanto outros retornamUnknownDenied. Se o status for Granted , não há necessidade de fazer outras chamadas. No iOS, se o status for Denied , você deve solicitar que o usuário altere a permissão nas configurações. No Android, você pode ligar ShouldShowRationale para detectar se o usuário já negou a permissão no passado.

Status da permissão

Ao usar CheckStatusAsync ou RequestAsync, um PermissionStatus é retornado que pode ser usado para determinar as próximas etapas:

  • Unknown
    A permissão está em um estado desconhecido, ou no iOS, o usuário nunca foi solicitado.

  • Denied
    O usuário negou a solicitação de permissão.

  • Disabled
    O recurso está desativado no dispositivo.

  • Granted
    O usuário concedeu permissão ou é concedida automaticamente.

  • Restricted
    Em estado restrito.

  • Limited
    Em um estado limitado. Somente o iOS retorna esse status.

Solicitando permissões

Para solicitar uma permissão dos usuários, use o método RequestAsync com a permissão específica. Se o usuário concedeu permissão anteriormente e não a revogou, esse método retornará Granted sem mostrar uma caixa de diálogo para o usuário. As permissões não devem ser solicitadas à sua MauiProgram classe App e só devem ser solicitadas quando a primeira página do aplicativo for exibida.

O exemplo a seguir solicita a LocationWhenInUse permissão:

PermissionStatus status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();

A PermissionException será lançado se a permissão necessária não for declarada.

Importante

Em algumas plataformas, uma solicitação de permissão só pode ser ativada uma única vez. Outros prompts devem ser manipulados pelo desenvolvedor para verificar se uma permissão está no estado e, em Denied seguida, pedir ao usuário para ativá-la manualmente.

Explicar por que a permissão é necessária

É uma prática recomendada explicar ao usuário por que seu aplicativo precisa de uma permissão específica. No iOS, você deve especificar uma cadeia de caracteres que é exibida para o usuário. O Android não tem essa capacidade e também padroniza o status de permissão para Disabled. Isso limita a capacidade de saber se o usuário negou a permissão ou se é a primeira vez que a permissão está sendo solicitada. O ShouldShowRationale método pode ser usado para determinar se uma interface do usuário informativa deve ser exibida. Se o método retornar true, isso ocorre porque o usuário negou ou desabilitou a permissão no passado. Outras plataformas sempre retornam false ao chamar esse método.

Exemplo

O código a seguir apresenta o padrão de uso geral para determinar se uma permissão foi concedida e, em seguida, solicitá-la, se não foi.

public async Task<PermissionStatus> CheckAndRequestLocationPermission()
{
    PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();

    if (status == PermissionStatus.Granted)
        return status;

    if (status == PermissionStatus.Denied && DeviceInfo.Platform == DevicePlatform.iOS)
    {
        // Prompt the user to turn on in settings
        // On iOS once a permission has been denied it may not be requested again from the application
        return status;
    }

    if (Permissions.ShouldShowRationale<Permissions.LocationWhenInUse>())
    {
        // Prompt the user with additional information as to why the permission is needed
    }

    status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();

    return status;
}

Estendendo permissões

A API de permissões foi criada para ser flexível e extensível para aplicativos que exigem mais validação ou permissões que não estão incluídas no .NET MAUI. Crie uma classe que herda de Permissions.BasePermissione implemente os métodos abstratos necessários. O código de exemplo a seguir demonstra os membros abstratos básicos, mas sem implementação:

public class MyPermission : Permissions.BasePermission
{
    // This method checks if current status of the permission.
    public override Task<PermissionStatus> CheckStatusAsync()
    {
        throw new System.NotImplementedException();
    }

    // This method is optional and a PermissionException is often thrown if a permission is not declared.
    public override void EnsureDeclared()
    {
        throw new System.NotImplementedException();
    }

    // Requests the user to accept or deny a permission.
    public override Task<PermissionStatus> RequestAsync()
    {
        throw new System.NotImplementedException();
    }

    // Indicates that the requestor should prompt the user as to why the app requires the permission, because the
    // user has previously denied this permission.
    public override bool ShouldShowRationale()
    {
        throw new NotImplementedException();
    }
}

Ao implementar uma permissão de uma plataforma específica, a classe Permissions.BasePlatformPermission pode ser herdada. Essa classe fornece métodos auxiliares de plataforma extra para verificar automaticamente as declarações de permissão. Isso ajuda ao criar permissões personalizadas que fazem agrupamentos, por exemplo, solicitando acesso de leitura e gravação ao armazenamento no Android. O exemplo de código a seguir demonstra a solicitação de acesso de armazenamento de leitura e gravação :

public class ReadWriteStoragePerms : Permissions.BasePlatformPermission
{
    public override (string androidPermission, bool isRuntime)[] RequiredPermissions =>
        new List<(string androidPermission, bool isRuntime)>
        {
        (global::Android.Manifest.Permission.ReadExternalStorage, true),
        (global::Android.Manifest.Permission.WriteExternalStorage, true)
        }.ToArray();
}

Em seguida, verifique a permissão da mesma forma que qualquer outro tipo de permissão fornecido pelo .NET MAUI:

PermissionStatus status = await Permissions.RequestAsync<ReadWriteStoragePerms>();

Se você quisesse chamar essa API a partir de seu código de plataforma cruzada, poderia criar uma interface e registrar a permissão personalizada como uma dependência no contêiner de serviço do aplicativo. O exemplo a seguir mostra a IReadWritePermission interface:

public interface IReadWritePermission
{        
    Task<PermissionStatus> CheckStatusAsync();
    Task<PermissionStatus> RequestAsync();
}

Em seguida, implemente a interface em sua permissão personalizada:

public class ReadWriteStoragePermission : Permissions.BasePlatformPermission, IReadWritePermission
{
    public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string androidPermission, bool isRuntime)>
    {
        (Android.Manifest.Permission.ReadExternalStorage, true),
        (Android.Manifest.Permission.WriteExternalStorage, true)
    }.ToArray();
}

MauiProgram Na classe, você deve registrar a interface e seu tipo concreto, e o tipo que consumirá a permissão personalizada, no contêiner de serviço do aplicativo:

builder.Services.AddTransient<MyViewModel>();
builder.Services.AddSingleton<IReadWritePermission, ReadWriteStoragePermission>();

A implementação de permissão personalizada pode ser resolvida e invocada de um de seus tipos, como um viewmodel:

public class MyViewModel
{
    IReadWritePermission _readWritePermission;

    public MyViewModel(IReadWritePermission readWritePermission)
    {
        _readWritePermission = readWritePermission;
    }

    public async Task CheckPermissionAsync()
    {
        var status = await _readWritePermission.CheckStatusAsync();
        if (status != PermissionStatus.Granted)
        {
            status = await _readWritePermission.RequestAsync();
        }
    }
}

Diferenças de plataforma

Esta seção descreve as diferenças específicas da plataforma com a API de permissões.

As permissões devem ter os atributos correspondentes definidos no arquivo de Manifesto do Android. O status de permissão tem como Deniedpadrão .