《深入淺出Windows Phone 8應用開發》之程序聯系人存儲
程序聯系人存儲是第三方的應用程序創建的聯系人數據,這些聯系人的數據也可以在手機的通訊錄里面進行顯示,但是它們是由創建這些聯系人數據的第三方應用程序所管理的。聯系人數據的歸屬應用程序可以設置這些聯系人數據的系統和其他程序的訪問權限,對屬於它自己的聯系人具有增刪改的權限,並且一旦用戶卸載了聯系人數據歸屬應用程序,這些聯系人也會被刪除掉。程序聯系人存儲的API在空間Windows.Phone.PersonalInformation下,下面來看一下如何去使用這些API來操作聯系人。
ContactStore類和StoredContact類
ContactStore類表示一個Windows Phone應用程序的自定義聯系人存儲,它是應用程序存儲的一個管理者,負責管理應用程序所創建的聯系人。ContactStore類的主要成員如表15.9所示。StoredContact類表示一個應用程序自定義的聯系人存儲,它繼承了IContactInformation接口,所有由應用程序創建的聯系人都是一個StoredContact類的對象。StoredContact類的主要成員如表15.10所示。
表15.9 ContactStore類的主要成員
成員 |
說明 |
public ulong RevisionNumber { get; } |
聯系人存儲的版本號 |
public ContactQueryResult CreateContactQuery() |
創建一個默認的聯系人查詢,返回ContactQueryResult對象,包含了存儲中的聯系人 |
public ContactQueryResult CreateContactQuery(ContactQueryOptions options) |
創建一個自定義的聯系人查詢,返回ContactQueryResult對象,包含了存儲中的聯系人 |
public static IAsyncOperation<ContactStore> CreateOrOpenAsync() |
異步方法創建或者打開應用程序的自定義聯系人存儲,假如存儲不存在將創建一個存儲 |
public static IAsyncOperation<ContactStore> CreateOrOpenAsync(ContactStoreSystemAccessMode access, ContactStoreApplicationAccessMode sharing) |
異步方法創建或者打開應用程序的自定義聯系人存儲,假如存儲不存在將創建一個存儲,返回當前的聯系人存儲對象 access:聯系人是否可以在手機系統通訊錄里面進行編輯還是只能在應用程序中創建 sharing:是否存儲的聯系人所有屬性都可以在另外的應用程序里面進行訪問 |
public IAsyncAction DeleteAsync() |
異步方法刪除應用程序的聯系人存儲 |
public IAsyncAction DeleteContactAsync(string id) |
異步方法通過聯系人的ID刪除應用程序里面存儲的聯系人 |
public IAsyncOperation<StoredContact> FindContactByIdAsync(string id) |
異步方法通過ID查找應用程序的聯系人,返回StoredContact對象 |
public IAsyncOperation<StoredContact> FindContactByRemoteIdAsync(string id) |
異步方法通過remote ID查找應用程序的聯系人,返回StoredContact對象 |
public IAsyncOperation<IReadOnlyList<ContactChangeRecord>> GetChangesAsync(ulong baseREvisionNumber) |
異步方法通過聯系人的版本號獲取聯系人改動記錄 |
public IAsyncOperation<IDictionary<string, object>> LoadExtendedPropertiesAsync() |
異步方法加載應用程序聯系人的擴展屬性Map表 |
public IAsyncAction SaveExtendedPropertiesAsync(IReadOnlyDictionary<string, object> data) |
異步方法保存應用程序聯系人的擴展屬性Map表 |
表15.10 StoredContact類的主要成員
成員 |
說明 |
public StoredContact(ContactStore store) |
通過當前應用程序的ContactStore來初始化一個StoredContact對象 |
public StoredContact(ContactStore store, ContactInformation contact) |
通過ContactStore對象和ContactInformation對象來創建一個StoredContact對象,StoredContact對象的信息由ContactInformation對象來提供 |
public string DisplayName { get; set; } |
獲取或設置一個存儲聯系人的顯示名稱 |
public IRandomAccessStreamReference DisplayPicture { get; } |
獲取一個存儲聯系人的圖片 |
public string FamilyName { get; set; } |
獲取或設置一個存儲聯系人的家庭姓 |
public string GivenName { get; set; } |
獲取或設置一個存儲聯系人的名字 |
public string HonorificPrefix { get; set; } |
獲取或設置一個存儲聯系人的尊稱前綴 |
public string HonorificSuffix { get; set; } |
獲取或設置一個存儲聯系人的尊稱后綴 |
public string Id { get; } |
獲取應用程序存儲聯系人的ID |
public string RemoteId { get; set; } |
獲取或設置應用程序聯系人的RemoteId |
public ContactStore Store { get; } |
獲取當前應用程序聯系人所在的聯系存儲對象 |
public IAsyncOperation<IRandomAccessStream> GetDisplayPictureAsync() |
獲取一個存儲聯系人的圖片 |
public IAsyncOperation<System.Collections.Generic.IDictionary<string, object>> GetExtendedPropertiesAsync() |
異步方法獲取聯系人的擴展屬性Map表 |
public IAsyncOperation<System.Collections.Generic.IDictionary<string, object>> GetPropertiesAsync() |
異步方法獲取聯系人的已知屬性Map表 |
public IAsyncAction ReplaceExistingContactAsync(string id) |
異步方法使用當前的聯系兒人來替換聯系人存儲中某個ID的聯系人 |
public IAsyncAction SaveAsync() |
異步方法保存當前的聯系人到聯系人存儲中 |
public IAsyncAction SetDisplayPictureAsync(IInputStream stream) |
異步方法保存當前的聯系人的圖片 |
public IAsyncOperation<IRandomAccessStream> ToVcardAsync() |
異步方法把當前的聯系人轉化為VCard信息流 |
15.3.2 程序聯系人的新增
新增程序聯系人需要先創建或者打開程序的聯系人存儲ContactStore,並且可以設置該程序聯系人存儲的被訪問權限。創建的代碼如下:
ContactStore conStore = await ContactStore.CreateOrOpenAsync();
聯系人存儲對於系統通訊和其他程序的都有權限的限制,ContactStoreSystemAccessMode枚舉表示手機系統通訊錄對應用程序聯系人的訪問權限,有ReadOnly只讀權限和ReadWrite讀寫兩個權限,ContactStoreApplicationAccessMode枚舉表示第三方應用程序對應用程序聯系人的訪問權限類型,有LimitedReadOnly限制只讀權限和ReadOnly只讀權限。上面的代碼創建聯系人存儲的代碼是默認用了最低的訪問權限來來創建聯系人存儲,即聯系人對於系統通訊錄是只讀的權限,對於其他程序的訪問權限是限制只讀權限。下面來看一下自定義權限的創建聯系人存儲。
//創建一個系統通訊可以讀寫和其他程序只讀的聯系人存儲
ContactStore conStore = await ContactStore.CreateOrOpenAsync(ContactStoreSystemAccessMode.ReadWrite, ContactStoreApplicationAccessMode.ReadOnly);
接下來看一下如何創建一個聯系人:
1.第一種方式直接通過聯系人存儲創建聯系人
//創建或者打開聯系人存儲
ContactStore conStore = await ContactStore.CreateOrOpenAsync();
//保存聯系人
StoredContact storedContact = new StoredContact(conStore);
// 設置聯系人的展示名稱
storedContact.DisplayName = "展示名稱";
//保存聯系人
await storedContact.SaveAsync();
2.第二種方式通過ContactInformation類對象創建聯系人
ContactInformation類表示一個非系統存儲中聯系人的聯系人信息。ContactInformation類的主要成員如表15.11所示。
//創建一個ContactInformation類
ContactInformation conInfo = new ContactInformation();
// 獲取ContactInformation類的屬性map表
var properties = await conInfo.GetPropertiesAsync();
//添加電話屬性
properties.Add(KnownContactProperties.Telephone, "123456");
//添加名字屬性
properties.Add(KnownContactProperties.GivenName, "名字");
//創建或者打開聯系人存儲
ContactStore conStore = await ContactStore.CreateOrOpenAsync();
//保存聯系人
StoredContact storedContact = new StoredContact(conStore, conInfo);
//保存聯系人
await storedContact.SaveAsync();
表15.11 ContactInformation類主要成員
成員 |
說明 |
ContactInformation() |
初始化 |
string DisplayName |
聯系人的顯示名字 |
IRandomAccessStreamReference DisplayPicture |
聯系人圖片信息 |
string FamilyName |
聯系人姓 |
string GivenName |
名字 |
string HonorificPrefix |
尊稱前綴 |
string HonorificSuffix |
尊稱后綴 |
IAsyncOperation<IRandomAccessStream> GetDisplayPictureAsync() |
異步獲取聯系人圖片 |
IAsyncOperation<System.Collections.Generic.IDictionary <string, object>> GetPropertiesAsync() |
異步獲取聯系人的Map表信息 |
IAsyncOperation<ContactInformation> ParseVcardAsync(IInputStream vcard) |
異步解析一個VCard數據流為ContactInformation對象 |
IAsyncAction SetDisplayPictureAsync(IInputStream stream) |
異步設置聯系人的圖片通過圖片數據流 |
IAsyncOperation<IRandomAccessStream> ToVcardAsync() |
異步轉換ContactInformation對象為一個VCard信息流 |
程序聯系人的查詢
聯系人查詢也需要創建聯系人存儲,創建聯系人存儲的形式和聯系人新增是一樣的。聯系人查詢是通過ContactStore的CreateContactQuery方法來創建一個查詢,可以查詢的參數ContactQueryOptions來設置查詢返回的結果和排序的規則,創建的查詢時ContactQueryResult類型。可以通過ContactQueryResult類的GetContactsAsync異步方法獲取聯系人存儲中的聯系人列表和通過GetCurrentQueryOptions方法獲取當前的查詢條件。下面來看創建聯系人查詢的代碼如下:
conStore = await ContactStore.CreateOrOpenAsync();
ContactQueryResult conQueryResult = conStore.CreateContactQuery();
uint count = await conQueryResult.GetContactCountAsync();
IReadOnlyList<StoredContact> conList = await conQueryResult.GetContactsAsync();
程序聯系人的編輯
聯系人編輯刪除也需要創建聯系人存儲,創建聯系人存儲的形式和聯系人新增是一樣的。聯系人的編輯需要首先要獲取要編輯的聯系人,獲取編輯的聯系人可以通過聯系人的id或者remoteid來獲取,獲取到的聯系人是一個StoredContact對象,通過修改該對象的屬性,然后再調用SaveAsync保存方法就可以實現編輯聯系人了。刪除聯系人的可以分為刪除一個聯系人和刪除所有的聯系人,刪除一個聯系人的可以通過聯系人的id然后調用ContactStore的DeleteContactAsync方法來進行刪除,如果要刪除所有的聯系人那么就要調用ContactStore的DeleteAsync方法。聯系人的新增,編輯和刪除都會有相關的操作記錄,GetChangesAsync方法來獲取聯系人的修改記錄。下面來看一下修改一個聯系人的代碼:
ContactStore conStore = await ContactStore.CreateOrOpenAsync();
StoredContact storCon = await conStore.FindContactByIdAsync(id);
var properties = await storCon.GetPropertiesAsync();
properties[KnownContactProperties.Telephone] = "12345678";
await storCon.SaveAsync();
程序聯系人的刪除
刪除聯系人的可以分為刪除一個聯系人和刪除所有的聯系人,刪除一個聯系人的可以通過聯系人的id然后調用ContactStore的DeleteContactAsync方法來進行刪除,如果要刪除所有的聯系人那么就要調用ContactStore的DeleteAsync方法。聯系人的新增,編輯和刪除都會有相關的操作記錄,GetChangesAsync方法來獲取聯系人的修改記錄。下面來看一下刪除一個聯系人的代碼:
ContactStore conStore = await ContactStore.CreateOrOpenAsync();
await conStore.DeleteContactAsync (id);
await conStore.DeleteAsync ();
實例演示聯系人存儲的使用
下面給出查詢日程安排的示例:查詢手機里面所有的日程安排信息。
代碼清單15-3:聯系人存儲的增刪改(源代碼:第15章\Examples_15_3)
MainPage.xaml文件主要代碼:聯系人新增頁面
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel> <TextBlock HorizontalAlignment="Left" Text="名字" FontSize="30"/> <TextBox HorizontalAlignment="Left" x:Name="name" Height="85" Text="" Width="296"/> <TextBlock HorizontalAlignment="Left" Text="電話" FontSize="30" /> <TextBox HorizontalAlignment="Left" x:Name="phone" Height="85" Text="" Width="296"/> <Button Content="保存" HorizontalAlignment="Left" Width="308" Height="91" Click="Button_Click_1"/> <Button Content="查詢應用存儲的聯系人" HorizontalAlignment="Left" Width="308" Height="91" Click="Button_Click_2"/> </StackPanel> </Grid>
MainPage.xaml.cs文件主要代碼
// 新增一個聯系人 private async void Button_Click_1(object sender, RoutedEventArgs e) { if (name.Text != "" && phone.Text != "") { try { // 創建一個聯系人的信息對象 ContactInformation conInfo = new ContactInformation(); // 獲取聯系人的屬性字典 var properties = await conInfo.GetPropertiesAsync(); // 添加聯系人的屬性 properties.Add(KnownContactProperties.Telephone, phone.Text); properties.Add(KnownContactProperties.GivenName, name.Text); // 創建或者打開聯系人存儲 ContactStore conStore = await ContactStore.CreateOrOpenAsync(); StoredContact storedContact = new StoredContact(conStore, conInfo); // 保存聯系人 await storedContact.SaveAsync(); MessageBox.Show("保存成功"); } catch (Exception ex) { MessageBox.Show("保存失敗,錯誤信息:" + ex.Message); } } else { MessageBox.Show("名字或電話不能為空"); } } // 跳轉到聯系人列表頁面 private void Button_Click_2(object sender, RoutedEventArgs e) { NavigationService.Navigate(new Uri("/ContactsList.xaml", UriKind.Relative)); }
ContactsList.xaml文件主要代碼:聯系人列表頁面
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel> <ListBox x:Name="conListBox" ItemsSource="{Binding}" > <ListBox.ItemTemplate > <DataTemplate> <StackPanel> <TextBlock Text="{Binding Name}" /> <TextBlock Text="{Binding Id}" /> <TextBlock Text="{Binding Phone}" /> <Button Content="刪除" HorizontalAlignment="Left" Width="308" Height="91" Click="Button_Click_1"/> <Button Content="編輯" HorizontalAlignment="Left" Width="308" Height="91" Click="Button_Click_2"/> <TextBlock Text="————————————————————————" /> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </StackPanel> </Grid>
ContactsList.xaml.cs文件主要代碼
private ContactStore conStore;//聯系人存儲 public ContactsList() { InitializeComponent(); } // 進入頁面事件 protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { GetContacts(); base.OnNavigatedTo(e); } // 獲取聯系人列表 async private void GetContacts() { conStore = await ContactStore.CreateOrOpenAsync(); ContactQueryResult conQueryResult = conStore.CreateContactQuery(); // 查詢聯系人 IReadOnlyList<StoredContact> conList = await conQueryResult.GetContactsAsync(); List<Item> list = new List<Item>(); foreach (StoredContact storCon in conList) { var properties = await storCon.GetPropertiesAsync(); list.Add( new Item { Name = storCon.FamilyName + storCon.GivenName, Id = storCon.Id, Phone = properties[KnownContactProperties.Telephone].ToString() }); } conListBox.ItemsSource = list; } // 刪除聯系人事件處理 private async void Button_Click_1(object sender, RoutedEventArgs e) { Button deleteButton = sender as Button; Item deleteItem = deleteButton.DataContext as Item; await conStore.DeleteContactAsync(deleteItem.Id); GetContacts(); } // 跳轉到編輯聯系人頁面 private void Button_Click_2(object sender, RoutedEventArgs e) { Button deleteButton = sender as Button; Item editItem = deleteButton.DataContext as Item; NavigationService.Navigate(new Uri("/EditContact.xaml?Id=" + editItem.Id, UriKind.Relative)); } } // 自定義綁定的聯系人數據對象 class Item { public string Name { get; set; } public string Id { get; set; } public string Phone { get; set; } }
EditContact.xaml文件主要代碼:聯系人編輯頁面
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <StackPanel> <TextBlock HorizontalAlignment="Left" Text="名字" FontSize="30"/> <TextBox HorizontalAlignment="Left" x:Name="name" Height="85" Text="" Width="296"/> <TextBlock HorizontalAlignment="Left" Text="電話" FontSize="30" /> <TextBox HorizontalAlignment="Left" x:Name="phone" Height="85" Text="" Width="296"/> <Button Content="保存" HorizontalAlignment="Left" Width="308" Height="91" Click="Button_Click_1"/> </StackPanel> </Grid>
EditContact.xaml.cs文件主要代碼
private string conId = ""; private ContactStore conStore;//聯系人數據存儲 private StoredContact storCon; //聯系人對象 private IDictionary<string, object> properties;//聯系人屬性字典 public EditContact() { InitializeComponent(); } // 進入頁面事件處理 protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e) { // 通過聯系人的id獲取聯系人的信息 if (NavigationContext.QueryString.ContainsKey("Id")) { conId = NavigationContext.QueryString["Id"].ToString(); GetContact(conId); } base.OnNavigatedTo(e); } // 保存編輯的聯系人 private async void Button_Click_1(object sender, RoutedEventArgs e) { if (name.Text != "" && phone.Text != "") { storCon.GivenName = name.Text; properties[KnownContactProperties.Telephone] = phone.Text; await storCon.SaveAsync();//保存聯系人 NavigationService.GoBack(); //返回上一個頁面 } else { MessageBox.Show("名字或者電話不能為空"); } } // 獲取需要編輯的聯系人信息 async private void GetContact(string id) { conStore = await ContactStore.CreateOrOpenAsync(); storCon = await conStore.FindContactByIdAsync(id); properties = await storCon.GetPropertiesAsync(); name.Text = storCon.GivenName; phone.Text = properties[KnownContactProperties.Telephone].ToString(); } phone.Text = properties[KnownContactProperties.Telephone].ToString(); }
程序的運行效果如圖所示