Содержание
Получение разрешений приложениями в Android — это одна из необходимых процедур, призванная информировать пользователя о том, какие операции планирует выполнять приложение с данными устройства, в том числе и с конфиденциальными. Например, если ваше приложение должно работать с камерой устройства, то вы должны запросить необходимое разрешение у пользователя. Для разных типов операций требуется получение различных разрешений.
Получение разрешений приложения Android в .NET MAUI
Доступ к некоторым возможностям Android может быть получен только после того как приложение запросит и получит необходимые разрешения. Например, мы не сможем воспользоваться геолокацией или фонариком на устройстве пока не получим необходимые разрешения. При этом, не стоит увлекаться и запрашивать сразу все возможные разрешения для вашего приложения. Будет очень странно выглядеть, если приложение-фонарик при запуске запросит у пользователя разрешение на просмотр контактов.
В .NET MAUI константы различных разрешений Android расположены в классе Android.Manifest.Permission
. Приложения .NET MAUI может получать разрешения различными способами:
- Используя атрибуты сборки
- Используя манифест приложения
- Используя явный запрос разрешения при выполнении приложения.
Рассмотрим процесс получения разрешений на примере приложения, которое выводит информацию о заряде батареи устройства.
Пример приложения
Создадим новое приложение .NET MAUI и изменим класс MainPage
следующим образом:
public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); } private void Button_Clicked(object sender, EventArgs e) { ChargeLevelLabel.Text = $"Заряд батареи {Battery.Default.ChargeLevel * 100}%"; var accState = Battery.Default.State switch { BatteryState.Unknown => "Unknown", BatteryState.Charging => "Заряжается", BatteryState.Discharging => "Разряжается", BatteryState.Full => "Полный заряд", BatteryState.NotCharging => "Не заряжается", BatteryState.NotPresent => "Аккумулятор отсутствует" }; AccumulatorStateLabel.Text = $"Состояние аккумулятора {accState}"; var accSource = Battery.Default.PowerSource switch { BatteryPowerSource.Unknown => "Unknown", BatteryPowerSource.Battery => "Аккумулятор", BatteryPowerSource.AC => "Зарядное устройство", BatteryPowerSource.Usb => "USB-порт", BatteryPowerSource.Wireless => "Беспроводная зарядка" }; AccumulatorSourceLabel.Text = $"Источник питания {accSource}"; var energySaver = Battery.Default.EnergySaverStatus switch { EnergySaverStatus.Unknown => "Unknown", EnergySaverStatus.On => "Включено", EnergySaverStatus.Off => "Выключено" }; EnergySaverLabel.Text = $"Экономия заряда: {energySaver}"; } }
XAML-код страницы MainPage изменим так:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MauiAndroidPermissions.MainPage"> <ScrollView> <VerticalStackLayout Padding="30,0" Spacing="25"> <Button Text="Проверить" Clicked="Button_Clicked"/> <Label x:Name="ChargeLevelLabel"/> <Label x:Name="AccumulatorStateLabel"/> <Label x:Name="AccumulatorSourceLabel"/> <Label x:Name ="EnergySaverLabel"/> </VerticalStackLayout> </ScrollView> </ContentPage>
В нашем приложении клик по кнопке приводит к выполнению обработчика Button_Clicked()
в котором мы получаем доступ к реализации по умолчанию интерфейса IBattery
. Интерфейс IBattery
предоставляет нам свойства для отслеживания состояния аккумулятора устройства:
Свойство | Тип | Описание |
ChargeLevel |
double |
Возвращает текущий уровень заряда устройства от 0,0 до 1,0 . |
EnergySaverStatus |
EnergySaverStatus |
Возвращает текущее состояние экономии энергии устройства. Может принимать следующие значения:
|
PowerSource |
BatteryPowerSource |
Возвращает текущий источник питания для устройства. Может принимать следующие значение:
|
State |
BatteryState |
Возвращает состояние зарядки устройства. Может принимать следующие значения:
|
Также нам доступны для события:
Событие | Описание |
event EventHandler<BatteryInfoChangedEventArgs> BatteryInfoChanged; |
Событие, которое генерируется каждый раз, когда изменяются свойства ChargeLevel , PowerSource или State |
event EventHandler<EnergySaverStatusChangedEventArgs> EnergySaverStatusChanged; |
Событие, которое генерируется при изменении свойства EnergySaverStatus |
Получив необходимые сведения о состоянии аккумулятора мы выводим их в метки Label
. Теперь, если запустить приложение и попытаться нажать на кнопку, то мы гарантированно получим ошибку следующего создержания:
Так как для доступа к состоянию батареи требуется получить разрешение, то попытка получения такого доступа без предварительной настройки манифеста приложения приводит к ошибке. На примере этого приложения мы и рассмотрим различные варианты получения разрешений Android.
Получение разрешений с использованием манифеста
Самый простой вариант определить разрешения для своего приложения — это добавить их в манифест приложения. Кликните дважды по файлу Platforms/Android/AndroidMainfest.xml. По умолчанию в Visual Studio откроется редактор манифеста:
В списке «Required permissions» перечислены все доступные разрешения, которые мы можем декларировать для нашего приложения. Здесь нам необходимо выбрать разрешение
BATTERY_STATS
:
Сохраним файл и снова запустим приложение. Теперь клик по кнопке не приведет к появлению ошибки:
Получение разрешений с использованием атрибутов сборки
Второй вариант объявления необходимых для приложения Android разрешений в .NET MAUI — это использование атрибутов сборки. Атрибуты UsesPermission
объявляются только в файле Platform/Android/MainApplication.cs. Применительно к нашему приложению, файл MainApplication.cs должен выглядеть следующим образом:
using Android.App; using Android.Runtime; [assembly: UsesPermission(Android.Manifest.Permission.BatteryStats)] namespace MauiAndroidPermissions; [Application] public class MainApplication : MauiApplication { public MainApplication(IntPtr handle, JniHandleOwnership ownership) : base(handle, ownership) { } protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
Как можно видеть по представленному выше коду, атрибут сборки объявляется перед сразу после using
и перед всеми остальными частями файла. При сборке приложения .NET MAUI проанализирует все атрибуты сборки и внесет информацию о разрешениях в манифест приложения.
Использование класса Permissions
В Android все разрешения делятся на обычные и опасные (dangerous
). Обычные разрешения, например, для доступа к заряду батареи, получаются непосредственно при установке приложения.
Опасные разрешения Android — это такие разрешения, благодаря получению которых, приложение получает доступ к конфиденциальной информации и к информации, использование которой может повлиять на безопасность устройства. Опасные разрешения необходимо запрашивать у пользователя непосредственно при работе приложения. Это помогает снизить риск утечки конфиденциальной информации или взлома устройства. Например, разрешение на использование геолокации относится к опасным.
Вы также можете указать опасные разрешения в манифесте приложения или в атрибутах сборки, однако, при попытке выполнить операцию с конфиденциальными данными приложение явно запросит разрешение. Например, вот так будет выглядеть окно приложения при первой попытке поучить координаты местоположения:
Пользователь может запретить использовать данные о своем местоположении, поэтому при следующей попытке получить доступ к конфиденциальным данным нам необходимо проверить наличие необходимых разрешений.
Класс Permissions
используется для проверки и, при необходимости, запроса разрешений у пользователя на выполнение каких-либо операций. Например, если нам необходимо проверить и запросить разрешение на получение доступа к местоположению устройства, то можно написать вот такой метод проверки необходимого разрешения:
public async Task<PermissionStatus> CheckPermissionStatus() { var currentStatus = await Permissions.CheckStatusAsync<Permissions.LocationAlways>(); if (currentStatus != PermissionStatus.Granted) { currentStatus = await Permissions.RequestAsync<Permissions.LocationAlways>(); } return currentStatus; }
Метод CheckPermissionStatus()
возвращает один из следующих статусов разрешения:
Unknown
— разрешение находится в неизвестном состоянии.Denied
— пользователь отказался от запроса на разрешение.Disabled
— эта функция отключена на устройстве.Granted
— пользователь предоставил разрешение или автоматически предоставляется.Restricted
— разрешено в ограниченном состоянии.
Вначале мы проверяем текущий статус разрешения:
var currentStatus = await Permissions.CheckStatusAsync<Permissions.LocationAlways>();
если разрешение ещё не получено от пользователя, то мы запрашиваем необходимое разрешение:
currentStatus = await Permissions.RequestAsync<Permissions.LocationAlways>();
и возвращаем результат. Воспользоваться этим методом можно, например, так:
private async void Button_Clicked(object sender, EventArgs e) { PermissionStatus status = await CheckPermissionStatus(); if (status != PermissionStatus.Granted) { await DisplayAlert("Разрешение не получено", "Доступ к информации о местоположении запрещен", "Понятно"); } else { //выполняем операции, связанные с местоположением устройства } }
Если пользователь отклонит разрешение, то увидит на экране сообщение о том, что доступ к местоположению был запрещен.
Итого
Для получения разрешений приложения Android в .NET MAUI мы можем воспользоваться атрибутами сборки, или объявить необходимые разрешения в манифесте приложения. При этом, для опасных разрешений необходимо явное разрешение пользователя на выполнение необходимых операций. Чтобы проверить статус того или иного разрешения, необходимо воспользоваться методами класса Permissions
.