酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows PhoneでContactsクラスを使って連絡先情報を取得する

Windows Phone OS 7.1からデバイスに保存されたユーザーの連絡先情報やカレンダー情報にアクセスすることが出来るようになりました。

今まではセレクターを通して取得していた情報が、アプリケーション内で扱えるようになり、連絡帳やカレンダーといった分野のアプリケーションの開発が可能となりました。

Marketplaceでこれらの情報を扱うアプリケーションを公開するのであれば、位置情報を使用する前にユーザーに注意する必要があります。

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

namespace UserDataTest {
    public partial class MainPage : PhoneApplicationPage {
        // コンストラクター
        public MainPage() {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e) {
            var contacts = new Contacts();
            
            // 連作先の取得は非同期で行われる為、
            contacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
            
            // フィルターを掛けずに連絡先を全件取得する
            contacts.SearchAsync(string.Empty, FilterKind.None, null);
        }

        // 検索後の連絡先を取得する
        void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e) {
            // 連絡先の数をメッセージボックスで表示する
            MessageBox.Show("検索件数:" + e.Results.Count());
        }
    }
}

ListBoxに並んだ連絡先を選択すると写真を表示する

取得した連絡先をListBoxに表示させ、選択した連絡先の写真を表示させてみます。

まずは連絡先を表示するListBoxと選択後の写真を表示するImageコントロールを配置します。

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
	
    <Button Content="Button" Height="72" HorizontalAlignment="Right" 
		Name="button1" VerticalAlignment="Top" Width="160" Click="button1_Click" />
		
    <ListBox Height="405" Name="listBox1" VerticalAlignment="Bottom" 
		FontSize="32" SelectionChanged="listBox1_SelectionChanged">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding DisplayName}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Image HorizontalAlignment="Left" Height="200" 
		VerticalAlignment="Top" Width="200" Name="image1" />
</Grid>

先ほどの例と同様に連絡帳を全件取得し、検索結果の連絡先をListBoxのItemsSourceへ設定します。あとは選択された連絡先から写真を取得して、BitmapImageオブジェクトを作成して、ImageコントロールのSourceプロパティに設定しています。

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

namespace UserDataTest {
    public partial class MainPage : PhoneApplicationPage {
        // コンストラクター
        public MainPage() {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e) {
            var contacts = new Contacts();
            
            // 連作先の取得は非同期で行われる為、
            contacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
            
            // フィルターを掛けずに連絡先を全件取得する
            contacts.SearchAsync(string.Empty, FilterKind.None, null);
        }

        // 検索後の連絡先を取得する
        void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e) {
            // 連絡先をリストに表示する
            listBox1.ItemsSource = e.Results;
        }

        private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e) {
            // 何も選択されていない場合は何もしない
            if (listBox1.SelectedIndex == -1) {
                image1.Source = null;
                return;
            }
            
            // 選択した連絡先から画像を取得する
            var contact = listBox1.SelectedItem as Contact;
            var strm = contact.GetPicture();
            if (strm == null) {
                image1.Source = null;
                return;
            }

            // 画像をImageコントロールに設定する
            var bmpImage = new BitmapImage();
            bmpImage.SetSource(strm);
            image1.Source = bmpImage;
        }
    }
}

Windows Phone エミュレータでは写真が登録されていませんでしたので、実機にて実行してみました。


検索フィルターを掛ける

先ほどのサンプルコードでは、連絡先情報を取得する際に検索フィルターの種類を無しにしていました。

contacts.SearchAsync(string.Empty, FilterKind.None, null);

第2引数のFilterKind列挙子と第1引数の検索キーワードを使用することで、OS組み込みの検索を行うことが出来ます。

フィルターの種類 取得対象
None 連絡先を全件取得する(フィルター無し)
PinnedToStart スタート画面に追加されている連絡先を全件取得する
DisplayName 該当する表示名の連絡先を取得する
EmailAddress 該当するメールアドレスの連絡先を取得する
PhoneNumber 該当する電話番号の連絡先を取得する

検索のフィルタリングをするのに、まず連絡先を全件取得してからLINQを使用してクエリすることも出来ますが、組み込み検索の方が処理が速いです。これは連絡先を格納しているデーターベースにてインデックスが付けられている為です。