IT tutorials
 
Technology
 

Windows Phone 8 : Phone Integration - Contacts and Appointments

8/8/2013 11:23:20 AM
- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

Even though we can get caught up in the mystique of our phones as being little computers, most users actually use their phones to contact people and to keep their appointments.

So, as a developer, you might want to access the user’s contacts and appointments to more tightly integrate your applications into the phone experience. To do this, the Windows Phone SDK supports entry points into the user’s contacts and appointments. These APIs provide a way to search by commonly used search semantics but also return results that can be further filtered using LINQ.


Note

All access to the contacts and appointments is read-only. You cannot change, add, or delete any information in the list of contacts or appointments.


Contacts

To access the contacts on a phone, you will start with the Contacts class (in the Microsoft.Phone.UserData namespace). This class provides the capability to perform an asynchronous search for the contacts on the phone:

var contactCtx = new Contacts();

contactCtx.SearchCompleted += (s, a) =>
  {
    IEnumerable<Contact> contacts = a.Results;
    contactList.ItemsSource = results;
  };

contactCtx.SearchAsync(null, FilterKind.None, null);

The SearchAsync call takes three parameters: a filter string, a type of filter, and an object that is passed to the completed event (a state object). The first two parameters typically allow you to do basic filtering in the underlying data store and are specified as the most common filtering semantics. The FilterKind enumeration tells the search API how to treat the filter string. For example, to find a specific person you can search by name, like so:

contactCtx.SearchAsync("Chris Sells", FilterKind.DisplayName, null);

The FilterKind enumeration includes the members shown in Table 1.

TABLE 1 FilterKind Enumeration

Image

To use the FilterKind enumeration, you can specify the filter and the FilterKind enumeration in the SearchAsync method:

   contactCtx.SearchAsync("[email protected]",
                          FilterKind.EmailAddress,
                          null);

The result of a search is an IEnumerable collection of Contact objects. The Contacts class supports all the information about a particular contact. Because the data structure can be verbose (for example, there can be multiple phone numbers, addresses, company names, and so on), the class supports many collections for the various items in the data store. For instance, you can get the simple display name as a property, but to get the phone number of a contact you have to use LINQ against the collection:

IEnumerable<Contact> contacts = a.Results;

var contact = contacts.First();

string displayName = contact.DisplayName;
string phoneNumber = contact.PhoneNumbers.First().PhoneNumber;

This means that to meaningfully bind to the Contact, you will likely need to create a class that represents the data you want to show:

public class ContactInfo
{
  public string Name { get; set; }
  public ContactPhoneNumber PhoneNumber { get; set; }
  public DateTime? Birthday { get; set; }
  public ContactCompanyInformation Company { get; set; }
  public ImageSource Picture { get; set; }
  public ContactEmailAddress EmailAddress { get; set; }
}

Although you can have the bindable class only include basic types, you can also use the built-in data structures (for example, ContactPhoneNumber) because they do support binding. Luckily, building a collection of these bindable objects is easy using LINQ projections:

IEnumerable<Contact> contacts = a.Results;

var qry = from c in contacts
          select new ContactInfo()
                  {
                    Name = c.DisplayName,
                    EmailAddress = c.EmailAddresses.FirstOrDefault(),
                    PhoneNumber = c.PhoneNumbers.FirstOrDefault(),
                    Company = c.Companies.FirstOrDefault(),
                  };

var results = qry.ToList();

By using this technique of projecting into a new list of the contact information, you can easily build a ListBox using data binding:

<ListBox x:Name="contactList">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel Width="470">
       <TextBlock Text="{Binding Name}" />
        <TextBlock Text="{Binding EmailAddress.EmailAddress}" />
        <TextBlock Text="{Binding Company.CompanyName}" />
        <TextBlock Text="{Binding PhoneNumber.PhoneNumber}" />
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

You can see in the data binding that you can navigate down the data structure to the object you want to bind to. And because they are data bindings, if the user does not have one of these objects, the binding silently fails (which is one of the advantages of doing this in a binding).

Of course, because you can use LINQ to query against the resultant collection, you can use it if the FilterKind enumeration does not give you the granularity you need to find contacts. Although this works well, be aware that loading all contacts in memory can consume a lot of memory. For example, if you want to find all the contacts who have a phone number in the 206 area code (as well as sort them by display name), you can just use LINQ:

var qry = from c in contacts
          where c.PhoneNumbers
                 .Any(phone => phone.PhoneNumber.Contains("(206)"))
          orderby c.DisplayName
          select new ContactInfo()
                  {
                    Name = c.DisplayName,
                    EmailAddress = c.EmailAddresses.FirstOrDefault(),
                    PhoneNumber = c.PhoneNumbers.FirstOrDefault(),
                    Company = c.Companies.FirstOrDefault(),
                  };

In addition to the basic contact information, you can also ascertain which accounts the user contacts. The Contacts class exposes a list of the user’s accounts. Each account will tell you the kind of account (for example, Facebook, Microsoft Account, Outlook, and so on) as well as the name of the account:

Account first = contactCtx.Accounts.FirstOrDefault();
if (first != null)
{
  string accountName = first.Name;
  if (first.Kind == StorageKind.Facebook)
  {
    MessageBox.Show("Your first account is Facebook");
  }
}

You cannot filter by account through the SearchAsync method, but you can filter any of the associated objects by account. For instance, to filter contacts by account, simply use the following:

Account first = contactCtx.Accounts.FirstOrDefault();

var qry = from c in contacts
          where c.Accounts.Contains(first)
          select new ContactInfo()
                  {
                    Name = c.DisplayName,
                    EmailAddress = c.EmailAddresses.FirstOrDefault(),
                    PhoneNumber = c.PhoneNumbers.FirstOrDefault(),
                    Company = c.Companies.FirstOrDefault(),
                  };

Most of the objects related to contacts also have an account associated with them. For example, if you have a contact, you can find out which email address is from Facebook, like so:

Contact theContact = contacts.First();

var addr = theContact.EmailAddresses
  .Where(email => email.Accounts
                       .Any(a => a.Kind == StorageKind.Facebook))
  .FirstOrDefault();

Lastly, each contact can have a picture associated with it. This picture is not immediately returned with the contact (because that could occupy a large chunk of memory). To access the picture, the Contacts class has a GetPicture method that returns a Stream object containing the image. Although this is useful, you’ll probably need to wrap it with an ImageSource object to use it in data binding. One approach is to do this during the projection into the bindable class, like so:

var qry = from c in contacts
          select new ContactInfo()
                  {
                    Name = c.DisplayName,
                    EmailAddress = c.EmailAddresses.FirstOrDefault(),
                    PhoneNumber = c.PhoneNumbers.FirstOrDefault(),
                    Company = c.Companies.FirstOrDefault(),
                    Picture = CreateImageSource(c.GetPicture())
                  };

The implementation of the CreateImageSource method that does the wrapping looks like this:

ImageSource CreateImageSource(Stream stream)
{
  if (stream == null) return null;
  var src = new BitmapImage();
  src.SetSource(stream);
  return src;
}

Because data binding can’t turn a Stream into an image automatically, either you need to do that when you create the object or perhaps you can do it with a value converter .

Appointments

Working with appointments follows the same pattern. It all starts with the Appointments class (like the Contacts class started with Contacts):

var appointmentCtx = new Appointments();

appointmentCtx.SearchCompleted += (s,a) =>
{
  IEnumerable<Appointment> appts = a.Results;

  // Bind to the UI
  apptList.ItemsSource = appts;
};

appointmentCtx.SearchAsync(DateTime.MinValue,
                           DateTime.Today,
                           null);

After creating the Appointments class, you can handle the SearchCompleted event and call the SearchAsync method to perform a search. The SearchAsync method enables you to specify a date range for the search (the last parameter is an optional piece of state to send to the completed event). The data returned by the search is an enumerable list of Appointment objects.

Unlike the Contacts class, the Appointments class supports binding because the nature of the data is fairly simple. For example, by using data binding, a ListBox to show appointments could look as simple as this:

<ListBox x:Name="apptList">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel Width="470">
        <TextBlock Text="{Binding StartTime, StringFormat=d}" />
        <TextBlock Text="{Binding IsPrivate}" />
        <TextBlock Text="{Binding Location}" />
        <TextBlock Text="{Binding Subject}" />
        <TextBlock Text="{Binding Status}" />
      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

The SearchAsync method also enables you to specify an account to search as well as the maximum number of results. So, you can select an account and then search like so:

var outlookAccount = appointmentCtx.Accounts
                        .Where(a => a.Kind == StorageKind.Outlook)
                        .FirstOrDefault();

appointmentCtx.SearchAsync(DateTime.MinValue, // Start
                           DateTime.Today,    // End
                           25,                // Max Results
                           outlookAccount,    // Account
                           null);

By using these APIs, you can access the contacts and appointments for the phone’s user.

 
Others
 
- Active Directory 2008 : Supporting User Objects and Accounts (part 3) - Administering User Accounts
- Active Directory 2008 : Supporting User Objects and Accounts (part 2) - Managing User Attributes with DSMod and DSGet, Understanding Name and Account Attributes
- Active Directory 2008 : Supporting User Objects and Accounts (part 1) - Managing User Attributes with Active Directory Users And Computers
- Exchange Server 2010 Administration Essentials : Using and Managing Exchange Server Services
- Exchange Server 2010 Administration Essentials : Understanding Data Storage in Exchange Server 2010
- Windows 8 Tile-Based Apps : Calendar
- Windows 8 Tile-Based Apps : Cloud Service Connections
- Windows 8 Tile-Based Apps : People
- Introduction to Sharepoint 2013 : SHAREPOINT CENTRAL ADMINISTRATION
- Introduction to Sharepoint 2013 : THE PLATFORM
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
Technology FAQ
- Is possible to just to use a wireless router to extend wireless access to wireless access points?
- Ruby - Insert Struct to MySql
- how to find my Symantec pcAnywhere serial number
- About direct X / Open GL issue
- How to determine eclipse version?
- What SAN cert Exchange 2010 for UM, OA?
- How do I populate a SQL Express table from Excel file?
- code for express check out with Paypal.
- Problem with Templated User Control
- ShellExecute SW_HIDE
programming4us programming4us