Chapter 10. Integrating Applications with the Windows Phone OS

When a third-party application runs on a Windows Phone, it runs in an execution environment that is highly restricted. The Windows Phone OS must be restrictive in order to protect unsuspecting users of mobile devices from potential malicious application behavior, which may include stealing personal data stored on the phone, dialing phone numbers without users' knowledge, or corrupting other applications' data stores. One of the major restrictions that Windows Phone OS places on mobile applications is limiting them to their own execution environment, or sandbox, and not allowing them access to other applications' space or the internals of the operating system. Sandboxing and other Windows Phone security features are covered in great detail in Chapter 19.

Yet many applications need to access the system features of the phone to play a music file in the media library, for example, or to take a photo, or to send a text message. Windows Phone 7 OS enables such application interactions with the device via a set of Application Programming Interface (API) tasks referred to as launchers and choosers. Some launchers and choosers may be invoked via hardware buttons on the phone, such as using a camera button to take photos. It is also relatively easy to use launchers and choosers from within your application, but when one is invoked or when a user presses hardware buttons on the phone while your application is running, managing your application state does get a little tricky.

This chapter covers the launchers and choosers available on the Windows Phone 7 platform, as well as various states an application can enter when you invoke them. You will also learn about integrating your applications with popular external services such as Facebook. Finally, you'll take a quick look at Windows Phone 7 hubs, which bring many applications found on desktop devices and in the cloud to the palm of your hand.

Introducing Windows Phone 7 Launchers and Choosers

When an application executes, the Windows Phone 7 OS confines it to its own space, or sandbox. Both memory and file storage are isolated within that sandbox—one application can't access or alter another's memory or file storage. Neither can one application directly call another or access a shared data store, such as a list of contacts, for example. There are obvious reasons for this behavior; Microsoft must ensure that the Windows Phone 7 platform is as secure and stable as possible, and isolating applications is one giant step toward getting there.

There is a set of built-in APIs that provides access to the most common features of Windows Phone 7. These APIs help you perform tasks, such as saving a contact's e-mail address or phone number or placing a phone call (with the mandatory prior user authorization, of course), that require access to shared resources on the phone.

Launchers and choosers, which can be thought of as system functions provided by the Windows Phone OS, provide you with the means to call into these applications. The difference between a launcher and a chooser is small but important: choosers provide a return value into the calling application, whereas launchers do not. If you think about a task of composing an e-mail message, for example, then it is sufficient to "fire and forget" an e-mail application, allowing users to create and send an e-mail. A launcher is an ideal solution for this task. On the other hand, an application allowing you to select a photo from the photo library on the phone needs to pass the selected photo to your application. Windows Phone 7 provides a chooser to perform such a task.

An important concept to remember is that launchers and choosers are separate applications. Since one of the core design principles behind Windows Phone 7 is to maximize battery life, only one application is allowed to execute on the phone at any time. Therefore, if you invoke a launcher or chooser from within your application, that launcher or chooser will replace your application and become the running application. Depending on the circumstances, your application may enter one of several states when that happens. We will cover these possible states when we cover the application life cycle in depth later in this chapter, but in the meantime, Tables 10-1 and 10-2 list the launchers and choosers available on the Windows Phone 7 platform today. You'll find all of them in the Microsoft.Phone.Tasks namespace; therefore, to use any of them, be sure to import that namespace into your application via the following standard directive at the very top of the code page:

using Microsoft.Phone.Tasks;

Launchers

Table 10-1 lists the launchers offered on the Windows Phone 7 platform with a brief description of functionality offered by each.

Table 10.1. Windows Phone 7 Launchers and Their Functions

Launcher

Function

EmailComposeTask

Launch the e-mail application with a new message displayed.

MarketplaceDetailTask

Launch the Windows Phone Marketplace client application and display the details page for the specified product.

MarketplaceHubTask

Launch the Windows Phone Marketplace client application.

MarketplaceReviewTask

Launch the Windows Phone Marketplace client application and display the review page for the specified product.

MarketplaceSearchTask

Launch the Windows Phone Marketplace client application and display the search results from the specified search terms.

MediaPlayerLauncher

Launch the media player.

PhoneCallTask

Launch the Phone application; use this to allow users to make a phone call from your application.

SaveEmailAddressTask

Launch the Contacts application; use this to allow users to save an e-mail address from your application to a new or existing contact.

SavePhoneNumberTask

Launch the Contacts application; use this to allow users to save a phone number from your application to a new or existing contact.

SearchTask

Launch the Web Search application.

SmsComposeTask

Launch the SMS application.

WebBrowserTask

Launch the Web Browser application.

Choosers

Table 10-2 lists and describes the choosers available on the Windows Phone 7 platform.

Table 10.2. Windows Phone Choosers and Their Functions

Chooser

Function

EmailAddressChooserTask

Launch the Contacts application and obtain the e-mail address of a contact selected by the user.

CameraCaptureTask

Launch the Camera application and allow users to take a photo from your application (for more information and in-depth examples, please refer to Chapter 16).

PhoneNumberChooserTask

Launch the Contacts application and obtain the phone number of a contact selected by the user.

PhotoChooserTask

Launch the Photo Chooser application and select a photo (refer to Chapter 16 for more information and a detailed demo using this Chooser).

Working with Launchers and Choosers

In this section, you will explore how to work with launchers and choosers from within your application. You will use PhoneNumberChooserTask and SmsComposeTask to create an application that selects a contact from the shared list of contacts on the phone and then composes a text message to that contact's phone number.

Creating the User Interface

The user interface for this sample consists of a single button; when the user clicks this button, a list of contacts will be displayed, allowing the user to pick one.

  1. Launch Visual Studio 2010 Express, and select the Windows Phone Application template. Change the project name to Tasks, select OK, and Visual Studio will set up a new project.

  2. Open MainPage.xaml in design mode, and add a button to the page. Change the button's caption to "Send SMS."

Coding Application Logic

When the user clicks the Send SMS button of your application, she should be presented with a list of contacts available on your device. Conveniently for you, even on the emulator, Microsoft has included a sample list of contacts for you to test an application with.

  1. Open MainPage.xaml.cs (right-click MainPage.xaml and select View Code). At the top of the page, add the following using statement:

    using Microsoft.Phone.Tasks;
  2. Declare the following module-level variable for the PhoneNumberChooserTask chooser (insert it right above the MainPage() constructor):

    private PhoneNumberChooserTask _choosePhoneNumberTask;
  3. Instantiate a new PhoneNumberChooserTask object within the MainPage() constructor, and associate a method to invoke when the user selects a contact from the list. The method to call upon the chooser's return will accept the phone number selected as one of the parameters. Use the following two lines of code to accomplish that:

    _choosePhoneNumberTask = new PhoneNumberChooserTask();
    _choosePhoneNumberTask.Completed += new
         EventHandler<PhoneNumberResult>(ChoosePhoneNumberTaskCompleted);
  4. Code the ChoosePhoneNumberTaskCompleted method that will be invoked upon selection of a contact from the list. Note the use of an SmsComposeTask launcher to create a new text message to the person you have selected from the contact list.

    private void ChoosePhoneNumberTaskCompleted(object sender,
    PhoneNumberResult e)
    {
                           new SmsComposeTask() { Body = "SMS using Windows Phone 7 Chooser", To
    =
                           e.PhoneNumber }.Show();
                       }
  5. Finally, add code to react to the button-click event by opening the PhoneNumberChooser launcher. The easiest way to accomplish this is to double-click the button with MainPage.xaml open in design view and make the button-click event look like the following:

    private void button1_Click(object sender, RoutedEventArgs e)
    {
         _choosePhoneNumberTask.Show();
    }
  6. Press F5 to run your application. Click the Send SMS button, and select Andrew R. (Andy) Hill from the list of contacts that comes up on the emulator. Immediately after selecting Andy, you should see a screen similar to Figure 10-1, where the SMS message has been composed and is ready to be sent to Andrew.

To summarize what you have learned so far, your application integrates with the Windows Phone OS via a set of API methods referred to as launchers and choosers. Working with launchers and choosers is fairly straightforward, as illustrated by the previous example. If that was all there was to application integration, it would have made for a very brief chapter. But there's more.

One major limitation of mobile platforms is their inherently short battery life. This limitation causes OS designers and phone manufacturers to come up with various techniques to balance short battery life with positive user experience. One such technique is to allow only one application to run on the phone at any given time. You may be wondering then, what happens when your application yields execution to the built-in Windows Phone OS application invoked with the launcher? That brings us to the important Windows Phone concept of application tombstoning, a subject you'll explore along with the Windows Phone application life cycle in the next section.

SMS is composed and ready to go to Andrew.

Figure 10.1. SMS is composed and ready to go to Andrew.

Working with the Windows Phone 7 Application Life Cycle

To program responsive applications on a Windows Phone 7 device, you must be familiar with the concept of tombstoning on that platform. The simplest way to explain tombstoning is to describe it as an event that happens when your application loses focus on the Windows Phone 7 device, such as when a user invokes a launcher or a chooser, or presses the hardware Start button. When your application loses focus, the Windows Phone OS realizes that there is a good chance that the user will want to come back to or reactivate your application shortly, and he or she will expect to find it in its previous state. Therefore, instead of simply terminating your application as soon as it loses focus, the Windows Phone OS remembers its state and provides developers with a means to save session-related information to a custom State dictionary object. However, with tombstoning, there is always a chance that your application may never be reactivated. So, if there is data that needs to be permanently preserved within your application, you should save it to the isolated storage instead of the transient State object.

You will get to observe tombstoning at work shortly, but before that, you need to examine a typical life cycle of a Windows Phone 7 application. Table 10-3 summarizes the application events that can occur during the execution of a typical Windows Phone 7 application. The table also describes the actions you as a developer should take when each of those events occurs.

Table 10.3. Applications Events, Triggers, and Actions

Application Event

Occurs When

Your Actions

Application_Launching

The user taps the entry for an application on the installed applications screen, and a new instance of an application is created.

Do not read application settings from the isolated storage as this will slow down the loading process; do not attempt to restore transient state. When an application launches, it should always appear as a new instance.

Application_Activated

For this event to occur, two conditions must be met: (1) the user navigates away from your application, either by using a launcher or a chooser, or by starting another application and (2) the user then comes back to your application by either completing the launcher or chooser or using the hardware Back button. This event is not raised when an application is first launched.

The application should allow the user to continue interaction as if she had never left the application; transient state information should be restored, but the application should not attempt to read the contents of the isolated storage to avoid potential slowdown.

Application_Deactivated

The user navigates away from your application either by invoking a launcher or a chooser, or by launching another application. This event is not raised when your application is closing.

You should save all transient (i.e., related to the current application session) state into the State dictionary. You should save persistent state to an isolated storage. Applications are given ten seconds to complete this event; after ten seconds, if this event is still not completed, an application will be terminated and not tombstoned.

Application_Closing

The user uses the Back key to navigate past the first page of your application.

Save all of the persistent state into the isolated storage.

In the next section, you will code and observe the conditions under which each of the events in the application life cycle is triggered.

Observing Application Life Cycle Events

To help you better understand the conditions under which tombstoning occurs and the events that are fired, let's enhance the application built previously in this chapter to trace the events raised within the application.

Enhancing the User Interface

You will enhance the application user interface by adding a text box and a button control to the design surface of MainPage.xaml to make it look similar to Figure 10-2.

  1. Launch Visual Studio 2010 Express, and open the previously created Tasks project.

  2. Double-click MainPage.xaml in Solution Explorer, and add a text box and a button to the design surface, as shown in Figure 10-2. Clear the Text property of the text box, and set the button's caption to "Launch Browser."

Adding Application Logic to Invoke WebBrowserTask Launcher and Log Events

Now, you will add logic to invoke a WebBrowserTask launcher and navigate to www.windowsphone.com, as well as add messages to print in the Debug window when various application life cycle events occur.

  1. Add the following using directive to the top of MainPage.xaml:

    using System.Diagnostics;
  2. You will launch the web browser when the user clicks the Launch Browser button. Double-click the Launch Browser button on MainPage.xaml, and make that button's Click event handler look like the following:

    private void button2_Click(object sender, RoutedEventArgs e)
    {
            WebBrowserTask webTask = new WebBrowserTask();
            webTask.Show();
            webTask.URL = "http://www.windowsphone.com";
    }
  3. The application life cycle events discussed in the previous section are all automatically stubbed out (in other words, they contain basic method signatures without any implementation logic) in the App.xaml.cs file. Open that file (one way to do it is to right-click App.xaml and select View Code) so that you can modify those events by adding tracing logic to them.

  4. Within the Application_Launching event, add the following line of code:

    Debug.WriteLine("Application Launching");
  5. Within the Application_Activated event, add the following line of code:

    Debug.WriteLine("Application Activated");
  6. Within the Application_Deactivated event, add the following line of code:

    Debug.WriteLine("Application Deactivated");
  7. Within the Application_Closing event, add the following line of code:

    Debug.WriteLine("Application Closing");
User interface for application lifecycle test application

Figure 10.2. User interface for application lifecycle test application

Running the Application

Before running the application, make sure to bring the Visual Studio Output window to the forefront—in Visual Studio, select Debug

Running the Application
  1. When the application first comes up, observe how an Application Launching message is printed in the Output window, indicating that the Application_Launching event has fired, but the Application_Activated event has not fired upon the initial launch of an application.

  2. Click the Launch Browser button to bring up Internet Explorer with the Windows Phone web site open. In the Visual Studio Output window, notice how the Application_Deactivated event fired as soon as the web browser was launched (see Figure 10-3), indicating possible tombstoning of your application.

  3. Click the Back button on the emulator screen. Notice how the Application_Activated event fires and prints a message in the Output window.

  4. Click the Start button, and observe how Application_Deactivated is fired again. If you click the Back button now, the Application_Activated event is triggered.

  5. Finally, click the Back button again. Since you have navigated past the first page of the application, the application is terminated, triggering the Application_Closing event and printing the corresponding message in the Output window.

To summarize the previous experiments, any time your application lost focus, an Application_Deactivated event was triggered. Any time an application gained focus (except for the initial launch), an Application_Activated event was triggered. These concepts are important to keep in mind as we discuss saving and retrieving state information in Windows Phone 7 applications in the next section.

Application life cycle illustrated by switching between applications on the phone.

Figure 10.3. Application life cycle illustrated by switching between applications on the phone.

Table 10-4 summarizes the actions you took and the corresponding events raised within your application. You can cross-reference Tables 10-4 and 10-3 for actions to take in order to persist state when a given event is raised within your application.

Table 10.4. Summary of Your Actions and Resulting Application Events

Your Action

Application Event

Pressed F5 to start the application

Application_Launching

Pressed Launch Browser button to launch IE on the phone

Application_Deactivated

Clicked the Back button to go back to your application

Application_Activated

Clicked the Start button

Application_Deactivated

Clicked the Back button to return to your application

Application_Activated

Clicked the Back button to go past the first page of your application

Application_Closing

Managing Application State

Try the following experiment: open the Tasks project if it's not already open within Visual Studio 2010 Express for Windows Phone, and press F5 to run it. In the text box field that comes up, type "Hello, world" (you can press the Page Up key to allow you to type from the keyboard in the emulator). Next, click the Launch Browser button, and then press the Back button to return to your application.

Notice how the text box is blank (the "Hello, world" text is gone) once you come back to the main application screen. Now imagine if your application were a real-world application capturing many different pieces of data and it provided a WebBrowserTask to allow quick lookup of data on the Internet. It would certainly not be acceptable to the end user to have to retype all the information once the WebBrowserTask completes. Hence, you must devise a mechanism to preserve such data when the application is being tombstoned. Enter state management.

If you have done any sort of web development, the concept of state management will already be very familiar to you. And if you haven't been exposed to state management before, it's a fairly easy concept to grasp. Per Microsoft's documentation, when an application like the Tasks application of the previous example is tombstoned, it should save state information in case it is reactivated. The sections that follow will show you how to save and retrieve state information within your application.

Managing State at the PhoneApplicationPage Level

The concept of state management at the page level applies not only to those times when an application is about to be tombstoned and the page needs to persist its state for possible future retrieval. Many times, individual pages within a Windows Phone 7 application must save their session data to allow navigation to other pages within that same application; if the user comes back to the original page, the application should be smart enough to retrieve data previously entered by the user.

To accomplish session persistence for both tombstoning and page navigation scenarios, each page relies on the following three methods within the PhoneApplicationPage class:

  • OnNavigatedFrom(), which is called when the page is no longer an active page in a frame.

  • OnNavigatedTo(), which is called when the page becomes the active page in a frame.

  • OnBackKeyPress(), which is called when the hardware Back key is pressed.

In the following code demo, you will use each one of these methods, as well as the State dictionary object, to persist data from the text box in the Tasks application that you have built in this chapter. Follow these steps to accomplish this task.

You will not be making any changes to the user interface of the Tasks application—it will stay very basic, just as it is shown in Figure 10-2. You will, however, add code to the Tasks application to persist the information that has been entered inside the single text box in that application.

  1. Launch Visual Studio 2010 Express, and open the previously created Tasks project, if it's not already open.

  2. Open MainPage.xaml.cs (one way is to right-click MainPage.xaml and select View Code). You will add code to save text entered in the text box on MainPage.xaml into the session objects if the page becomes no longer active in a frame—i.e., in that page's OnNavigatedFrom method. Add the following code to the MainPage.xaml.cs file:

    protected override void
    OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
                    {
                            Debug.WriteLine("Navigated From MainPage");
    
                            if (State.ContainsKey("TextboxText"))
                    {
                                    State.Remove("TextboxText");
                    }
                            State.Add("TextboxText", textBox1.Text);
                            base.OnNavigatedFrom(e);
                    }

    Notice the use of the State dictionary object—it is indeed very similar to the Session variable of ASP.NET web-based applications, and in the previous method you add the value from the text box into the State dictionary object.

  3. Next, you will add code to retrieve values from the State dictionary object when the user navigates to the current page; you will do that inside the OnNavigatedTo method:

    protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs
    e)
            {
                    Debug.WriteLine("Navigated To MainPage");
    
                    if (State.ContainsKey("TextboxText"))
                    {
                            string strTextboxText = State["TextboxText"] as string;
    
                            if (null != strTextboxText)
                                    textBox1.Text = strTextboxText;
                    }
    
                    base.OnNavigatedTo(e);
            }

The code you have written thus far is sufficient to save the text from the text box for the duration of the application session; even if an application is tombstoned, and the user later returns to the current page, the text will be properly preserved. Let's test this out really quickly: press F5 to run this application, enter "Hello, world" in the text box, and press the Launch Browser button. Once the browser comes up, press the Back button—you should see "Hello, world" still displayed in the text box, unlike the behavior you saw previously in this chapter, where you did not handle any state information at all.

While saving information for the duration of the session is extremely important, there are many occasions when you would like to save information permanently, so that even if you turn your phone off (or the battery dies), you will still have access to that information. Let's expand the demo to accommodate saving text into the isolated storage on the Windows Phone 7, so that text is available for use as long as the application's isolated storage is intact (and as long as you don't remove this information from the isolated storage, of course). Follow these steps to accomplish this task.

  1. Add the following two using directives to the top of the MainPage.xaml.cs file:

    using System.IO.IsolatedStorage;
    using System.IO;
  2. You will add code to save text into the isolated storage area of your application if the user presses the Back button past your application's first page (for example, the user presses the Back button as soon as the application launches). If you would like to get more familiar with isolated storage, see Chapter 13. Add the following method to the MainPage.xaml.cs file:

    protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs
    e)
                  {
                          base.OnBackKeyPress(e);
                          MessageBoxResult res = MessageBox.Show("Do you want to save your work
    before
                          leaving?", "You are exiting the application",
                  MessageBoxButton.OKCancel);
    
                          if (res == MessageBoxResult.OK)
                          {
                                  Debug.WriteLine("Ok");
                                  SaveString(textBox1.Text, "TextboxText.dat");
                          }
                          else
                          {
                                  Debug.WriteLine("Cancel");
                          }
                  }

    Notice how the message box is used to ask the user whether to save information to the file inside isolated storage; if the user chooses Yes, the SaveString method is called, passing the value to save and the file to save it to.

  3. Finally, you need to code the SaveString method that performs all the heavy lifting saving data to the isolated storage. This method accepts the name of the file as one of the parameters, and then it creates a file with that name within the isolated storage. After the file is created, the method saves the data string passed to it inside that file. While persisting string values inside the file is perfectly acceptable for the small application that you are building in this demo, you might consider a different data structure for bigger production applications with lots of data to persist. Serializing data to XML would be a better alternative for such applications, as would be saving data inside a dictionary or key-value collection objects. Here is the full listing of the method to persist data to an isolated storage; make sure it is also present in your code.

private void SaveString(string strTextToSave, string fileName)
                {
                        using (IsolatedStorageFile isf =
IsolatedStorageFile.GetUserStoreForApplication())
                        {
                                //If user choose to save, create a new file
                                using (IsolatedStorageFileStream fs =
isf.CreateFile(fileName))
                                {
                                        using (StreamWriter write = new StreamWriter(fs))
                                        {
                                                        write.WriteLine(strTextToSave);
                                        }
                                }
                        }
               }

You are now ready to run your application. Press F5 to launch it, type "Hello, world" in the text box shown, and press the Back button. Remember, pressing the Back button past the first page of an application results in termination of that application. Click Yes on the message box prompting you to save your work before leaving. Next, re-launch your application. You should see "Hello, world" displayed in the text box—but you don't. What happened? If you guessed that you still have to retrieve the values previously stored inside the isolated storage, you are correct. You will retrieve those values in the next section, together with looking at the best practices for retrieving this information.

Retrieving Application Initial State

Microsoft guidelines state that within the Application_Launching event there should not be any isolated storage access or web service calls, so that the application comes up and is available for use as quickly as possible. Instead, Microsoft recommends asynchronously loading values from the isolated storage of an application once the application is fully loaded. This set of restrictions forces us as developers to code the initialization routines using the following two guidelines:

  1. Invoke data initialization and retrieval on a separate thread so as to maximize the responsiveness of an application.

  2. Perform application initialization inside the OnNavigatedTo method of the PhoneApplicationPage class.

  3. In this demo, you will add the necessary methods to properly load application data from the isolated storage.

  4. You will continue modifying the Tasks project that you have worked with throughout this chapter. At the top of MainPage.xaml.cs, add the following using directive:

    using System.Threading;
  5. Open MainPage.xaml.cs and go to the OnNavigatedTo method within that code. You will make adjustments to that method to load data asynchronously (on a separate thread) from the isolated storage, if there is no data in the State dictionary. If you recall, the State dictionary object is used to hold transient application data, or data that is being saved and retrieved as the user navigates between pages in the application. Therefore, you check the State object to determine whether transient or permanently persisted data should be retrieved. Make the OnNavigatedTo method look like the following:

    protected override void
    OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
                       {
                            Debug.WriteLine("Navigated To MainPage");
    
                            if (State.ContainsKey("TextboxText"))
                            {
                                    string strTextboxText = State["TextboxText"] as string;
    
                                    if (null != strTextboxText)
                                    textBox1.Text = strTextboxText;
                            }
                            else
                            {
                                    LoadAppStateDataAsync();
                            }
    
                            base.OnNavigatedTo(e);
                       }
  6. The LoadAppStateDataAsync method is responsible for invoking a method that accesses isolated storage data on a separate thread. The full method is shown here:

    public void LoadAppStateDataAsync
    {
         Thread t = new Thread(new ThreadStart(LoadAppStateData));
         t.Start();
    }
  7. Finally, the LoadAppStateData method accesses isolated storage data looking for a particular file (hardcoded to be TextboxText.dat at the moment) and the settings within that file.

    public void LoadAppStateData()
                   {
    string strData = String.Empty;
    
                            //Try to load previously saved data from IsolatedStorage
                            using (IsolatedStorageFile isf =
    IsolatedStorageFile.GetUserStoreForApplication())
                            {
                                    //Check if file exits
                                    if (isf.FileExists("TextboxText.dat"))
                                    {
                                            using (IsolatedStorageFileStream fs =
    isf.OpenFile("TextboxText.dat",
                                            System.IO.FileMode.Open))
                                            {
                                                            using (StreamReader reader = new
    StreamReader(fs))
                                                            {
                                                                    strData = reader.ReadToEnd();
                                                            }
                                            }
                                    }
                            }
                            Dispatcher.BeginInvoke(() => { textBox1.Text = strData; });
                      }
  8. Your application is now complete, and it should handle both transient and persistent states. To test it, press F5 and enter "Hello, world" in the text box presented. Next, press the Back button and answer Yes to save work before leaving. The application is now terminated; if you press F5 again to re-launch the application, the screen should come with "Hello, world" already populated within it.

Best Practices for Managing the Application Life Cycle on the Windows Phone 7 OS

Microsoft provides an important set of application behavior guidelines to follow to ensure a consistent and positive user experience on a Windows Phone 7 platform. Some of the highlights of those best practices are as follows:

  1. Ensuring that when the user launches a new instance of an application, it is clear that it's a new instance (in other words, the last example of automatically retrieving settings from the isolated storage upon application launch may not be ideal). At the same time, if an application is being reactivated, the user should feel that the reactivated application has returned in its previous state.

  2. Since the user may never return to the application once it becomes tombstoned, any data that needs to be saved to a persistent data store should be saved when either the Closing or Deactivated event fires.

  3. Invoking a launcher or a chooser will always deactivate an application and may cause it to become tombstoned. An application may not be tombstoned if it launches an experience that feels like it's a part of the original application. Microsoft currently lists the following launchers and choosers as not automatically tombstoning the calling application (it clarifies, however, that an OS may still choose to tombstone the calling application if the resources are needed elsewhere):

    • PhotoChooserTask

    • CameraCaptureTask

    • MediaPlayerLauncher

    • EmailAddressChooserTask

    • PhoneNumberChooserTask

    • MultiplayerGameInvite [games]

    • GamerYouCard [games]

You can take a look at the full list of best practices for managing the application life cycle (most of which have already been covered in this chapter) at http://msdn.microsoft.com/en-us/library/ff817009(v=VS.92).aspx.

Integrating with Facebook

Applications running on mobile devices, including Windows Phone 7 devices, are ideally suited to take advantage of social networks—these devices are always on and are always with their respective owners, allowing for constant interaction with peers and colleagues. Today, integration of mobile devices into social networks is virtually assumed, so it makes a lot of sense for your application to take advantage of as many social networking features as are applicable. In the next section, you will walk through integrating with (currently) the biggest social network of them all—Facebook. These integration efforts will allow you to practice what you have learned about tombstoning and managing application state so far in this chapter, as well as explore new concepts of tapping vast marketing potential for your application through Facebook. More good news for application developers is that similar integration principles apply to other social networks as well—for example, LinkedIn uses the same protocol (OAuth, which you will learn about shortly) for authorizing applications on behalf of the users to retrieve and manipulate data.

A Few Words about OAuth

Facebook uses OAuth protocol for third-party application authentication and authorization. OAuth is the authorization protocol characterized by separating resource ownership and access to the resource by third parties (referred to as clients in the OAuth documentation). In the context of Windows Phone 7 development, the applications that you build that need to post to users' Facebook walls or retrieve resources from the users' social graphs are clients, and Facebook users (they are also users of your application) are the resource owners. Instead of blindly giving away their user name and password to your app, Facebook users will instead grant your application limited time and scope to perform authorized operations on their behalf. These operations may include posting on users' walls or querying users' information. The authorization to perform these operations will come in the form of an OAuth token obtained from Facebook.

Facebook provides an excellent set of step-by-step guidelines for integrating your applications into their vast ecosystem (you can access those at http://developers.facebook.com/docs/authentication/). These guidelines state that there are essentially three steps to proper Facebook authorization via OAuth: (1) user authentication, (2) application authorization and (3) application authentication. Let's take a look at how these three steps would happen on a Windows Phone 7 device.

In the next demo, you will enhance the Tasks application that you built so far with the ability to post simple messages to your application users' Facebook wall. In the first step (user authentication), you will need to launch a Web browser on the Windows Phone 7 device and direct it to www.facebook.com asking the user to authenticate (note that you cannot simply "post" user name and password to Facebook web page from within a XAML page in your application—that would break the trust chain that OAuth was designed to protect, since your application can easily capture the user name and password values). Once the user is successfully authenticated, she will be presented with a dialog listing all of the action your application intends to take on her behalf—that's the second step in the OAuth implementation. This second step is necessary for the user to make an informed decision about whether to grant your application the necessary rights. Finally, in the third step (application authentication), your application will supply a special unique secret key that identifies your app on Facebook to ensure that the user is giving her information to your app and not someone else's. Let's go ahead and code these three steps.

Note

Before your application is able to interact with Facebook, you must register it on Facebook and obtain the Application ID and a Secret Key. These values are unique to your application; do not share those values with anyone! To register your application, go to http://developers.facebook.com/setup and follow the step-by-step guidelines to get the necessary information pieces for your app.

Enhancing the User Interface for Facebook Integration

You will continue working with the Tasks application and add an additional option to post a message to Facebook on the main page of your application plus a separate page containing web browser control for navigating to facebook.com—you'll see why a separate page is needed shortly.

  1. Launch Visual Studio 2010 Express, and open the previously created Tasks project.

  2. Double-click MainPage.xaml in Solution Explorer, and add a button to the design surface, somewhere underneath the other two buttons. Set the name of the button to be btnFacebook and set the button's caption to "Post to Facebook."

  3. Right-click on the project name (Tasks) in the Solution Explorer and choose Add

    Enhancing the User Interface for Facebook Integration
  4. Double-click the newly added FBLogin.xaml page in Solution Explorer and add a web browser control to that page. Make the web browser control occupy the whole width and height of the page, since the user will be utilizing this control to log in to Facebook.

Adding Application Logic to Post to Facebook

Now, you will add logic to post to Facebook from your application. Remember the brief discussion about OAuth—posting to Facebook is a multi-step procedure, which includes (1) user authentication, (2) app authorization and (3) app authentication. Follow the steps below to successfully implement each of these steps.

  1. First things first—you need to add a couple of references to the project to make the code below work. Right-click on the project name in Solution Explorer and select Add Reference. Add a reference to Microsoft.Phone.Reactive and System.Observable assemblies.

  2. Add the following using directives to the top of the page:

    using Microsoft.Phone.Reactive;
    using System.IO;
    using System.Diagnostics;
    using System.Text;
  3. User authentication will happen inside the newly added FBLogin.xaml page—therefore your button click event handler should redirect the user to that page. Add the following code to the btnFacebook button click event (notice how you pass the MessageToPost parameter to the page):

    private void btnFacebook_Click(object sender, RoutedEventArgs e)
               {
                NavigationService.Navigate(new
                Uri(String.Format("/FBLogin.xaml?MessageToPost={0}", textBox1.Text),
                UriKind.Relative));
               }
  4. In the next step, you will define certain constants, such as permission types that an application needs, as well as a standard URL that Facebook gives to desktop and mobile developers to use upon successful authentication of an application (STR_FB_SuccessUrl constant below). Facebook developer documentation gives an in-depth overview of permission types available to your application; your sample application simply needs a permission to post to users' Facebook wall. Open FBLogin.xaml.cs page (right-click on FBLogin.xaml and select View Code) and add the following constant declarations to the top of the page (note that you must supply your application ID and your application secret key for the STR_FB_AppID and FB_AppSecret parameters correspondingly):

    const string STR_FB_Permissions = "publish_stream";
    const string STR_FB_SuccessUrl =
    "http://www.facebook.com/connect/login_success.html";
            const string STR_FB_Login =
            "https://graph.facebook.com/oauth/authorize?display=wap&client_id={0}&redirect
            _uri={1}&scope={2}";
            const string FB_GetAccessToken =
            "https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&
            client_secret={2}&code={3}";
    
            const string STR_Post = "POST";
            const string STR_Access_token = "access_token";
            const string STR_FB_AppId = "Your App ID";
            const string FB_AppSecret = "Your App Secret";
            const string STR_FormEncoded = "application/x-www-form-urlencoded";
  5. In this step, you will use Reactive Extensions for .NET (Rx.NET) to subscribe to Webbrowser's control Navigated event. Rx.NET is ideally suited for working with events, such as navigation to and from facebook.com and the like. There is a whole chapter (Chapter 18) in this book devoted to learning and using Rx.NET. For right now, however, a simple understanding that you are reacting to the web browser's Navigated event and then creating a web request to Facebook in the code below is sufficient. Upon receiving the Navigated event, the code below parses out a session ID obtained from Facebook, then uses that session ID to compose a custom message to Facebook requesting an authentication token for the application. The actual posting of the message to the Facebook wall happens in the next step (Step 6). Make the FBLogin() constructor look like the following code:

    public FBLogin()
            {
                InitializeComponent();
    
                this.Loaded += (sender, args) =>
                {
                    var url = string.Format(STR_FB_Login, STR_FB_AppId,
                    HttpUtility.UrlEncode(STR_FB_SuccessUrl), STR_FB_Permissions);
                    IObservable<IEvent<NavigationEventArgs>> FBResponse;
    
                    //register a subscription to FaceBook navigated event
                    FBResponse = Observable.FromEvent<NavigationEventArgs>(webBrowser1,
                    "Navigated");
                    FBResponse.ObserveOn(Deployment.Current.Dispatcher)
                        .Subscribe(evt =>
                        {
                            //on successful user authentication event only
                            if
    (evt.EventArgs.Uri.ToString().StartsWith(STR_FB_SuccessUrl))
                            {
                                //1. get a session ID from the query string
                                var sessionId =
    evt.EventArgs.Uri.Query.Substring("?code=".Length);
    
                                //get the user and compose an authentication token request
                                string strTokenId = GetGraphToken(sessionId);
                                string strMessage = String.Empty;
                                NavigationContext.QueryString.TryGetValue("MessageToPost",
    out
    
                            strMessage);
    
                                //2. get OAuth authentication token and use it to update
    user's Facebook wall
                                UpdateWall("POST", strTokenId, strMessage);
                                NavigationService.GoBack();
                            }
                        },
                        ex =>
                        {
                            //log/process exceptions here
    
                        }
                    );
    
                    //invoke the navigation process
                    webBrowser1.Navigate(new Uri(url, UriKind.Absolute));
                };
            }
  6. Finally, you will code a couple of helper methods that will create a message to Facebook in the format that Facebook can understand, properly parse Facebook responses, and redirect. The first one of those methods is the GetGraphToken method shown here:

    public static string GetGraphToken(string sessionId)
    {
        string strAccessTokenUrl = String.Empty;
        try
        {
            strAccessTokenUrl = string.Format(FB_GetAccessToken, STR_FB_AppId,
            STR_FB_SuccessUrl, FB_AppSecret, sessionId);
        }
        catch (Exception exc)
        {
            System.Diagnostics.Debug.WriteLine("ERROR: " + exc.Message);
            System.Diagnostics.Debug.WriteLine(exc.StackTrace);
        }
    
        return strAccessTokenUrl;
    }
  7. The final helper method performs the heavy lifting of posting to Facebook. The gist of it is to use Rx.NET to asynchronously create a POST request to Facebook website, asking for a special OAuth authentication token and, upon successfully getting it, update user's Facebook wall. Don't feel overwhelmed by the length of the method below—you have learned the basic flow of OAuth authorization already, and this method simply implements the details of that flow inside a single function that you could reuse inside the applications that you build. Also, don't forget that you can always download all the code for this book instead of manually typing it in.

public static void UpdateWall(string method, string url, string postData)
        {
            var webRequest = WebRequest.Create(url) as HttpWebRequest;
            webRequest.Method = method;

            if (method == STR_Post)
            {
                webRequest.ContentType = STR_FormEncoded;
                // request an authentication token
                Observable.FromAsyncPattern<WebResponse>(
                            webRequest.BeginGetResponse,
                            webRequest.EndGetResponse)()
                            .Subscribe(
                            wr =>
                            {
                                try
                                {
                                    // upon completion of request for authentication
token, parse out access
                      // token
                  using (var responseReader = new
                      StreamReader(wr.GetResponseStream()))
                                   {
                                       string strOutput = responseReader.ReadToEnd();

                                       // use access token to compose the request to
post to user's Wall
                                       var payload =
                      string.Format("{0}&message={1}&caption={2}&link={3}&name={4}",
                      strOutput, "My WP7 App: 

" + postData, "WP7 App",
                      "http://www.windowsphone.com", "WP7 Facebook Integration");

                                       var uri = new
                       Uri(string.Format("https://graph.facebook.com/me/feed?{0}",
                       payload));

                                       var wc = new WebClient { Encoding =
Encoding.UTF8 };

Observable.FromEvent<UploadStringCompletedEventArgs>(wc,
                        "UploadStringCompleted")
                                            .Subscribe(evt =>
{
                                                try
                                                {
                                                    if (evt.EventArgs.Result != null)
                                                    {
                                                        //successfully updated wall,
print SUCCESS message into
                              // Debug window
                                                        Debug.WriteLine("SUCCESS!");
                                                    }
                                                }
                                                catch (WebException ex)
                                                {
                                                    StreamReader readStream = new
                                StreamReader(ex.Response.GetResponseStream());
Debug.WriteLine(readStream.ReadToEnd());
                                                }
                                            },
                                            ex =>
                                            {

                                            }
                                        );

                                        wc.UploadStringAsync(uri, null, payload);
                                    }

                                }
                                catch (WebException ex)
                                {
                                    StreamReader readStream = new
                        StreamReader(ex.Response.GetResponseStream());
                                    //Get the error message from Facebook
                                    Debug.WriteLine(readStream.ReadToEnd());
                                }
                            });
             }
        }

You are now ready to run the application. Press F5, type "Hello from WP7 and Rx.NET" in the text box that comes up, then press "Post to Facebook" button. You should be prompted to login to Facebook (it's probably a good idea to create a test account on Facebook for testing your application), and, upon successful authentication, your message should appear on your Facebook wall.

This section provided you with the basics of integrating your applications with social networks using OAuth. You should be able to relatively easily modify your applications to talk to LinkedIn and other providers implementing OAuth using the sample code above. The beauty of this implementation is the fact that the whole OAuth flow is embedded inside a single page (FBLogin.xaml), providing for modularized application development.

A final word of caution, however, and it's a very important one: even though in the sample above you have embedded your Facebook application ID and Secret Application Key inside the code, you should never do this in applications that you will distribute to the end users. As you will see in Chapter 19 of this book, it is extremely easy to gain access to application's source code, and you don't want to be sharing your application's secrets with anybody. In the real-world solution, your Windows Phone 7 application will request Facebook ID and a Secret Key from a secure web service that you provide (upon initialization, or right before the user makes a request to post to Facebook wall, for example). We have avoided showing you an implementation of this service here to avoid complicating the example; however, there are good demos on building web services throughout this book, including the one in Chapter 17 where you build a simple WCF service.

Note

Note Remember to never embed your Facebook Application ID or your Secret Key inside your production code!

Integrating into Windows Phone 7 Hubs

Among the many strengths of the Windows Phone 7 platform is the extent of its integration into the rest of the .NET ecosystem developed by Microsoft over the years, which remains one of its biggest advantages over competing phone platforms. The integrated experience comes in the form of hubs on the phone Start screen, which are essentially menu areas that collect data based on functions. The following hubs are available and are tightly integrated into the Windows Phone 7 OS:

  • The People Hub integrates feeds from Windows Live and Facebook, and you can also connect other services to Windows Live like LinkedIn, YouTube, Flickr, WordPress, and over 70 more.

  • The Pictures Hub makes it easy to share pictures and video with your friends via social networks.

  • The Games Hub with its first and only Xbox Live app, which allows for game, avatar, achievements, and profile integration.

  • The Music and Video Hub makes the full collection of music and videos available to Zune devices also integrated with Windows Phone 7. In fact, the Zune pass that allows unlimited leasing of music may be one of the best kept secrets of Windows Phone 7 platform!

  • The Marketplace Hub allows users to find and install certified applications and games on the phone.

  • The Office Hub with its support of Exchange and Exchange ActiveSync, Outlook (with e-mail, calendar, and contacts all available), PowerPoint, SharePoint, Word, and Excel. You can edit Office documents on your mobile device and have your changes available in real time (i.e., as you change them) to others.

The marketing campaign for Windows Phone 7 is about allowing users to "glance and go," or to get the information or the functionality they need from the phone very quickly (quicker than competing platforms, that is). Hubs play a critical role in providing this "glance and go" experience, and your application can raise that role even further by integrating with hubs directly. When you integrate with one of the hubs, your application becomes visible and available through that hub, and not just through the standard list of applications installed on the device. Of course, the functionality provided by your application must fit with the functionality a user might expect from the hub; for example, a music discovery service that allows you to search and find new music based on what you currently like and own should certainly fit within the Music and Video Hub.

Detailed instructions for integrating with the Pictures Hub are provided in Chapter 16 by using the Extras feature of that hub. The next section of this chapter will briefly cover the Music and Video Hub, giving you a general idea of what it would take for your application to appear there and providing users more of the "glance and go" experience. In addition, we will touch on integration features of Windows Phone 7 platform available to users of SharePoint, a major enterprise collaboration platform from Microsoft.

Integrating your Application with Music and Video Hub

Integrating with Music and Video Hub is simple: once you ensure that your application makes use of the MediaHistory and MediaHistoryItem classes and provide images to display in the Music and Video Hub tile, the Windows Phone application certification process (discussed in detail in Chapter 5) will take care of the rest. Once the certification process detects that your application uses the MediaHistory and MediaHistoryItem classes, your application's hub will be set to Music and Video, and your application will show up on the panorama panel titled "Marquee" within that hub. The quickest way to get to Marquee tab is to swipe the panorama from left to right once you are in the Music and Video hub.

Once your application is inside the Music and Video Hub, it can manipulate the tile for that hub, and it can also update the history list of media items played or the list of newly available media items. To update the history and new media items lists, your application will instantiate a new MediaHistoryItem object, set its properties, and call WriteRecentPlay and WriteAcquiredItem, correspondingly. To update the Now Playing tile on the phone, you would once again create a new MediaHistoryItem object, set its properties, and then assign it to the MediaHistory.Instance.NowPlaying property.

It is certainly inconvenient enough that the emulator does not provide any of the hubs to test integration against, so you have to deploy your application to a real device to test that integration. What could be even more frustrating is the fact that you may need to wait for your application to be certified before it is available for testing as part of the Music and Video Hub. To help prevent potentially lengthy application development procedures for hub integration, Microsoft has come up with a workaround for testing Music and Video Hub integration. Inside the WMAppManifest.xml file, located within the Properties folder in your Solution Explorer, make sure to set the HubType value to 1, as illustrated here:

<App xmlns="" ProductID="{c98b0a70-e0c1-462f-a756-5d0aff98e066}" Title="Tasks"
RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal"  Author="Tasks author"
Description="Sample description" Publisher="Tasks" HubType="1">

Microsoft provides a set of guidelines for images that you must submit during the certification step, should you choose to integrate with the Music and Video Hub and decide to update the tile of that hub. These guidelines are summarized in the list below:

  1. Your tile images must be of type JPEG.

  2. You must include your application title or logo on each tile image.

  3. The Now Playing tile must be 358 pixels x 358 pixels in size.

  4. Other tiles must be 173 pixels x 173 pixels in size.

Integration with SharePoint

While Microsoft has been very explicit in their marketing materials that the first release of Windows Phone 7 OS is targeted at everyday consumer and not at enterprise customers, the company has already started creating several critical hooks necessary for enterprises to take notice of the platform. One of such hooks is the fact that you can work within the enterprise SharePoint environment on your Windows Phone 7 device. The SharePoint Workspace Mobile application comes pre-installed on every single Windows Phone 7 device (and is located in the same exact spot on every device—inside the Office hub). Once you log in into SharePoint site, you can browse all Office documents and they will appear in the same exact format as on any other computer capable of connecting to SharePoint. You can modify documents, and your changes, as well as potential conflicts when others modify the same document, will be detected and resolved via the SharePoint integration. Another exciting feature is Offline Documents, which allows you to download and edit documents even if connection to SharePoint site is not available. You can synchronize the documents later, and you will also be guided through resolving potential conflicts within the document due to multiple people working on it.

SharePoint integration is just one example of the powerful platform integration that you have on Windows Phone 7. As the platform continues to evolve, we will see even broader and better integration options available into the vast Microsoft ecosystem out there.

Summary

In this chapter, you learned how applications integrate with the Windows Phone OS. You learned how to use launchers and choosers to accomplish common tasks on the platform. You learned what effects launchers and choosers have on the state of the application that uses them, and you reviewed the application life cycle and managing state within this life cycle. Finally, you got a brief overview of all the major applications already tightly integrated within Windows Phone 7 and grouped in hubs. In the next chapter, you will learn about Trial API and build sample trial applications for submission to the Marketplace.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset