Разработка под Android в .NET MAUI. Набор телефонного номера

Набор телефонного номера на устройстве Android в .NET MAUI тесно связан с работой с контактами, которую мы изучали в предыдущей части. Поэтому логично будет продолжить работу над нашим приложением, тем более, что там мы уже научились выбирать контакт и получать список его телефонных номеров.

Приложение для выбора контакта (из предыдущей части)

Для начала повторим код приложения, которое было разработано в предыдущей части. Структура проекта выглядит следующим образом:

Для получения разрешения на чтение контактов мы добавили атрибут сборки:

[assembly: UsesPermission(Android.Manifest.Permission.ReadContacts)]

Код модели представления ContactsViewModel:

using System.Collections.ObjectModel;
using System.Windows.Input;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace MauiPhone.ViewModels
{
    public class ContactsViewModel: INotifyPropertyChanged
    {
        public ObservableCollection<Contact> ContactList { get; set; } = [];


        private Contact selectedContact;
        public Contact SelectedContact { 
            get => selectedContact; 
            set 
            {
                if (value != selectedContact)
                {
                    selectedContact = value;
                    OnPropertyChanged();
                }
            } 
        }

        private ContactPhone selectedPhone;
        public ContactPhone SelectedPhone { 
            get => selectedPhone;
            set 
            {
                if (value != selectedPhone) 
                {
                    selectedPhone = value;
                    OnPropertyChanged();
                }
            }
        }

        private ContactEmail selectedEmail;
        public ContactEmail SelectedEmail
        {
            get => selectedEmail;
            set
            {
                if (value != selectedEmail)
                {
                    selectedEmail = value;
                    OnPropertyChanged();
                }
            }
        }


        public ICommand ReadContacts {  get; set; }
        public ICommand PickContact { get; set; }       

        public ContactsViewModel() 
        {
            PickContact = new Command(async () => 
            {
                var contact = await Microsoft.Maui.ApplicationModel.Communication.Contacts.Default.PickContactAsync();
                if (contact != null) 
                {
                    SelectedContact = contact;
                }
            });

            ReadContacts = new Command(async () => 
            {

                if (await CheckPermissionStatus() == PermissionStatus.Granted)
                {
                    foreach (var contact in await Microsoft.Maui.ApplicationModel.Communication.Contacts.Default.GetAllAsync())
                    {
                        ContactList.Add(contact);
                    }
                    if (ContactList.Count > 0) 
                    {
                        SelectedContact = ContactList[0];
                        
                        OnPropertyChanged(nameof(SelectedContact));
                    }
                }
            });
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        public void OnPropertyChanged([CallerMemberName] string prop = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
        }


        public async Task<PermissionStatus> CheckPermissionStatus()
        {
            var currentStatus = await Permissions.CheckStatusAsync<Permissions.ContactsRead>();
            if (currentStatus != PermissionStatus.Granted)
            {
                currentStatus = await Permissions.RequestAsync<Permissions.ContactsRead>();
            }
            return currentStatus;
        }
    }
}

Код C# страницы MainPage:

using MauiPhone.ViewModels;
namespace MauiPhone
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            BindingContext = new ContactsViewModel();
            InitializeComponent();
        }
    }
}

И, наконец, код 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"
             xmlns:local="clr-namespace:MauiPhone.ViewModels"
             xmlns:model="clr-namespace:Microsoft.Maui.ApplicationModel.Communication;assembly=Microsoft.Maui.Essentials"
             x:Class="MauiPhone.MainPage"
             x:DataType="local:ContactsViewModel">

    <ScrollView>
        <VerticalStackLayout
            Padding="30,0"
            Spacing="25">

            <Button Text="Посмотреть контакты" Command="{Binding ReadContacts}" />
            <Button Text="Выбрать контакт из адрекной книги" Command="{Binding PickContact}" />

            <Picker ItemsSource="{Binding ContactList, Mode=TwoWay}" 
                    ItemDisplayBinding="{Binding DisplayName}"
                    SelectedItem="{Binding SelectedContact, Mode=TwoWay}"/>

            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition></RowDefinition>
                    <RowDefinition></RowDefinition>
                    <RowDefinition></RowDefinition>
                    <RowDefinition></RowDefinition>
                    <RowDefinition></RowDefinition>
                    <RowDefinition></RowDefinition>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>

                <Label Text="Отображаемое имя" Grid.Row="0" Grid.Column="0"/>
                <Label Text="Имя" Grid.Row="1" Grid.Column="0"/>
                <Label Text="Отчество" Grid.Row="2" Grid.Column="0"/>
                <Label Text="Фамилия" Grid.Row="3" Grid.Column="0"/>
                <Label Text="Список телефонов" Grid.Row="4" Grid.Column="0" VerticalOptions="Center"/>
                <Label Text="Список Email" Grid.Row="5" Grid.Column="0" VerticalOptions="Center"/>
                <Label Text="{Binding SelectedContact.DisplayName, Mode=TwoWay}" Grid.Row="0" Grid.Column="1" />
                <Label Text="{Binding SelectedContact.GivenName, Mode=TwoWay}" Grid.Row="1" Grid.Column="1"/>
                <Label Text="{Binding SelectedContact.MiddleName, Mode=TwoWay}" Grid.Row="2" Grid.Column="1"/>
                <Label Text="{Binding SelectedContact.FamilyName, Mode=TwoWay}" Grid.Row="3" Grid.Column="1"/>
                <Picker ItemsSource="{Binding SelectedContact.Phones, Mode=TwoWay}" SelectedItem="{Binding SelectedPhone}" Grid.Row="4" Grid.Column="1"/>
                <Picker ItemsSource="{Binding SelectedContact.Emails, Mode=TwoWay}" SelectedItem="{Binding SelectedEmail}" Grid.Row="5" Grid.Column="1"/>
            </Grid>

        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

Наше приложение загружает список контактов с устройства Android, а также позволяет выбрать контакт, используя одно из приложений для работы с контактами, установленное на устройстве. Теперь мы доработаем наше приложение таким образом, чтобы мы могли набирать в телефоне выбранный номер контакта.

Интерфейс IPhoneDialer

Для набора телефонного номера в .NET MAUI используется интерфейс IPhoneDialer. Этот интерфейс довольно простой и предоставляет нам всего одно свойство:

public bool IsSupported { get; }

определяющее доступен ли набор номера на устройстве. И один метод:

public void Open(string number);

собственно, и открывающий приложение телефона с набранным номером, который указывается в параметре метода.

Как и в большинстве случаев, реализация по умолчанию этого интерфейса доступна через свойство Default одноименного класса PhoneDialer. Допишем наше приложение, чтобы мы могли набирать телефонный номер для выбранного контакта.

Набор телефонного номера

Изменение манифеста приложения

Для того, чтобы наше приложение могло взаимодействовать с другими приложениями на устройстве, а именно с приложением для совершения телефонных звонков, нам необходимо добавить в манифест приложения требования к видимости пакета. Для этого откройте файл Platforms/Android/AndroidManifest.xml, используя текстовый редактор — кликните правой кнопкой мыши по файлу и выберите в меню пункт «Открыть с помощью…»и в открывшемся окне выберите, например, вот такой редактор:Откроется обычный текстовый редактор XAML-файла:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

здесь уже содержатся разрешения приложения, добавленные .NET MAUI по умолчанию. Измените файл следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <queries>
        <intent>
            <action android:name="android.intent.action.DIAL" />
            <data android:scheme="tel"/>
        </intent>
    </queries>
</manifest>

Теперь наше приложение сможет совершать звонки, используя приложения для набора номера абонента.

Команда набора телефонного номера

Теперь перейдем к модели представления ContactsViewModel и добавим в неё ещё одну команду:

public class ContactsViewModel: INotifyPropertyChanged
{
    ...

    public ICommand CallCommand { get; set; }

    public ContactsViewModel() 
    {

        CallCommand = new Command(() => 
        {
            if (PhoneDialer.Default.IsSupported)
            {
                if (SelectedPhone != null)
                   PhoneDialer.Default.Open(SelectedPhone.PhoneNumber);
            }
        });

        ...
    }

    ...
}

здесь мы проверяем поддерживается ли набор номера на устройстве и выбран ли какой-либо номер в приложении и, если оба условия возвращают true, то открываем приложение для набора номера с уже набранным номером телефона.

Добавим новую кнопку на страницу 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"
             xmlns:local="clr-namespace:MauiPhone.ViewModels"
             xmlns:model="clr-namespace:Microsoft.Maui.ApplicationModel.Communication;assembly=Microsoft.Maui.Essentials"
             x:Class="MauiPhone.MainPage"
             x:DataType="local:ContactsViewModel">

    <ScrollView>
        <VerticalStackLayout
            Padding="30,0"
            Spacing="25">

            ...

            <Button Text="Набрать номер" Command="{Binding CallCommand}" />

        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

Теперь можно запустить приложение и проверить его работу. Приложение сразу после запуска:

Набор телефонного номера в .NET MAUIТеперь, если загрузите контакты или выберите контакт из телефонной книги, а затем выберите телефонный номер в списке телефонов. Например,

Набор телефонного номера в .NET MAUIНажмите «Набрать номер». Откроется приложение «Телефон» с уже набранным номером:

Набор телефонного номераИтого

Набор телефонного номера в .NET MAUI осуществляется с использованием интерфейса IPhoneDialer. Реализация по умолчанию для этого интерфейса содержится в свойстве Default статического класса PhoneDialer. Приложение .NET MAUI, использующее набор телефонного номера должно определять в манифесте приложения специальный XML-узел <query> для того, чтобы взаимодействовать с другими приложениями для телефонных звонков на устройстве.

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