Windows Phone 7 - 存取聯絡人與行事曆資料

Windows Phone 7 - 存取聯絡人與行事曆資料

在WP 7.0的時候App要與聯絡人溝通需要透過Chooser的方式,例如:EmailAddressChooserTask、PhoneNumberChooserTask。

但是到了WP 7.1之後,針對存取聯絡人資料的功能更加強了,並且支援存取行事曆的資料。因此,隨著Mango更新之後便可以在

Marketplace看到很多結合聯絡人與行事曆相關的功能,包括:WhatsApp(存取聯絡人)、Tasks(存取行事曆)…等。

 

〉WP7.1 提供的匯總資料範圍(Aggregated Data Sources)

WP7.1 針對聯絡人/行事曆的部分提供了匯總的機制,將不同的帳號之間的聯絡人/行事曆資訊匯總起來,因此,資料來源可能包括:

原Windows Live ID聯絡人、系統中的連絡人/行事曆資訊、Facebook聯絡人或其他資料來源。然而,這些資料也不是全部都可以取得到,

需要依照該帳戶對應設定的公開(publicly)程度來決定。因此,在存取Contacts與Calendar API時,可以透過StorageKind enumeration來找

出可能存取的資料清單。

 

以下為MSDN所提供針對不同資料來源提供可存取的範圍表:

Data Provider Contact Name Contact Picture Other contact data Calendar appointments StorageKind enumeration
Windows Phone Device
(資料來自電話本身,例如:sim卡聯絡電話)
Yes Yes Yes Yes Phone
預設是取得該來源的資料內容。
Windows Live Social
(資料來自Windows Live帳號)
Yes Yes Yes Yes WindowsLive
Windows Live Rolodex
(資料來自Windows Live帳號)
Yes Yes Yes Yes WindowsLive
Exchange Accounts
(Contacts are from the local address book only, not the global address list.)(資料來自Outlook帳號)
Yes Yes Yes Yes Outlook
Mobile Operator Address Book
(資料來自其他的位置)
Yes Yes Yes No Other
Facebook
(資料來自Facebook帳號)
Yes Yes No No Facebook
Windows Live Aggregated Networks (Twitter, LinkedIn, and so on)(由Windows Live匯總的其他帳號來源,例如:Twitter等) No No No No None

由上表可以得知目前WP7.1針對聯絡人與行事曆提供存取的功能範圍。

 

在練習實作Contact與Calendar API互動時,有幾個重要的元素需要去了解:

 

Microsoft.Phone.UserData Namespace

   UserData命名空間主要整合了WP7用戶的聯絡人與行事曆資料,讓開發人員可以透過該命名空間中的類別與資料進行互動。

主要互動類別:Contacts、Contact、Appointments、Appointment。以下將仔細說明。

a. Contacts Class & Contact Class

    Contacts允許App搜尋用戶的聯絡人資訊,並且回傳一個Contact物件,Contact物件是集合個體,其內容擁有相關搜尋結果的聯絡人資料。

    a-1. Contacts

           該類別提供了搜尋的方法與對應的事件,加以整合所有的用戶聯絡人資訊。重點屬性、事件與方法:

           a-1-1. SearchAsync:提供非同步的方法搜尋聯絡人資訊。搜尋完成時,觸發SearchCompleted事件。另外,在使用SearchAsync方法時,

                                             有三個重要的參數:SearchAsync(string filter, FilterKind  filterkind, Object state):

                          ‧filter:搜尋聯絡人的字串;

                          ‧filterkind:指定搜尋聯絡人的類型;類型包括:

                                                  EmailAddress、PhoneNumber、DisplayName,這三種需要配合filter一起使用;

                                                  None、PinnedToStar,filter為空白即可以使用;

                          ‧state:用戶自行定義的資訊包括運作時要搜尋的match樣式。而state會出現在SearchCompleted中的參數:ContactsSearchEventArgs

           a-1-2. SearchCompleted:當SearchAsync完成後即觸發該事件,該事件中可以取得搜尋結果的Contact集合。

           a-1-3. Accounts:取得所有可用的聯絡人資料來源。

           a-1-4. BaseUri:取得<PhoneDataSharingContext>分享的聯絡人與行事曆資訊。透過Uri來識別資料的內容。

 

    a-2. Contact

           該類別包含了所有個別用戶的可用聯絡資訊。可取得的屬性資料包括:Address、Birthdays、CompleteName、PhoneNumbers、

           IsPinnedToStart、DisplayName、Accounts等相關資訊。有些屬性是複數的名詞其中都是資料的集合要特別注意。

 

   a-3. 範例說明:指定搜尋所有的聯絡人。

   1: private void GetContact()
   2: {
   3:     //實例化Contacts類別
   4:     Contacts tContancts = new Contacts();
   5:     //註冊SearchCompleted事件處理
   6:     tContancts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(tContancts_SearchCompleted);
   7:     //利用FilterKind.None指定搜尋所有的聯絡人。
   8:     tContancts.SearchAsync(string.Empty, FilterKind.None, null);
   9: }
  10:  
  11: void tContancts_SearchCompleted(object sender, ContactsSearchEventArgs e)
  12: {
  13:     lstContacts.DataContext = e.Results;
  14: }

 

b. Appointments Class & Appointment Class

    Appointments允許App搜尋用戶的行事曆資訊,並且回傳Appointment物件集合,Appointment物件是資料實體,其內容擁有相關搜尋結果

    的行事曆約會資料。Appointments與Contacts的機制相近採用非同步(asynchronous)執行搜尋的任務。往下介紹幾個執行時需注意的方法:

    b-1. Appointments

           該類別提供了搜尋的方法與對應的事件,加以整合用戶行事曆中約會資訊。重點屬性、事件與方法:

           b-1-1. SearchAsync:提供搜尋用戶行事曆中的約會資訊。由於此方法是多載的型式,因此,針對不同的參數加以說明:

                                      ‧SearchAysnc(DateTime, DateTime, Object):

                                                           搜尋在指定啟始與結束時間區段的約會資訊。

                                      ‧SearchAysnc(DateTime, DateTime, Accout, Object):

                                                           搜尋在指定Account、啟始與結束時間區段的約會資訊。

                                      ‧SearchAsync(DateTime, DateTime, Int32, Object):

                                                           搜尋在指定啟始與結束時間區段的約會資訊,根據指定的回傳數量回傳結果。

                                      ‧SearchAysnc(DateTime, DateTime, Int32, Account, Object):

                                                           搜尋在指定Account、啟始與結束時間區段的約會資訊,根據指定的回傳數量回傳結果。                                           

           b-1-2. SearchCompleted:當SearchAsync完成後即觸發該事件,該事件中可以取得搜尋結果的Appointment集合。

           b-1-3. DefaultMaximumItems:預設搜尋結果的回傳數量。

           b-1-4. Accounts:取得所有可用的行事曆資料來源。

           b-1-5. BaseUri:取得<PhoneDataSharingContext>分享的聯絡人與行事曆資訊。透過Uri來識別資料的內容。

 

    b-2. Appointment

           該類別包含了所有相關此約會的所有資訊。可取得的屬性資料包括:Attendee、Details、StartTime、EndTime、IsPrivate等相關資訊。

 

    b-3. 範例說明:搜尋指定時間內的所有約會清單:

   1: private void ListAppointments()
   2: {
   3:     //實例化Appointments類別
   4:     Appointments tCalendar = new Appointments();
   5:     //註冊SearchCompleted事件處理
   6:     tCalendar.SearchCompleted += new EventHandler<AppointmentsSearchEventArgs>(tCalendar_SearchCompleted);
   7:     
   8:     //設定Start time與End time
   9:     DateTime tStart = DateTime.Now.AddDays(-3);
  10:     DateTime tEnd = DateTime.Now;
  11:     //搜尋,並指定回傳前10筆資料
  12:     tCalendar.SearchAsync(tStart, tEnd, 10, null);
  13: }
  14:  
  15: void tCalendar_SearchCompleted(object sender, AppointmentsSearchEventArgs e)
  16: {
  17:     lstAppointments.DataContext = e.Results;
  18: }

 

以上是針對使用聯絡人與行事曆API的介紹,其MSDN中也有提供相當容易的範例。如果想了解SearchAsync在搜尋比對的依據,

可以參考<Contact Filtering and Matching for Windows Phone>內容,裡面詳細表列了在人名、電話與Mail上的搜尋比對方式。

 

[注意]

a. 特別提醒的是這些聯絡人或行事曆的資料是「read-only」的。

b. 在開發支援存取聯絡人與行事曆資料的App時,記得告知用戶該App會存取到他的聯絡人與行事曆宣告隱私權與相關權限的使用。

c. App的WMAppManifest.xml記得設定對應的Capability,App送審時才會通過,可參考<Application Manifest File for Windows Phone>。

   1: <Capabilities>
   2:  <Capability Name="ID_CAP_CONTACTS"/>
   3: </Capabilities>

d. 當在程式中宣告使用Contact Data時,系統是採用Snapshot(快照)機制,所以資料都是read-only的。如果需要最新的資料,

    建議定期初始化搜尋的元件與Contact instance。

e. 由於Contact資料來源很多種,因此App使用到的Contact資料大小通常是不固定的。因此,建議在讀取過程裡顯示通知介面(如ProgressBar)

    告知用戶目前App處理的狀態。

 

[補充]

〉取得與顯示Contact中聯絡人圖片

在MSDN<How to: Display the Photo of a Contact for Windows Phone>中介紹「Data Binding Photos to the User Interface」的做法,

我覺得需要好好研究一下,開發過WP7或Silverlight的人應該都知道,在實作ListBox時可以透過DataBinding的方式,將資料與XAML直接

結合,不一定需要從後端寫程式一個個Insert至Item中,但使用前提是要Insert的Item需要是Data Item並且指定結合的對象要是屬性才行。

由於Contact中的取得圖片不是一個屬性(而是使用Contact.GetPicture方法),因此沒有辦法直接在DataBinding中直接使用。

 

MSDN裡介紹了一個實作轉換的方法,讓在XAML中直接指定對應的方法,即可以完成。往下來看看是怎麼實作的:

a. 在要呈現聯絡人資料的程式(例如:ContactsPage.xaml.cs)之後,增加延伸轉換Value的類別

    為何需要加在指定的Page.cs之後呢?主要是限定該延伸轉換Value的類別,只限定於該Page中使用。當然,如果這方法需要被其他Page使用,

    可以移到App.xaml.cs之中。以下擷取MSDN上的範例程式:

   1: namespace ContactsAndCalendar
   2: {
   3:     public partial class MainPage : PhoneApplicationPage {// ... Main Page的處理邏輯  }
   4:  
   5:     /// <summary>
   6:     /// 客製一個轉換聯絡人圖片的類別,透過實作IValueConverter Interface覆寫指定轉換的功能。
   7:     /// </summary>
   8:     public class ContactPictureConverter : System.Windows.Data.IValueConverter
   9:     {        
  10:         public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  11:         {
  12:             Contact c = value as Contact;
  13:             if (c == null) return null;
  14:  
  15:             System.IO.Stream imageStream = c.GetPicture();
  16:             if (null != imageStream)
  17:             {
  18:                 //回傳writeableBitmap
  19:                 return Microsoft.Phone.PictureDecoder.DecodeJpeg(imageStream);
  20:             }
  21:             return null;
  22:         }
  23:  
  24:         public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  25:         {
  26:             throw new NotImplementedException();
  27:         }
  28:     }
  29: }

 

b. 在要呈現聯絡人資料頁面(例如:ContactsPage.xaml)的<phone:PhoneApplicationPage>裡加上獨立實作的xmlns

   1: //使用自己方案的名稱
   2: xmlns:MyApp="clr-namespace:ContactsAndCalendar"

 

c. 在<phone:PhoneApplicationPage>到第一個Grid element之間的空白,加上該Phone可以用的Resources

   1: <phone:PhoneApplicationPage.Resources>
   2:     <MyApp:ContactPictureConverter x:Key="ContactPictureConverter" />
   3: </phone:PhoneApplicationPage.Resources>

 

d. 在要顯示聯絡人的ListBox清單中加上Image Element與Board Element

   1: <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
   2:     <Grid.RowDefinitions>
   3:         <RowDefinition Height="100*" />
   4:     </Grid.RowDefinitions>
   5:     <ListBox Grid.Row="0" x:Name="lstContacts" Width="460" ItemsSource="{Binding}">
   6:         <ListBox.ItemTemplate>
   7:             <DataTemplate>
   8:                 <StackPanel Orientation="Horizontal" >
   9:                     <!-- 加上要呈現的Image範圍 -->
  10:                     <Border BorderThickness="2" HorizontalAlignment="Left" BorderBrush="{StaticResource PhoneAccentBrush}" >
  11:                         <Image Source="{Binding Converter={StaticResource ContactPictureConverter}}" Width="48" Height="48" Stretch="Fill" />
  12:                     </Border>
  13:                     <!-- 顯示聯絡人名稱 -->
  14:                     <TextBlock Text="{Binding Path=DisplayName, Mode=OneWay}" VerticalAlignment="Center" />
  15:                 </StackPanel>
  16:             </DataTemplate>
  17:         </ListBox.ItemTemplate>
  18:     </ListBox>
  19: </Grid>

 

f. 執行結果

 

以上是針對MSDN上介紹的方法加上一些自己的說明,另外,其中技術裡有用到<WriteableBitmap>的元件來將聯絡人圖片轉至Bitmap中,

讓指定的Image可以直接透過「Binding Converter={StaticResource ContactPictureConverter}」的方法來取得資料。至於WriteableBitmap

的相關說明可以參考<Windows Phone 7 – Screenshot你的WP7 App>裡面有更詳細的說明。

 

[範例程式]

======

以上是針對WP7存取聯絡人與行事曆API的部分。由於WP7跟其他系統一樣也支援整合了多種不同帳號的聯絡人資料,

因此,在開發過程裡一定要切記有效的去處理聯絡人的搜尋,這樣可以讓效能比較好一些。如果有寫錯的地方,也請

大家跟我提醒一下,謝謝,希望對大家有所幫助。

 

References:

Microsoft.Phone.UserData Namespace

Contacts and Calendar for Windows Phone

How to: Access Contact Data for Windows Phone

How to: Access Calendar Data for Windows Phone

How to: Display the Photo of a Contact for Windows Phone

Contact Filtering and Matching for Windows Phone (重要,可加速搜尋聯絡人的效果)

Walkthrough: Accessing Contact and Calendar Data for Windows Phone

Data Templating Overview & Data Binding Overview

How to retreive all contacts from Windows Phone 7 using C# ?

【译】如何通过C#代码检索出Windows Phone中的所有联系人

 

Dotblogs Tags: