Friday, 4 January 2013

Windows 8 : Contact Picker

Suppose you want to create an application which uses mailing , messaging , appointments and social networking.  And you want to access existing contacts rather than adding your own contact, in this case Windows 8 provides you with the Contact Picker API.

Using Contact Picker API you can:
  • Add a contact
  • Pick a contact
  • Pick multiple contacts

Basically the Contact Picker API and ContactPicker class enables apps that to select and acquire info about contacts.

Namespace used is: Windows.ApplicationModel.Contacts

Following are the various classes in this namespace:

Contact
Creates a new contact.
ContactField
Shows a piece of contact data.
ContactFieldFactory
Creates fields that contain information about a contact.
ContactInformation
Contains the information about a contact.
ContactInstantMessageField
Defines a field that is an instant messaging (IM) address.
ContactLocationField
Contains information about a user's location and address.
ContactPicker
Controls how the Contact Picker user interface opens and what information it shows.
KnownContactField
A static class that contains the names of contact fields for storing commonly requested information like email address and phone numbers.

 

In the following example we will use:
  • ContactPicker class
  • ContactInformation class

In this demo I am trying to:
  • Open all the contact information available with me.
  • Select single information.
  • Display the data fetched from the contact information.

The namespaces I added for this sample are:
  • using Windows.ApplicationModel.Contacts;
  • using System.Text;
  • using Windows.Storage.Streams;
  • using Windows.UI.Xaml.Media.Imaging;

In the xaml file , I have six text blocks and one button called ‘pick single contact’

 

When the button is clicked , user is prompted with a screen which lists all the contacts that I have on my Windows 8 device.
I can select a single contact and on clicking the OK button the screen details the contact details of the contact selected in the previous screen.
For the above contact there is no address added, so the address field is empty. If the address fields are present in the contact information the address is also shown.

Now, let us look the xaml code.

<Page
    x:Class="ContactPicker.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ContactPicker"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
 
    <Grid Background="#FFF73131">
        <Image x:Name="OutputThumbnail" Grid.Column="0" Stretch="None" VerticalAlignment="Top" HorizontalAlignment="Left"/>
        <Button Content="Pick Single Contact " HorizontalAlignment="Left" Margin="581,145,0,0" VerticalAlignment="Top" Width="299" Name="PickContact" Click="PickContact_Click" Height="105" FontFamily="Segoe UI Light" FontSize="24" IsDoubleTapEnabled="False">
              <Button.Projection>
                     <PlaneProjection RotationX="-4" RotationY="-6"/>
              </Button.Projection>
        </Button>
        <TextBlock HorizontalAlignment="Left" Margin="704,270,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Height="56" Width="391" Visibility="Collapsed" Name="contactName" RenderTransformOrigin="0.502,5.966" FontFamily="Segoe UI Light" FontSize="32"/>
        <TextBlock HorizontalAlignment="Left" Margin="411.73,271.356,0,0" TextWrapping="Wrap" Text="Contact Name" VerticalAlignment="Top" Height="60.337" Width="247.325" Visibility="Visible" x:Name="contactNameLabel" RenderTransformOrigin="0.502,5.966" FontFamily="Segoe UI Light" FontSize="32" UseLayoutRounding="False" d:LayoutRounding="Auto">
            <TextBlock.RenderTransform>
                <CompositeTransform Rotation="0.166"/>
            </TextBlock.RenderTransform>
        </TextBlock>
        <TextBlock HorizontalAlignment="Left" Margin="413.223,351.953,0,0" TextWrapping="Wrap" Text="Email" VerticalAlignment="Top" Height="60.337" Width="247.325" Visibility="Visible" x:Name="Email" RenderTransformOrigin="0.502,5.966" FontFamily="Segoe UI Light" FontSize="32" UseLayoutRounding="False" d:LayoutRounding="Auto">
            <TextBlock.RenderTransform>
                <CompositeTransform Rotation="0.166"/>
            </TextBlock.RenderTransform>
        </TextBlock>
        <TextBlock HorizontalAlignment="Left" Margin="698,348,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Height="117" Width="582" Visibility="Visible" x:Name="EmailValue" RenderTransformOrigin="0.502,5.966" FontFamily="Segoe UI Light" FontSize="32"/>
        <TextBlock HorizontalAlignment="Left" Margin="413.223,516.132,0,0" TextWrapping="Wrap" Text="Address" VerticalAlignment="Top" Height="60.337" Width="247.325" Visibility="Visible" x:Name="Address" RenderTransformOrigin="0.502,5.966" FontFamily="Segoe UI Light" FontSize="32" UseLayoutRounding="False" d:LayoutRounding="Auto">
            <TextBlock.RenderTransform>
                <CompositeTransform Rotation="0.166"/>
            </TextBlock.RenderTransform>
        </TextBlock>
        <TextBlock HorizontalAlignment="Left" Margin="682,464,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Height="241" Width="589" Visibility="Visible" x:Name="AddressValue" RenderTransformOrigin="0.502,5.966" FontFamily="Segoe UI Light" FontSize="32"/>
 
 
    </Grid>
</Page>

 

The xaml code is nothing but a very simple xaml page.

Now , Let us do the button click event:

1.       Create an object of the Contact class

var contactPicker = new Windows.ApplicationModel.Contacts.ContactPicker();

2.       Now , we need to fetch the contact information using the ContactInformation class:

ContactInformation contact = await contactPicker.PickSingleContactAsync();

 

PickSingleContactAsync(); is the method which internally collates all the contact information from my OS and presents to me on the UI.

 

When implementing PickSingleContactAsync();This method has no parameters. Using this method I can select only one contact at a time.

 

Once , I have selected a contact , the contact information is now available , we need to fetch the information and show them in appropriate format.

 

                contactName.Visibility = Visibility.Visible;

                AddressValue.Text = string.Empty;

                contactName.Text = contact.Name;

                EmailValue.Visibility = Visibility.Visible;

                EmailValue.Text = contact.Emails[0].Value.ToString();

                if (contact.Locations.Count > 0)

                {

                    string street = contact.Locations[0].Street.ToString();

                    string city = contact.Locations[0].City.ToString();

                    string category = contact.Locations[0].Category.ToString();

                    string region = contact.Locations[0].Region.ToString();

                    string country = contact.Locations[0].Country.ToString();

 

                    string postalCode = contact.Locations[0].PostalCode.ToString();

                    string address = street + city + region + country + postalCode;

                    AddressValue.Visibility = Visibility.Visible;

                    AddressValue.Text = address;

           }

 

Although , I can get the all the contact information using this, I cannot get the thumbnail information using contact class.

So,  Let us try to fetch the thumbnail information.

To fetch the thumbnail information ,

 IRandomAccessStreamWithContentType stream = await contact.GetThumbnailAsync();

 

And once , you have fetched the image stream use following:

               if (stream != null && stream.Size > 0)

                {

                    BitmapImage bitmap = new BitmapImage();

                    bitmap.SetSource(stream);

                    OutputThumbnail.Source = bitmap;

                }

                else

                {

                    OutputThumbnail.Source = null;

         }

 

So,  the .cs file now looks like:

 

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using Windows.Foundation;

using Windows.Foundation.Collections;

using Windows.UI.Xaml;

using Windows.UI.Xaml.Controls;

using Windows.UI.Xaml.Controls.Primitives;

using Windows.UI.Xaml.Data;

using Windows.UI.Xaml.Input;

using Windows.UI.Xaml.Media;

using Windows.UI.Xaml.Navigation;

using Windows.ApplicationModel.Contacts;

using System.Text;

using Windows.Storage.Streams;

using Windows.UI.Xaml.Media.Imaging;

 

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

 

namespace ContactPicker

{

    /// <summary>

    /// An empty page that can be used on its own or navigated to within a Frame.

    /// </summary>

    public sealed partial class MainPage : Page

    {

        public MainPage()

        {

            this.InitializeComponent();

        }

 

        /// <summary>

        /// Invoked when this page is about to be displayed in a Frame.

        /// </summary>

        /// <param name="e">Event data that describes how this page was reached.  The Parameter

        /// property is typically used to configure the page.</param>

        protected override void OnNavigatedTo(NavigationEventArgs e)

        {

        }

 

     

        private async void PickContact_Click(object sender, RoutedEventArgs e)

        {

            var contactPicker = new Windows.ApplicationModel.Contacts.ContactPicker();

            ContactInformation contact = await contactPicker.PickSingleContactAsync();

            if (contact != null)

            {

                contactName.Visibility = Visibility.Visible;

                AddressValue.Text = string.Empty;

                contactName.Text = contact.Name;

                EmailValue.Visibility = Visibility.Visible;

                EmailValue.Text = contact.Emails[0].Value.ToString();

                if (contact.Locations.Count > 0)

                {

                    string street = contact.Locations[0].Street.ToString();

                    string city = contact.Locations[0].City.ToString();

                    string category = contact.Locations[0].Category.ToString();

                    string region = contact.Locations[0].Region.ToString();

                    string country = contact.Locations[0].Country.ToString();

 

                    string postalCode = contact.Locations[0].PostalCode.ToString();

                    string address = street + city + region + country + postalCode;

                    AddressValue.Visibility = Visibility.Visible;

                    AddressValue.Text = address;

                }

 

                IRandomAccessStreamWithContentType stream = await contact.GetThumbnailAsync();

                if (stream != null && stream.Size > 0)

                {

                    BitmapImage bitmap = new BitmapImage();

                    bitmap.SetSource(stream);

                    OutputThumbnail.Source = bitmap;

                }

                else

                {

                    OutputThumbnail.Source = null;

                }

 

            }

       }

           

    }

 

  

  

}

No comments:

Post a Comment