Содержание
Получение разрешений приложениями в 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.

