Xamarin.Essentials:Permissões

A classe Permissions fornece a capacidade de marcar e solicitar permissões de runtime.

Introdução

Para começar a usar essa API, leia o guia de introdução para Xamarin.Essentials para garantir que a biblioteca esteja instalada e configurada corretamente em seus projetos.

Essa API usa permissões de runtime no Android. Verifique se Xamarin.Essentials está totalmente inicializado e se o tratamento de permissões está configurado em seu aplicativo.

No projeto do MainLauncher Android ou em qualquer Activity que seja iniciado Xamarin.Essentials , deve ser inicializado no OnCreate método :

protected override void OnCreate(Bundle savedInstanceState) 
{
    //...
    base.OnCreate(savedInstanceState);
    Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
    //...
}    

Para lidar com permissões de runtime no Android, Xamarin.Essentials deve receber qualquer OnRequestPermissionsResult. Adicione o seguinte código a todas as classes Activity:

public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
    Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

    base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}

Usando permissões

Adicione uma referência a Xamarin.Essentials em sua classe:

using Xamarin.Essentials;

Verificando permissões

Para marcar o status atual de uma permissão, use o CheckStatusAsync método juntamente com a permissão específica para obter o status.

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

Um PermissionException será gerado se a permissão necessária não for declarada.

É melhor marcar o status da permissão antes de solicitá-la. Cada sistema operacional retornará um estado padrão diferente se o usuário nunca tiver sido solicitado. O iOS retorna Unknown, enquanto outros retornam Denied. Se o status forGranted, não será necessário fazer outras chamadas. No iOS, se o status forDenied, você deverá solicitar que o usuário altere a permissão nas configurações e, no Android, poderá chamar ShouldShowRationale para detectar se o usuário já negou a permissão no passado.

Solicitando permissões

Para solicitar uma permissão dos usuários, use o RequestAsync método junto com a permissão específica para solicitar. Se o usuário concedeu permissão anteriormente e não a revogou, esse método retornará Granted imediatamente e não exibirá uma caixa de diálogo.

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

Um PermissionException será gerado se a permissão necessária não for declarada.

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

Status da permissão

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

  • Desconhecido – a permissão está em um estado desconhecido
  • Negado - O usuário negou a solicitação de permissão
  • Desabilitado – o recurso está desabilitado no dispositivo
  • Concedido - O usuário concedeu permissão ou é concedido automaticamente
  • Restrito – em um estado restrito

Explicar por que a permissão é necessária

É uma prática recomendada explicar 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 usa como padrão a permissão status para Desabilitado. Isso limita a capacidade de saber se o usuário negou a permissão ou se é a primeira vez que o usuário solicita. O ShouldShowRationale método pode ser usado para determinar se uma interface do usuário educacional 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 retornarão false ao chamar esse método.

Permissões disponíveis

Xamarin.Essentials tenta abstrair o máximo possível de permissões. No entanto, cada sistema operacional tem um conjunto diferente de permissões de runtime. Além disso, há diferenças ao fornecer uma única API para algumas permissões. Aqui está um guia para as permissões disponíveis no momento:

Guia de ícones:

  • Suporte completo – com suporte
  • Sem suporte - Sem suporte/obrigatório
Permissão Android iOS UWP watchOS tvOS Tizen
CalendarRead Android compatível com IOS com suporte para iOS UWP sem suporte WatchOS compatível com tvOS sem suporte Tizen sem suporte
CalendarWrite Android compatível com IOS com suporte para iOS UWP sem suporte WatchOS compatível com tvOS sem suporte Tizen sem suporte
Câmera Android compatível com IOS com suporte para iOS UWP sem suporte WatchOS sem suporte tvOS sem suporte Tizen compatível com
ContactsRead Android compatível com IOS com suporte para iOS UWP compatível com WatchOS sem suporte tvOS sem suporte Tizen sem suporte
ContactsWrite Android compatível com IOS com suporte para iOS UWP compatível com WatchOS sem suporte tvOS sem suporte Tizen sem suporte
Flashlight Android compatível com IOS sem suporte UWP sem suporte WatchOS sem suporte tvOS sem suporte Tizen compatível com
LocationWhenInUse Android com suporte Suporte para iOS com suporte para UWP compatível com WatchOS com suporte para watchOS tvOS com suporte para Tizen com suporte do
LocationAlways Android com suporte Suporte para iOS com suporte para UWP compatível com WatchOS com suporte para watchOS tvOS sem suporte Tizen com suporte do
Mídia Android sem suporte Suporte para iOS com suporte para UWP não compatível com WatchOS sem suporte tvOS sem suporte Tizen não tem suporte para
Microfone Android com suporte Suporte para iOS com suporte para UWP compatível com WatchOS sem suporte tvOS sem suporte Tizen com suporte do
Telefone Android com suporte Suporte para iOS com suporte para UWP não compatível com WatchOS sem suporte tvOS sem suporte Tizen não tem suporte para
Fotos Android sem suporte Suporte para iOS com suporte para UWP não compatível com WatchOS sem suporte tvOS com suporte para Tizen não tem suporte para
Lembretes Android sem suporte Suporte para iOS com suporte para UWP não compatível com WatchOS com suporte para watchOS tvOS sem suporte Tizen não tem suporte para
Sensores Android com suporte Suporte para iOS com suporte para UWP compatível com WatchOS com suporte para watchOS tvOS sem suporte Tizen não tem suporte para
Sms Android com suporte Suporte para iOS com suporte para UWP não compatível com WatchOS sem suporte tvOS sem suporte Tizen não tem suporte para
Fala Android com suporte Suporte para iOS com suporte para UWP não compatível com WatchOS sem suporte tvOS sem suporte Tizen não tem suporte para
StorageRead Android com suporte IOS sem suporte UWP não compatível com WatchOS sem suporte tvOS sem suporte Tizen não tem suporte para
StorageWrite Android com suporte IOS sem suporte UWP não compatível com WatchOS sem suporte tvOS sem suporte Tizen não tem suporte para

Se uma permissão for marcada como sem suporte ela sempre retornará Granted quando for verificada ou solicitada.

Uso geral

O código a seguir apresenta o padrão de uso geral para determinar se uma permissão foi concedida e solicitá-la se não tiver sido concedida. Esse código usa recursos que estão disponíveis com Xamarin.Essentials a versão 1.6.0 ou posterior.

public async Task<PermissionStatus> CheckAndRequestLocationPermission()
{
    var 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;
}

Cada tipo de permissão pode ter uma instância dele criada para que os métodos possam ser chamados diretamente.

public async Task GetLocationAsync()
{
    var status = await CheckAndRequestPermissionAsync(new Permissions.LocationWhenInUse());
    if (status != PermissionStatus.Granted)
    {
        // Notify user permission was denied
        return;
    }

    var location = await Geolocation.GetLocationAsync();
}

public async Task<PermissionStatus> CheckAndRequestPermissionAsync<T>(T permission)
            where T : BasePermission
{
    var status = await permission.CheckStatusAsync();
    if (status != PermissionStatus.Granted)
    {
        status = await permission.RequestAsync();
    }

    return status;
}

Estendendo permissões

A API de Permissões foi criada para ser flexível e extensível para aplicativos que exigem validação ou permissões adicionais que não estão incluídas no Xamarin.Essentials. Crie uma nova classe que herda e BasePermission implemente os métodos abstratos necessários.

public class MyPermission : 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();
    }
}

Ao implementar uma permissão em uma plataforma específica, a BasePlatformPermission classe pode ser herdada. Isso fornece métodos auxiliares de plataforma adicionais para marcar automaticamente as declarações. Isso pode ajudar ao criar permissões personalizadas que fazem agrupamentos. Por exemplo, você pode solicitar acesso de Leitura e Gravação ao armazenamento no Android usando a permissão personalizada a seguir.

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

Em seguida, você pode chamar sua nova permissão do projeto android.

await Permissions.RequestAsync<ReadWriteStoragePermission>();

Se você quisesse chamar essa API do código compartilhado, poderia criar uma interface e usar um serviço de dependência para registrar e obter a implementação.

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

Em seguida, implemente a interface em seu projeto de plataforma:

public class ReadWriteStoragePermission : Xamarin.Essentials.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();
}

Em seguida, você pode registrar a implementação específica:

DependencyService.Register<IReadWritePermission, ReadWriteStoragePermission>();

Em seguida, no projeto compartilhado, você pode resolve e usá-lo:

var readWritePermission = DependencyService.Get<IReadWritePermission>();
var status = await readWritePermission.CheckStatusAsync();
if (status != PermissionStatus.Granted)
{
    status = await readWritePermission.RequestAsync();
}

Particularidades de implementação da plataforma

As permissões devem ter os atributos correspondentes definidos no arquivo de manifesto do Android. O padrão de permissão status Negado.

Leia mais sobre a documentação Permissões no Xamarin.Android .

API

Encontre mais vídeos sobre o Xamarin no Channel 9 e no YouTube.