MOBILE

Integrating Your Application with Windows Phone 7

6/7/2011 11:48:25 AM
So far in this article, you have built a stand-alone application that uses choosers and parts of the XNA Framework to manage photos snapped with a Windows Phone camera. What's unique about the Windows Phone 7 Framework, however, is that it encourages you to have your application make use of built-in phone applications to perform certain tasks. The Photo application, for example, provides you with hooks you can use to make the functionality of an application like PhotoCapture available to users without having to find it and explicitly launch it. Those hooks are the Extras and the Share commands, which are found on the context menus of each photo where the context menu is displayed when you press the photo for a few seconds.

Both features are best explained by actually observing them at work. With the real Windows Phone 7 in hand, click the Pictures hub, select the "folder" to view the photos from (Camera Roll, for example), and then select a specific photo from the list. Click the ellipsis (...) at the bottom of the screen. When the context menu appears, you'll see an Extras option displayed at the very bottom. This Extras option is available for you to integrate or tie into. What you will do in the next walkthrough is use it to launch the PhotoCapture application so that you can choose a picture, save it to your TwitPic, and share it with your Twitter friends.

The context menu that pops up when you press the picture includes a Share command. The Share option is available when photos are being viewed as a list rather than one at a time. If you click the Share command, you will notice that it offers several ways to share the photo with the world. In the following section, you will learn to build an application that will use TwitPic as a cloud store for the photos on the phone.


1. Using Extras to Launch an Application

The Windows Phone 7 platform is all about providing the best possible phone usage experience to consumers. When consumers look at a photo on the phone, they are using an application known as a Single Photo Viewer (SPV) that provides applications to extend the viewer's functionality via the Extras command of the context menu. In this section, you will further enhance the PhotoCapture application to take advantage of the Extras feature within the Photos application. The PhotoCapture application will be using PhotoChooserTask or CameraCaptureTask to allow the user to select or take a picture once it has been invoked via the Extras feature.

To integrate with SPV, an application needs the following:

  1. An Extras.xml file in its root directory with markup to the Extras feature

  2. Code to properly read and load or manipulate the photo selected in the Extras dialog

You will implement both of those steps in the next section.

1.1. Adding an Extras.xml File to the Project

Adding an Extras.xml file is very straightforward; the only potential difficulty may be in the fact that the content of that file has to be precise. Make sure you either copy and paste this content from the source code available with this book, or type it in very carefully.

  1. Right-click the project name, select Add => New Item, and then select XML file. Make sure (this is important!) you name it Extras.xml.

  2. Double-click the Extras.xml file to open it. Paste the following contents inside that file, which will enable the Windows Phone 7 framework to locate those applications ready to implement the Extras functionality.

    <Extras>
    <PhotosExtrasApplication>
    <Enabled>true</Enabled>
    </PhotosExtrasApplication>
    </Extras>

  3. The contents of the file are not very important; however, in the Properties window, make sure to set the Build Action property to Content and the Copy To Output property to Copy Always for the this file (click the file and press F4 to bring up the Properties dialog).

Make sure you save Extras.xml, but otherwise you are ready to move on to the next step.

1.2. Adding Code to Navigate to a Photo

To properly retrieve the photo that the user selected through the Extras feature, the application must override the OnNavigatedTo event in MainPage.xaml.cs. The steps here show you how to do that:

  1. Open MainPage.xaml.cs and add the following using statement to the top of the page:

    using System.Windows.Navigation;

  2. The reference to the Microsoft.Xna.Framework assembly should still be in the project from the prior walkthroughs; however, if you start a new project that implements the Extras functionality, make sure to add a reference to that assembly and the following using statement to properly refer to the Media Library. You will also need System.Windows.Medi.Imaging to work with the image source.

    using Microsoft.Xna.Framework.Media;
    using System.Windows.Media.Imaging;

  3. Paste the following OnNavigatedTo method. Note how the basic operation is that of reading a QueryString passed in, determining if we have a value for the parameter token, and then trying to retrieve the photo from the Media Library by that token ID.

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    try
    {


    IDictionary<string, string> queryStrings =
    this.NavigationContext.QueryString;
    if (queryStrings.ContainsKey("token"))
    {
    MediaLibrary library = new MediaLibrary();
    Picture picture = library.GetPictureFromToken(queryStrings["token"]);

    BitmapImage bitmap = new BitmapImage();
    bitmap.SetSource(picture.GetImage());
    WriteableBitmap picLibraryImage = new WriteableBitmap(bitmap);
    imgPhoto.Source = picLibraryImage;
    }

    }
    catch (Exception ex)
    {
    Dispatcher.BeginInvoke(() => txtStatus.Text = ex.Message);
    }
    }


  4. Deploy the application to the phone. Then, from the phone's Start screen, select the Pictures hub, pick any picture collection, and select an individual picture of your choice. Click the ellipsis at the bottom of the screen, and select Extras. You should see the PhotoCapture application listed on the next screen that comes up. Clicking the PhotoCapture application should start the application and load the selected photo into the Image control—exactly the expected behavior.

In the next section, you will walk through the steps needed to extend the Share dialog for the photos. The concepts you use to extend the Extras and Share features are very similar; the differences, as you will see shortly, are in the details of the file name and the query string key.

2. Using Share to Upload PhotoCapture Snapshots to TwitPic

In this walkthrough, you will make more changes to the PhotoCapture application to take advantage of the Share extensibility feature within the Photos application. For simplicity, the PhotoCapture application will load the selected image onto its main screen. In the next section, you will complete the circle and write code to send the image to the TwitPic cloud service for easy reference from the Twitter messages.

As with your implementation of Extras, to extend the Share option to include it, an application needs the following:

  1. An E0F0E49A-3EB1-4970-B780-45DA41EC7C28.xml file in its root directory enabling the application's integration with the Share feature (this is not a typo—the XML file must be named exactly like that for the application to belong to the Share feature)

  2. Code to properly read and/or share the photo selected in the Share dialog

You will implement both steps in the next section.

2.1. Adding an E0F0E49A-3EB1-4970-B780-45DA41EC7C28.xml File to the Project

Adding this strangely named XML file is very straightforward; the only potential difficulty may be the fact that the name is completely unreadable, so it would be best if you could copy and paste it from the source code available for download with this book.

  1. Right-click the project name, select Add => New Item, and then select "XML file." Make sure (this is important!) you name it E0F0E49A-3EB1-4970-B780-45DA41EC7C28.xml.

  2. While the contents of the file may not be very important, be sure to go to the Properties window and set the Build Action property to Content and the Copy To Output property to Copy Always for the this file (click the file and press F4 to bring up the Properties dialog).

Make sure you save this XML file before moving onto the next step.

2.2. Adding Code to Navigate to the Selected Photo

To properly retrieve the photo that the user selected through the Extras feature, the application must override the OnNavigatedTo event in MainPage.xaml.cs. The steps here show you how to do that:

  1. If you are continuing from the Extras walkthrough, you already have all the necessary references and using statements in place. However, if you were to start a new project, make sure that you have a reference added to Microsoft.Xna.Framework and the following using statements are in place:

    using System.Windows.Navigation;
    using Microsoft.Xna.Framework.Media;

  2. Paste the following OnNavigatedTo method (or add to that method if you are continuing from the Extras walkthrough). Note how the basic operation is that of reading a query string passed in, determining whether there is a value for the FileId parameter, and then trying to retrieve the photo from the Media Library by that token ID.

    try
    {
    IDictionary<string, string> queryStrings =
    this.NavigationContext.QueryString;

    if (queryStrings.ContainsKey("FileId"))
    {
    MediaLibrary library = new MediaLibrary();
    Picture picture = library.GetPictureFromToken(queryStrings["FileId"]);

    BitmapImage bitmap = new BitmapImage();
    bitmap.SetSource(picture.GetImage());
    WriteableBitmap picLibraryImage = new WriteableBitmap(bitmap);
    imgPhoto.Source = picLibraryImage;
    }
    }
    catch (Exception ex)
    {


    Dispatcher.BeginInvoke(() => txtStatus.Text = ex.Message);
    }

  3. Deploy the application to the phone.

Now you're ready to test your implementation so far. Just as you did for your Extras integration, from the phone's Start screen, select the Pictures hub on your phone, pick any picture collection, and select an individual picture of your choice. Click the ellipsis (...) at the bottom of the screen, and select Share. You should see Upload to PhotoCapture as one of the options that come up. Clicking that option should start the application and load the selected photo into the Image control—the behavior we expect.

Now you're ready to upload the photos to TwitPic, which is the primary hosting service for photos destined for Twitter, the hottest social media network today. Silverlight in general and Silverlight on Windows Phone 7 in particular differ from other applications in the fact that they rigorously enforce a non-blocking user interface principle: everything, including communications over the network, must happen asynchronously. TwitPic cloud service provides a RESTful API that allows programmers to send messages to that service as long as we conform to the expected message format.

2.3. Adding an Upload Button to the UI

On the user interface front, you will need to add an additional button that will trigger the upload of the photo to TwitPic. Figure 16-3 illustrates one possible placement of this button. Name the button btnUpload, and set its caption to TwitPic.

2.4. Writing Code to Transfer an Image to TwitPic

Because network access on Windows Phone 7 must be performed asynchronously, it takes quite a bit of code to properly construct the RESTful web service request. Most of the code, however, is repetitive, and all of the major points are summarized in these step-by-step instructions.

  1. Right-click the project name in Solution Explorer, select Add Reference, and then select System.Xml.Linq.

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

    using System.IO;
    using System.Text;
    using System.Xml.Linq;

  3. Open MainPage.xaml.cs and paste the UploadPhoto function written here. This will be the only function that will be invoked when the photo upload needs to take place. This function sets the URL and the type of the request, and then it invokes the asynchronous BeginGetRequestStream, which packages the photo and the user credentials.

    public void UploadPhoto()
    {
    HttpWebRequest request =
    (HttpWebRequest)WebRequest.Create("http://twitpic.com/api/upload");
    request.ContentType = "application/x-www-form-urlencoded";
    request.Method = "POST";
    request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback),
    request);
    }



    Figure 1. User interface for uploading photos to TwitPic
  4. Add the following code to define the asynchronous function GetRequestStreamCallback that does all of the packaging of proper parameters; note that the exact form of the message was dictated by TwitPic, and this method simply conforms to it.

    NOTE

    The TwitPic API is sensitive to even slightly malformed messages; be sure you copy/paste this method from the source code that comes with this book instead of manually retyping it and risking making a mistake.

    private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
    {
    try
    {

    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
    string encoding = "iso-8859-1";
    // End the operation



    Stream postStream = request.EndGetRequestStream(asynchronousResult);
    string boundary = Guid.NewGuid().ToString();
    request.ContentType = string.Format("multipart/form-data; boundary={0}",
    boundary);

    string header = string.Format("--{0}", boundary);
    string footer = string.Format("--{0}--", boundary);

    StringBuilder contents = new StringBuilder();
    contents.AppendLine(header);

    string fileHeader = String.Format("Content-Disposition: file; name=\"{0}\";
    filename=\"{1}\"; ", "media", "testpic.jpg");
    string fileData = Encoding.GetEncoding(encoding).GetString(imageBits, 0,
    imageBits.Length);

    contents.AppendLine(fileHeader);
    contents.AppendLine(String.Format("Content-Type: {0};", "image/jpeg"));
    contents.AppendLine();
    contents.AppendLine(fileData);
    contents.AppendLine(header);
    contents.AppendLine(String.Format("Content-Disposition: form-data;
    name=\"{0}\"", "username"));
    contents.AppendLine();
    contents.AppendLine("BeginningWP7");

    contents.AppendLine(header);
    contents.AppendLine(String.Format("Content-Disposition: form-data;
    name=\"{0}\"", "password"));
    contents.AppendLine();
    contents.AppendLine("windowsphone7");

    contents.AppendLine(footer);

    // Convert the string into a byte array.
    byte[] byteArray =
    Encoding.GetEncoding(encoding).GetBytes(contents.ToString());

    // Write to the request stream.
    postStream.Write(byteArray, 0, contents.ToString().Length);
    postStream.Close();

    // Start the asynchronous operation to get the response
    request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);
    }
    catch (Exception ex)
    {
    Dispatcher.BeginInvoke(() => txtStatus.Text = ex.Message);
    }
    }


  5. Add the GetResponseCallback function that will asynchronously receive the results of the upload (Success or Fail) and parse that result out using LINQ to XML.

    private void GetResponseCallback(IAsyncResult asynchronousResult)
    {
    try
    {

    HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
    // End the operation
    HttpWebResponse response =
    (HttpWebResponse)request.EndGetResponse(asynchronousResult);
    Stream streamResponse = response.GetResponseStream();
    StreamReader streamRead = new StreamReader(streamResponse);
    string responseString = streamRead.ReadToEnd();

    XDocument doc = XDocument.Parse(responseString);
    XElement rsp = doc.Element("rsp");
    string status = rsp.Attribute(XName.Get("status")) != null ? rsp.Attribute(XName.Get("status")).Value : rsp.Attribute(XName.Get("stat")).Value;

    // Close the stream object
    streamResponse.Close();
    streamRead.Close();

    // Release the HttpWebResponse
    response.Close();

    }
    catch (Exception ex)
    {
    Dispatcher.BeginInvoke(() => txtStatus.Text = ex.Message);
    }
    }


  6. Now you need to call the UploadPhoto method when the user clicks the TwitPic button. Open MainPage.xaml in Design view, and double-click the TwitPicbtnUpload_Click method, paste the following line of code: button. Inside the

    UploadPhoto();

You are now ready to run the application. Set the Windows Phone 7 emulator as your deployment target, click F5, and when the application comes up, click the camera button (the first button on the Application Bar). Take a picture, accept it, and then click the TwitPic button. If no errors were reported in the status TextBlock, you should see your image on TwitPic's web site, as shown in Figure 2.

Figure 2. Image uploaded to TwitPic
Other  
  •  Introducing Windows Phone 7 Photo Features (part 2) - Using a Chooser to Open Photos & Saving Photos to the Phone
  •  Introducing Windows Phone 7 Photo Features (part 1) - Using a Chooser to Take Photos
  •  Mobile Application Security : Bluetooth Security - Bluetooth Technical Architecture
  •  Mobile Application Security : Bluetooth Security - Overview of the Technology
  •  Windows Phone 7 Development : Push Notifications - Implementing Cloud Service to Track Push Notifications
  •  Windows Phone 7 Development : Push Notifications - Implementing Raw Notifications
  •  Windows Phone 7 Development : Push Notifications - Implementing Tile Notifications
  •  Windows Phone 7 Development : Push Notifications - Implementing Toast Notifications
  •  iPhone Application Development : Creating a Navigation-Based Application
  •  Windows Phone 7 Development : Push Notifications - Introducing the Push Notifications Architecture
  •  Windows Phone 7 Development : Push Notifications - Understanding Push Notifications
  •  Windows Phone 7 Development : Handling Multiple Concurrent Requests with Rx.NET
  •  WAP and Mobile HTML Security : Application Attacks on Mobile HTML Sites
  •  WAP and Mobile HTML Security : Authentication on WAP/Mobile HTML Sites & Encryption
  •  iPhone Application Development : Displaying and Navigating Data Using Table Views - Building a Simple Table View Application
  •  iPhone Application Development : Understanding Table Views and Navigation Controllers
  •  Windows Phone 7 Development : Revising WeatherRx to Manage Slow Data Connections
  •  Windows Phone 7 Development : Handling Data Connection Issues with Rx.NET
  •  Windows Phone 7 Development : Handling Errors in Rx.NET
  •  Windows Phone 7 Development : Using Rx.NET with Web Services to Asynchronously Retrieve Weather Data
  •  
    Top 10
    Nikon 1 J2 With Stylish Design And Dependable Image And Video Quality
    Canon Powershot D20 - Super-Durable Waterproof Camera
    Fujifilm Finepix F800EXR – Another Excellent EXR
    Sony NEX-6 – The Best Compact Camera
    Teufel Cubycon 2 – An Excellent All-In-One For Films
    Dell S2740L - A Beautifully Crafted 27-inch IPS Monitor
    Philips 55PFL6007T With Fantastic Picture Quality
    Philips Gioco 278G4 – An Excellent 27-inch Screen
    Sony VPL-HW50ES – Sony’s Best Home Cinema Projector
    Windows Vista : Installing and Running Applications - Launching Applications
    Most View
    Bamboo Splash - Powerful Specs And Friendly Interface
    Powered By Windows (Part 2) - Toshiba Satellite U840 Series, Philips E248C3 MODA Lightframe Monitor & HP Envy Spectre 14
    MSI X79A-GD65 8D - Power without the Cost
    Canon EOS M With Wonderful Touchscreen Interface (Part 1)
    Windows Server 2003 : Building an Active Directory Structure (part 1) - The First Domain
    Personalize Your iPhone Case
    Speed ​​up browsing with a faster DNS
    Using and Configuring Public Folder Sharing
    Extending the Real-Time Communications Functionality of Exchange Server 2007 : Installing OCS 2007 (part 1)
    Google, privacy & you (Part 1)
    iPhone Application Development : Making Multivalue Choices with Pickers - Understanding Pickers
    Microsoft Surface With Windows RT - Truly A Unique Tablet
    Network Configuration & Troubleshooting (Part 1)
    Panasonic Lumix GH3 – The Fastest Touchscreen-Camera (Part 2)
    Programming Microsoft SQL Server 2005 : FOR XML Commands (part 3) - OPENXML Enhancements in SQL Server 2005
    Exchange Server 2010 : Track Exchange Performance (part 2) - Test the Performance Limitations in a Lab
    Extra Network Hardware Round-Up (Part 2) - NAS Drives, Media Center Extenders & Games Consoles
    Windows Server 2003 : Planning a Host Name Resolution Strategy - Understanding Name Resolution Requirements
    Google’s Data Liberation Front (Part 2)
    Datacolor SpyderLensCal (Part 1)