Debugging Picture Viewer App Connect on WP7

The 7.5 update for Windows Phone 7, codenamed “Mango” has finally been released to the public and adds a ton of new features both for end users as well as developers. One of these features is called App Connect. App Connect can put your app in selected places within the OS and make your app more integrated with the system than ever before.

Extending the Picture Viewer

Described in the MSDN docs here, adding this extension to your app will put it in the list of apps available when looking at pictures.

IC513020

To activate this feature, you need to add the following code to your WMAppManifest.xml, as a child of the element.

You are then ready to begin receiving pictures to your app. To detect and accept the picture sent to you, you examine the “token” key of the NavigationContext, something like:

IDictionary queryStrings =
    this.NavigationContext.QueryString;

Stream photoStream = null;
if (queryStrings.ContainsKey("token"))
{
    var library = new MediaLibrary();
    Picture picture = library.GetPictureFromToken(queryStrings["token"]);
    photoStream = picture.GetImage();
}

Gotcha 1 – Navigation & the token parameter

Invoking the app from the Picture Viewer starts your app and navigates to the main page. I think the most common scenario for handling a new picture is to do this on some other page than the main page. In my app that I’m writing (a photo diary app), I directly navigate away from the main page to the details page, thus creating a diary entry for the new picture. This is all easily done, but the quirk comes when navigating back to the main page – the “token” parameter is not cleared! So, my so simple code immediately creates yet another entry and takes me straight back to the details page.

Fix – Clear the “token” parameter after fetching the picture.

if (queryStrings.ContainsKey("token"))
{
    var library = new MediaLibrary();
    Picture picture = library.GetPictureFromToken(queryStrings["token"]);
    photoStream = picture.GetImage();
    queryString.Remove("token");
}

Gotcha 2 – You can’t debug

I really hope someone proves me wrong here. Please do Smile

UPDATE: Someone has proven me wrong. Instead of connecting to the device through Zune, you can use the WPConnect.exe tool. You plug in your phone, wait for Zune to open, close Zune, wait for its process to die, then run wpconnect.exe. The problem is that Zune locks the media library on the phone, and the wpconnect tool does not. Thank you Andrew Byrne for the nudge!

The problem:

emulator – the picture hub does not exist, neither the camera app

device – you’re now allowed to access the picture hub while connected to the computer (not even the PhotoChooserTask will launch)

So, how can we debug this? Well, I found a way, a tedious way, but still a way.

Fix 2 – Put an image in the isolated storage, then feed this image to your code on the main page.

An even more realistic test would be to put the exact same token in the queryStrings collection – but I’m not sure that the app would have privileges to read that picture from the picture hub then.

2a. Take a snapshot of the isolated storage from the emulator using ISETOOL (Isolated Storage Explorer). The app guid is the “

isetool ts xd  .

2b. Put an image in the root (or wherever) of the isolated storage file structure

2c. Restore the snapshot to the emulator (note the folder name here, should the child folder of the folder specified in the “take snapshot command)

isetool rs xd  IsolatedStore

2d. Fake AppConnect by reading your file

Here I read the image to a MemoryStream and hand away, to interfere with IsolatedStorage as little as possible.

The high-level code that will not change looks like:

protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); HandleImageFromAppConnect(); } private void HandleImageFromAppConnect() { var stream = GetPictureStream(); if (stream != null) { ViewModel.HandleAddWithImageInvoked(stream); NavigateToDetails(); } }

And the method to get the stream:

private Stream GetPictureStream() { IDictionary queryStrings = this.NavigationContext.QueryString; Stream photoStream = null; if (queryStrings.ContainsKey("token")) { var library = new MediaLibrary(); Picture picture = library.GetPictureFromToken(queryStrings["token"]); queryStrings.Remove("token"); photoStream = picture.GetImage(); } #if DEBUG var isFakingImageFromAppConnect = false; if (isFakingImageFromAppConnect) { MemoryStream manualStream = null; using (var store = IsolatedStorageFile. GetUserStoreForApplication()) { if (store.FileExists("/pic.jpg")) { using (var file = store.OpenFile("/pic.jpg", FileMode.Open)) { var bytes = new byte[file.Length]; file.Read(bytes, 0, bytes.Length); manualStream = new MemoryStream(bytes); } } } photoStream = manualStream; } #endif

That does it – we can debug-stop on the bool, set it, then let the code spin and debug away.

Finally – please – find an easier way and tell me about it Smile

Bye for now!

This Post Has 2 Comments

    1. Hi Andrew.
      Thanks for the comment! I’ve been using WPConnect many times in the past but not recently. I was not aware of the fact that it does not lock the media lib and hence can be used for debugging media apps, great feedback. I’ll update the post soon.
      /A

Leave a Reply

Close Menu