Статьи

31 Дней Манго | День № 8: API контактов

Эта статья является 8-м днем ​​в серии под названием « 31 день манго» .

Day8-ContactsAPI

Если вы хотите попробовать приложение, которое я рассмотрю в статье на вашем устройстве, вы можете загрузить его с Windows Phone Marketplace.

DownloadIcon

Сегодня мы поговорим о новом пространстве имен, доступном на телефонах Windows: Microsoft.Phone.UserData. В первых 31 Днях Windows Phone я освещал тему в День № 8 «Выборщики» . С помощью этих задач мы смогли предложить пользователю выбрать запись из списка контактов на своем телефоне и извлечь из этого контакта определенную часть данных: адрес электронной почты или номер телефона, но не оба сразу.

Благодаря этому новому пространству имен в Windows Phone 7.5 теперь у нас есть возможность обрабатывать список контактов пользователя как локальную базу данных. Мы можем найти его, получить несколько контактов и получить всю их запись. Это намного более надежно, но работа с ним также намного более ручная.

Как примечание, так же, как напомнил ему дядя Питера Паркера Бен , «с большой силой приходит большая ответственность». Тот факт, что у вас есть доступ к списку контактов пользователя, не означает, что вы должны использовать эту привилегию. Установка вашего приложения на телефон пользователя требует высокого уровня доверия. Если вы нарушите это доверие, рассылая всем своим друзьям и знакомым по электронной почте и прочей ерунде, вы не только будете удалены, но и разочарование вашего пользователя будет отражено в негативных отзывах на рынке.

Наконец, важно помнить, что данные, к которым мы обращаемся, доступны только для чтения. Мы не можем делать обновления, удалять что-либо или даже добавлять что-либо. Это просто механизм для поиска некоторых или всех контактов на телефоне пользователя и использования этих данных в наших приложениях.

Создание нашего пользовательского интерфейса

Как и во всех наших статьях из этой серии, нам сначала нужно начать с пользовательского интерфейса. В этом примере мы используем стандартный шаблон приложения для Windows Phone, и я добавил ListBox с некоторыми обязательными операторами, которые мы будем использовать позже. Подробнее о привязке данных в XAML вы можете узнать в День № 13 из 31 Дня Silverlight . Я также добавил TextBox, который мы будем использовать для поиска по контактам.

Вот XAML, который мы будем использовать для этого приложения:

<phone:PhoneApplicationPage
   x:Class="Day8_ContactsAPI.MainPage"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
   xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
   mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
   FontFamily="{StaticResource PhoneFontFamilyNormal}"
   FontSize="{StaticResource PhoneFontSizeNormal}"
   Foreground="{StaticResource PhoneForegroundBrush}"
   SupportedOrientations="Portrait" Orientation="Portrait"
   shell:SystemTray.IsVisible="True">

    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="31 DAYS OF MANGO - DAY #8" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="contacts api" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <TextBox x:Name="SearchTerm" Height="80" Margin="0,-12,0,539" TextChanged="SearchTerm_TextChanged" />
            <ListBox x:Name="ContactList" Margin="0,70,0,0">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=DisplayName, Mode=OneWay}" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
    </Grid>
</phone:PhoneApplicationPage> 

В этом XAML следует обратить внимание на наш ListBox с именем «ContactList» и TextBlock внутри его DataTemplate. Мы связали этот TextBlock со значением DisplayName, которое мы собираемся извлечь из списка контактов нашего пользователя. Другой важной частью является TextBox с именем «SearchTerm». Мы будем использовать содержимое этого поля в качестве критерия поиска, реализовав обработчик события TextChanged. Вот как будет выглядеть наш последний интерфейс, когда мы закончим:

образ

Поиск контактных данных

В нашем файле с выделенным кодом мы должны убедиться, что у нас есть оператор using для пространства имен Microsoft.Phone.UserData. Это то, что позволяет нам получить доступ к контактной информации на устройстве.

Первый шаг — зафиксировать любые изменения текста в нашем TextBox. Мы уже определили обработчик событий в нашем XAML, но нам нужно создать метод обработчика событий. Вот наш начальный код C # с созданным обработчиком событий:

using System;
using System.Linq;
using System.Windows.Controls;
using Microsoft.Phone.Controls;
using Microsoft.Phone.UserData;

namespace Day8_ContactsAPI
{
    public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();
        }

        private void SearchTerm_TextChanged(object sender, TextChangedEventArgs e)
        {
            SearchContacts(SearchTerm.Text);
        }

        private void SearchContacts(string searchterm)
        {
             //PERFORM THE SEARCH
        }
    }
}
 

Как вы можете видеть, SearchTerm_TextChanged запускается каждый раз, когда значение в нашем TextBox изменяется, и я настроил его так, чтобы мы вызывали отдельный метод, SearchContacts, для фактического выполнения поиска. SearchContacts принимает строковый параметр, и мы будем использовать это значение в нашем фактическом поисковом коде.

Однако для фактического поиска в данных нам нужно создать новый экземпляр объекта Contacts. (Для этого нам нужно пространство имен Microsoft.Phone.UserData.) Чтобы получить эти данные, нам нужно выполнить асинхронный поиск по данным Контактов. У объекта Contacts есть обработчик события SearchCompleted, который мы будем использовать, чтобы получить результаты нашего поиска после его завершения. Наконец, мы будем использовать метод SearchAsync () для выполнения поиска по определенным критериям. Давайте посмотрим на наш последний C #, а затем я потрачу некоторое время на обсуждение различных параметров поиска, которые мы можем использовать.

using System;
using System.Linq;
using System.Windows.Controls;
using Microsoft.Phone.Controls;
using Microsoft.Phone.UserData;

namespace Day8_ContactsAPI
{
    public partial class MainPage : PhoneApplicationPage
    {
        Contacts contacts = new Contacts();

        public MainPage()
        {
            InitializeComponent();
            contacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
            SearchContacts(String.Empty);
        }

        private void SearchTerm_TextChanged(object sender, TextChangedEventArgs e)
        {
            SearchContacts(SearchTerm.Text);
        }

        void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
        {
            ContactList.ItemsSource = e.Results;
        }

        private void SearchContacts(string searchterm)
        {
            contacts.SearchAsync(searchterm, FilterKind.DisplayName, null);
        }
    }
} 

Как вы можете видеть в нашем методе конструктора, мы вызываем метод SearchContacts, который мы создали ранее, передавая String.Empty. Используя пустую строку, мы указываем методу SearchAsync (), что нам нужны ВСЕ контакты. Хотя в эмуляторе это будет работать нормально (по умолчанию в нем всего 7 контактов), телефон пользователя может иметь тысячи записей и может занять несколько секунд для загрузки. Помните об этом, когда будете использовать эту функцию, и рассмотрите возможность использования ProgressBar или какого-либо другого механизма, чтобы пользователь знал, что вы все еще собираете данные.

Если вы посмотрите на сигнатуру для метода Contacts.SearchAsync, он принимает три параметра:

  • Строка — это критерии поиска, которые вы используете. В нашем примере это содержимое TextBox, которое мы создали в нашем XAML-файле.
  • FilterKind — позволяет выполнять поиск только по PhoneNumber, DisplayName или EmailAddress. Если вы выберете None, строка критериев поиска будет игнорироваться.
  • объект — это параметр объекта, который можно использовать для передачи данных в поиск, чтобы при получении результатов вы что-то знали о том, что пытались выполнить. Это может быть так же просто, как строковый идентификатор, вплоть до конкретного объекта, который вам понадобится позже.

Если вы запустите приложение прямо сейчас, вы должны увидеть, что все, что вы введете в TextBox, отфильтрует результаты в вашем ListBox. Вот посмотрите на отфильтрованный список в эмуляторе Windows Phone:

образ

Глядя на необработанные данные

Итак, мы успешно запросили контакты на устройстве и привязали его к ListBox. Однако мы не видели, какие именно данные мы можем получить, и их много. Кроме того, поскольку мы получаем коллекцию данных IEnumerable из нашего поиска, мы можем использовать LINQ для запроса наших результатов.

Я изменил метод contacts_SearchCompleted из нашего примера выше, захватывая первую запись из данных и просто сохраняя некоторые значения в локальных переменных для демонстрации. Вы бы с большей вероятностью отобразили эти данные на экране или сохранили их в механизме хранения вашего приложения. Вот как выглядит этот новый метод с некоторыми доступными вам свойствами объекта Contact:

void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
    ContactList.ItemsSource = e.Results;

    //Grabbing the first record of our result.
    Contact patientZero = e.Results.FirstOrDefault();

    string firstname = patientZero.CompleteName.FirstName;
    string lastname = patientZero.CompleteName.LastName;

    string emailaddress = patientZero.EmailAddresses.FirstOrDefault().EmailAddress;
    string phonenumber = patientZero.PhoneNumbers.FirstOrDefault().PhoneNumber;

    bool isPinnedToStart = patientZero.IsPinnedToStart;
} 

Приведенный выше пример представляет собой небольшую выборку данных, доступных вам в записи контактов, и, в зависимости от ваших потребностей, практически все есть. Вот краткий список того, что вы можете получить (при условии, что это доступно в записи контактов).

  • Аккаунты — список аккаунтов, с которыми связан этот контакт. Это включает в себя такие вещи, как Facebook, Windows Live, Outlook и т. Д.
  • Адреса — список адресов для этого контакта. Каждый адрес также включает в себя «учетную запись» (сверху), с которой он связан, «тип» адреса, которым он является (например, рабочий, домашний и т. Д.), И, наконец, PhysicalAddress, который предоставляет все ожидаемые значения, такие как Address1, Город, государство, провинция и страна.
  • Дни рождения — я не уверен, почему у пользователя разные дни рождения, но каждая «учетная запись» может иметь разное значение, поэтому вы получаете список. Кроме того, если год не указан, в этих случаях вы получите значение «1» для года.
  • Дети — простой список строк, которые представляют имена детей контакта.
  • Компании — снова обогащенные данными учетных записей, включая такие значения, как JobTitle, CompanyName и OfficeLocation.
  • CompleteName — показанный в нашем примере кода выше, он содержит все свойства имени контакта, включая Title, Suffix, MiddleName и т. Д.
  • DisplayName — простая строка, представляющая имя, которое используется в телефоне для этого контакта.
  • EmailAddresses — список адресов электронной почты, с данными «account» и «kind».
  • IsPinnedToStart — это интересная часть логических данных, потому что она обычно указывает, какие из контактов этого пользователя являются для них наиболее важными (поскольку контакт прикреплен к начальному экрану пользователя).
  • Заметки — список строк, которые пользователь сохранил как заметки об этом контакте.
  • PhoneNumbers — список всех телефонных номеров, связанных с контактом, он также украшен «учетными записями» и «добрыми» данными ».
  • ВажныеДругие — вы хотели бы думать, что для этого тоже есть только одно значение, но … вы знаете … В любом случае, это похоже на свойство Children. Список строк.
  • Веб-сайты — список веб-сайтов, связанных с этим контактом, хранящихся в виде строк.

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

Итак, я думаю, что это довольно хороший стартовый набор для использования API контактов на Windows Phone. Все это пространство имен доступно только на телефонах с ОС Windows Phone 7.5, поэтому если вы работаете с приложением 7.0, вы не сможете его использовать. (Но на самом деле, почему вы все еще создаете приложение 7.0? Пора обновить!)

Чтобы загрузить работающее решение для Windows Phone, использующее весь код из этой статьи, нажмите кнопку «Загрузить код» ниже:

скачать

Завтра мы поговорим о другой стороне пространства имен UserData — API-интерфейсе календаря. Это еще один набор данных, предназначенный только для чтения, но он позволяет нам иметь некоторую информацию о доступности пользователя за определенный период времени. Увидимся позже!

toolsbutton