IContacts — работа с контактами в Android

При разработке приложения Blazor Hybrid, для работы с контактами в Android предназначен интерфейс IContacts, содержащийся в пространстве имен Microsoft.Maui.ApplicationModel.Communication.

Определение необходимых разрешений

Для работы с контактами в Android приложение должно иметь разрешение

android.permission.READ_CONTACTS

Создадим новое приложение Blazor Hybrid и добавим новое разрешение в файл Platform/Android/MainApplication.cs, используя атрибут сборки

using Android.App;
using Android.Runtime;

[assembly: UsesPermission(Android.Manifest.Permission.ReadContacts)] //добавляем необходимое разрешение

namespace BlazorContacts
{
    [Application]
    public class MainApplication : MauiApplication
    {
        public MainApplication(IntPtr handle, JniHandleOwnership ownership)
            : base(handle, ownership)
        {
        }

        protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
    }
}

Теперь мы можем воспользоваться функцией чтения контактов на устройстве Android.

Интерфейс IContacts и класс Contact

Интерфейс IContacts достаточно простой и предоставляет нам всего два метода:

Метод Описание
GetAllAsync(CancellationToken) Возвращает коллекцию всех контактов на устройстве.
PickContactAsync() Открывает пользовательский интерфейс операционной системы по умолчанию для выбора контакта с устройства.

Реализация этого интерфейса доступна нам с использованием свойства Default статического класса Contacts. Когда мы запрашиваем отдельный контакт или весь список контактов с устройства, то мы получаем один или несколько объектов Contact, у которого определены следующие свойства:

Свойство Описание
DisplayName Отображаемое имя контакта.
Emails Коллекция адресов электронной почты контакта.
FamilyName Фамилия контакта.
GivenName Имя контакта.
Id Идентификатор контакта.
MiddleName Отчество контакта.
NamePrefix Префикс имени контакта.
NameSuffix Суффикс имени контакта.
Phones Коллекция номеров телефонов контакта.

Вернемся к нашему приложению и посмотрим на работу с контактами в Android.

Получение всего списка контактов

Перепишем код компонента Home следующим образом:

@page "/"

@using Microsoft.Maui.ApplicationModel.Communication


<h1>Список контактов</h1>

@if (list == null)
{
    <p><em>Загружаем...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>DisplayName</th>
                <th>GivenName</th>
                <th>MiddleName</th>
                <th>FamilyName</th>
                <th>Email</th>
                <th>Phone</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var contact in list)
            {
                <tr>
                    <td>@contact.DisplayName</td>
                    <td>@contact.GivenName</td>
                    <td>@contact.MiddleName</td>
                    <td>@contact.FamilyName</td>
                    <td>
                        @if (contact.Emails.Count > 1)
                        {
                            <text>@contact.Emails[0] и ещё @contact.Emails.Count-1 </text>
                        }
                        else
                        {
                            if (contact.Emails.Count == 1)
                            {
                                <text>@contact.Emails[0]</text>
                            }
                        }
                    </td>
                    <td>
                        @if (contact.Phones.Count > 1)
                        {
                            <text>@contact.Phones[0] и ещё @contact.Phones.Count-1 </text>
                        }
                        else
                        {
                            if (contact.Phones.Count == 1)
                            {
                                <text>@contact.Phones[0]</text>
                            }
                        }
                    </td>
                </tr>
            }
        </tbody>
    </table>
}
<button @onclick="LoadAll">Получить список контактов</button>

@code{
    IContacts MyContacts = Contacts.Default;
    IEnumerable<Contact> list;

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

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

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

        return status;
    }


    public async Task LoadAll()
    {
        if (await CheckAndRequestContactsPermission() == PermissionStatus.Granted)
           list = await MyContacts.GetAllAsync();
    }
}

Рассмотрим этот код более подробно. Первое, что мы сделали — это подключили необходимое нам пространство имен:

@using Microsoft.Maui.ApplicationModel.Communication

Далее, в коде C# компонента мы объявили два поля

IContacts MyContacts = Contacts.Default; 
IEnumerable<Contact> list;

здесь MyContacts предоставляет нам реализацию интерфейса IContacts по умолчанию, а list служит для хранения списка контактов. Сам список контактов загружается в методе LoadAll():

public async Task LoadAll()
{
    if (await CheckAndRequestContactsPermission() == PermissionStatus.Granted)
       list = await MyContacts.GetAllAsync();
}

и здесь мы сталкиваемся с вызовом еще одного метода CheckAndRequestContactsPermission() в котором используется класс Permissions:

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

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

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

    return status;
}

Класс Permissions используется для проверки и, при необходимости, запроса разрешений у пользователя на выполнение каких-либо операций. Дело в том, что в Android все разрешения делятся на обычные и опасные (dangerous ). Обычные разрешения, например, для доступа к заряду батареи, получаются непосредственно при установке приложения. Что касается опасных разрешений, то такие разрешения получаются при доступе к конфиденциальной информации и к информации, использование которой может повлиять на безопасность устройства. Опасные разрешения необходимо запрашивать у пользователя непосредственно при работе приложения. Это помогает снизить риск утечки конфиденциальной информации или взлома устройства. Согласитесь, что если условное приложение «Фонарик» запросит у вас доступ к чтению контактов или SMS, то такое поведение приложение вас насторожит?

Чтобы узнать к какой группе разрешение относится разрешение, необходимое вашему приложению, можно обратиться к документации по API Android и посмотреть на Protection level конкретного разрешения.

Так вот в методе CheckAndRequestContactsPermission() мы и производим ровно две операции:

1. Проверяем получено ли у пользователя разрешение. Для этого мы выполняем метод

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

PermissionStatus — это перечисление, в котором определены следующие значения, которые мы можем использовать в Android:

  • Unknown — разрешение находится в неизвестном состоянии.
  • Denied — пользователь отказался от запроса на разрешение.
  • Disabled — эта функция отключена на устройстве.
  • Granted — пользователь предоставил разрешение или автоматически предоставляется.
  • Restricted — в ограниченном состоянии.

В нашем случае, мы проверяем значение Granted. Если разрешение получено, то мы возвращаем статус, иначе — пытаемся запросить разрешение у пользователя:

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

и вне зависимости от результата возвращаем полученное значение. В методе LoadAll() проверяется статус разрешения и загружается список контактов, если разрешение получено:

if (await CheckAndRequestContactsPermission() == PermissionStatus.Granted)
   list = await MyContacts.GetAllAsync();

И, наконец, в разметке компонента мы выводим обычную таблицу с контактами. В запущенном приложении это будет выглядеть следующим образом:

сразу после запуска приложения:

Запрос на разрешение после нажатия кнопки «Получить список контактов»

После успешного получения разрешения вы увидите через некоторое время список всех контактов с устройства:

Выбор контакта из адресной книги

Метод интерфейса IContacts PickContactAsync() позволяет выбрать для просмотра контакт из адресной книги. Чтобы продемонстрировать его работу, перепишем компонент Home следующим образом:

@page "/"

@using Microsoft.Maui.ApplicationModel.Communication


<h1>Список контактов</h1>

@if (Contact == null)
{
    <p><em>Загружаем...</em></p>
}
else
{
    <p>@Contact.DisplayName</p>
    <p>@Contact.GivenName</p>
    <p>@Contact.MiddleName</p>
    <p>@Contact.FamilyName</p>
    <p>Адреса электронной почты</p>
    <li>
        @foreach (var email in Contact.Emails)
        {
            <ul>@email</ul>
        }
    </li>

    <p>Телефоны</p>
    <li>
        @foreach (var phone in Contact.Phones)
        {
            <ul>@phone</ul>
        }
    </li>
}
<button @onclick="LoadAll">Получить контакт</button>

@code{
    IContacts MyContacts = Contacts.Default;

    Contact? Contact;

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

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

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

        return status;
    }


    public async Task LoadAll()
    {
        if (await CheckAndRequestContactsPermission() == PermissionStatus.Granted)
            Contact = await MyContacts.PickContactAsync();
    }
}

Принципиально, этот код не сильно отличается от предыдущего — мы изменили разметку компонента, чтобы вывести информацию по конкретному контакту, а также немного изменили код компонента — завели новое поле для контакта:

Contact? Contact;

И заменили вызов метода IContacts:

if (await CheckAndRequestContactsPermission() == PermissionStatus.Granted) 
   Contact = await MyContacts.PickContactAsync();

Отличие заключается в работе приложения — после того как разрешение на просмотр контактов будет получена откроется или сразу приложение «Контакты» на устройстве Android или операционная система предложит выбрать одно из приложений для просмотра контактов (если у вас их установлено несколько). После выбора контакта информация о нем будет показана на экране:

Итого

Для чтения контактов в Android используется интерфейс IContacts у которого определено два метода — для чтения всего списка контактов и выбора контакта из адресной книги. Запись контактов на момент написания этой статьи не поддерживалась. Перед получением доступа к контактам на устройстве Android необходимо явно получить разрешение на такое действие.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии