Xamarin.Essentials:Permissões

A classe Permissions fornece a capacidade de verificar e solicitar permissões de tempo de execução.

Introdução

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

Essa API usa permissões de tempo de execução no Android. Certifique-se de que Xamarin.Essentials esteja totalmente inicializado e que o tratamento de permissões esteja configurado em seu aplicativo.

No projeto MainLauncher Android ou em qualquer Activity um 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 tempo de execução no Android, Xamarin.Essentials o deve receber qualquer OnRequestPermissionsResultarquivo . 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);
}

Usar permissões

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

using Xamarin.Essentials;

Verificar permissões

Para verificar o status atual de uma permissão, use o método CheckStatusAsync 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 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 Unknown, enquanto outros retornam Denied. 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 e, no Android, você pode ligar 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 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 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, a solicitação de permissão só pode ser ativada uma única vez. Outros prompts devem ser tratados pelo desenvolvedor para verificar se uma permissão está no Denied estado e solicitar que o usuário a ative 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
  • Desativado – O recurso está desabilitado no dispositivo
  • Concedido – O usuário concedeu permissão ou ela foi concedida automaticamente
  • Restrito – Em um estado restrito

Explique 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 padroniza o status de permissão para Desativado. Isso limita a capacidade de saber se o usuário negou a permissão ou se é a primeira vez que solicita ao usuário. 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 maior número possível de permissões. No entanto, cada sistema operacional tem um conjunto diferente de permissões de tempo de execução. Além disso, há diferenças ao fornecer uma única API para algumas permissões. Aqui está um guia para as permissões atualmente disponíveis:

Guia de ícones:

  • suporte completo -Suportado
  • Sem suporte - Não suportado/necessário
Permissão Android iOS UWP watchOS tvOS Tizen
CalendarRead Compatível com Android Compatível com iOS Incompatível com UWP Compatível com watchOS Incompatível com tvOS Incompatível com Tizen
CalendarWrite Compatível com Android Compatível com iOS Incompatível com UWP Compatível com watchOS Incompatível com tvOS Incompatível com Tizen
Câmera Compatível com Android Compatível com iOS Incompatível com UWP Incompatível com watchOS Incompatível com tvOS Compatível com Tizen
ContactsRead Compatível com Android Compatível com iOS Compatível com UWP Incompatível com watchOS Incompatível com tvOS Incompatível com Tizen
ContactsWrite Compatível com Android Compatível com iOS Compatível com UWP Incompatível com watchOS Incompatível com tvOS Incompatível com Tizen
Lanterna Compatível com Android Incompatível com iOS Incompatível com UWP Incompatível com watchOS Incompatível com tvOS Compatível com Tizen
LocationWhenInUse Compatível com Android Compatível com iOS Compatível com UWP Compatível com watchOS Compatível com tvOS Compatível com Tizen
LocationAlways Compatível com Android Compatível com iOS Compatível com UWP Compatível com watchOS Incompatível com tvOS Compatível com Tizen
Mídia Incompatível com Android Compatível com iOS Incompatível com UWP Incompatível com watchOS Incompatível com tvOS Incompatível com Tizen
Microfone Compatível com Android Compatível com iOS Compatível com UWP Incompatível com watchOS Incompatível com tvOS Compatível com Tizen
Telefone Compatível com Android Compatível com iOS Incompatível com UWP Incompatível com watchOS Incompatível com tvOS Incompatível com Tizen
Photos Incompatível com Android Compatível com iOS Incompatível com UWP Incompatível com watchOS Compatível com tvOS Incompatível com Tizen
Lembretes Incompatível com Android Compatível com iOS Incompatível com UWP Compatível com watchOS Incompatível com tvOS Incompatível com Tizen
Sensores Compatível com Android Compatível com iOS Compatível com UWP Compatível com watchOS Incompatível com tvOS Incompatível com Tizen
Sms Compatível com Android Compatível com iOS Incompatível com UWP Incompatível com watchOS Incompatível com tvOS Incompatível com Tizen
Fala Compatível com Android Compatível com iOS Incompatível com UWP Incompatível com watchOS Incompatível com tvOS Incompatível com Tizen
StorageRead Compatível com Android Incompatível com iOS Incompatível com UWP Incompatível com watchOS Incompatível com tvOS Incompatível com Tizen
StorageWrite Compatível com Android Incompatível com iOS Incompatível com UWP Incompatível com watchOS Incompatível com tvOS Incompatível com Tizen

Se uma permissão estiver marcada como sem suporte ela sempre retornará Granted quando 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 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;
}

Estender Permissões

A API de permissões foi criada para ser flexível e extensível para aplicativos que exigem validação adicional ou permissões que não estão incluídas no Xamarin.Essentials. Crie uma nova classe que herda de BasePermission e implemente os métodos de abstração 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 de uma plataforma específica, a classe BasePlatformPermission pode ser herdada. Isso fornece métodos auxiliares de plataforma adicionais para verificar 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 seu 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, a partir do seu projeto compartilhado, você pode resolvê-lo 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 status padrão da permissão é Negado.

Leia mais na documentação de Permissões no Xamarin.Android.

API

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