How to support Windows Phone 8 devices in a Windows Phone 7 application

As I’ve already highlighted in another blog post, Windows Phone 8 has introduced many new features; plus, lot of things have been changed under the hood: Microsoft has abandoned the old kernel, based on Window Mobile’s core, to introduce a new modern kernel, based on Windows 8’s one. As a consequence, also the architecture has deeply changed: no more Silverlight and .NET Framework, but Windows Runtime.

To allow developers to reuse as much as possible their code and skills, Microsoft has introduced two important features:

  • Quirk mode: the old APIs are automatically mapped to the new ones; this way, all the applications written for Windows Phone 7.x are able to run on a Windows Phone 8 device without changes in most of the cases.
  • .NET API for Windows Phone, which is a set of libraries in the Windows Runtime that match the one that were part of the Silverlight for Windows Phone runtime. This way, when the developer decides to port his project to Windows Phone 8 he can focus on supporting the new features rather than rewriting the previous code to use the new Windows Runtime APIs.

 

The best way to use the Windows Phone 8 features is to update your project to the new release, by using a specific Visual Studio option that is displayed when you right click on a Windows Phone 7 project.

This scenario, even if it’s the most powerful, requires to maintain two different projects if we want to keep supporting also Windows Phone 7 users, since Windows Phone 8 applications are not compatible with the previous versions. Sometimes this solution can be too expensive for the developer, especially if your application is very simple and can gain few benefits from the Windows Phone 8 features.

In this post we’re going to see two solutions that will help us to maintain a single Windows Phone 7 project that will be adapted so that Windows Phone 8’s devices owners will be able to get the best from their devices.

Supporting the new resolutions

One of the most important Windows Phone 8 new features is new resolutions support: Windows Phone 7 supported just the 800×480 resolution; as a consequence all the icons and images that are part of our project can degrade if they are displayed on a device with a higher resolution, like the Lumia 920 (1280×768) or the HTC 8X (1280×720).

Now the Store accepts also Windows Phone 7.x applications with icons with higher resolution: you can embed in your project 336×336 tiles and 99×99 icons. This way, also Windows Phone 8 owners will be able to see images at the best possible quality.

You just have to overwrite the original images, prepare a new XAP and sumit a new update of your application to the store.

How to use some of the new Windows Phone 8 features

By using a mechanism called reflection developers are able to use some of the new Windows Phone 8 features in a Windows Phone 7.x application, in case it’s running on a Windows Phone 8 device.

What is reflection? This mechanism allows developers to use methods, properties and classes that are stored in a DLL library without adding it as a reference in a Visual Studio project. With this procedure you’ll be able to interact with some of the new Windows Phone 8 libraries from a Windows Phone 7.x project, even if Visual Studio isn’t able to show them.

You’ll be able to use the following features:

  • The new launchers and choosers (for example, to add a new appointment to the calendar or download a map).
  • The new tiles templates and sizes.

 

Using the reflection requires to write more complicated code compared to the approach you use when you have a reference in your Visual Studio project: for example, you don’t have access to Intellisense and you have to remember the exact name of every method and class you’re going to use.

For this reason Rudy Hyun, a Windows Phone MVP, has developed a library called Mangopollo (the strange name comes from the fusion between Mango, the Windows Phone 7.5 codename, and Apollo, the Windows Phone 8 codename), which features a set of classes and methods that act as a wrapper to the reflection, so that you can interact with the Windows Phone 8 features using the usual approach.

Mangopollo is an open source project that is available both on Codeplex and NuGet in two versions: Mangopollo and Mangopollo.Light. The difference is that the light version contains only the libraries to interact with the new tiles, so that it can be used also in a background agent project. Mangopollo already supports Windows Phone 7.8: it’s possible to use it to interact with the new tiles that are available on Windows Phone 7.8 devices.

The simplest way to add Mangopollo to your project is by using NuGet: right click on your Windows Phone project, choose Manage NuGet packages and look for and install the package called Mangopollo.

Now you’ll be able to use the new launchers and choosers (that are stored inside the Mangopollo.Tasks namespace) and the new tiles (which classes are inside the Mangopollo.Tiles namespace).

Let’s see to examples on how to use this library: in the first one we’re going to use the SaveAppointmentTask launcher, so that the user will be able to add a new appointment to the calendar.

Use the launchers

Here is how to use the SaveAppointmentTask launcher:

private void OnCreateAppointmentClick(object sender, RoutedEventArgs e)
{
    if (Utils.IsWP8)
    {
        SaveAppointmentTask task = new SaveAppointmentTask();
        task.Subject = "Windows Phone Developer Day";
        task.StartTime = new DateTime(2012, 12, 5);
        task.IsAllDayEvent = true;
        task.Show();
    }
    else
    {
        MessageBox.Show("This is Windows Phone 7!");
    }
}

The first thing to do to use the new features is to check if the app is running on a Windows Phone 8 device, otherwise we would get an exception. We can perform this task by using the Utils.IsWP8 property, which is a simple Boolean.

In case our code is running on a Windows Phone 8 device we create a new SaveAppointmentTask object and we define some properties that describe the appointment, like the title and the date. The definition of this task is the same that is available in the Windows Phone 8 APIs: the name of the methods and properties are the same that you can find in the new SDK.

In the end, we invoke the launcher by calling the Show method. Now let’s test the application using both the emulators: the Windows Phone 8 one (at this point, it doesn’t matter which resolution you use) and the Windows Phone 7.1 one.

In the first case we’ll see the launcher, that will ask to the user to fill all the missing information about the appointment; in the second case, instead, we’ll see a warning message we’ve defined in the code.

imageimage

Play with the tiles

Windows Phone 8 now supports three new tiles sizes and three new templates. The new sizes are:

  • Small: the tile size is ¼ of the original size.
  • Medium: it’s the standard size.
  • Wide: it’s the rectangular size, it’s like having two medium tiles one after the other.

 

The supported templates, instead, are:

  • Flip: it’s the only template that was available in Windows Phone 7; information (texts and pictures) are placed on the front and on the back of the tile, which is periodically flipped to show all of them.
  • Cycle: you can include up to 9 images, that are displayed in rotation.
  • Iconic: it’s used to create tiles with the same look & feel of the native ones, like Mail or Messages. You can use it to show an icon, a counter or text.

 

As a developer, other than choosing the template, you’ll be able also to interact with the tile in different ways, according to the size: for example, we can show some content only in case the user is using a bigger size.

Here is a sample code that uses the Iconic template, which is described by the IconicTileData class, to create a secondary tile.

private void OnCreateWideTileClick(object sender, RoutedEventArgs e)
{
    if (Utils.CanUseLiveTiles)
    {
      var tile = new IconicTileData
      {
          Title = "WP Day",
          Count = 8,
          BackgroundColor = Colors.Transparent,
          IconImage = new Uri("/Assets/Tiles/IconicTileMediumLarge.png", UriKind.Relative),
          SmallIconImage = new Uri("/Assets/Tiles/IconicTileSmall.png", UriKind.Relative),
          WideContent1 = "WP Developer Day",
          WideContent2 = "use Windows Phone 8 features",
          WideContent3 = "on Windows Phone 7 apps"
      }.ToShellTileData();

      ShellTileExt.Create(new Uri("/MainPage.xaml?Id=5", UriKind.Relative), tile, true);
    }
    else
    {
      MessageBox.Show("This is Windows Phone 7");
    }
}

The code is placed inside a statement similar to the one that you’ver seen in the previous example: we’re going to execute the operation only if the app is running on a Windows Phone 8 device.

UPDATE: As Alessandro, a reader of this blog, correctly pointed me it’s better to use the Utils.CanUseLiveTiles property for this purpose: this way, the code will work also on a Windows Phone 7.8 device. Instead, it’s important to keep using the Utils.IsWP8 property for launchers and choosers because they are available only in Windows Phone 8.

If you already had the chance to work with tiles the code will be familiar: we create a new IconicTileData object (which describes the iconic template) and we set up some properties that define the information displayed on the tile. I would like to highlight that we set also three properties (identified by the prefix WideContent), that are used only in case the user has chosen the wide size for the tile of our application.

The secondary tile is created using the Create method of the ShellTileExt class, that works exactly like the native ShellTile class but that is part of the Mangopollo library: in fact, it supports some parameters specific for the new tiles, like (other than deep link and the template) a Boolean which tell to the OS if the tile is going to support or not the wide tile.

Also in this case if we’re going to run the code on the Windows Phone 8 emulator everything will be just fine: the app will close and the new secondary tile will be created. If we play with the various tiles formats we can notice that, once we set the wide size, the information that we have specified in the WideContent properties will be displayed. Instead, if we run the code on the Windows Phone 7 emulator we’ll get the usual warning message.

image

And what if we would like to update the tile? The task is very easy:

private void OnUpdateTileClick(object sender, RoutedEventArgs e)
{
    if (Utils.IsWP8)
    {
        IconicTileData tile = new IconicTileData
                                  {
                                      WideContent1 = "This is the new content",
                                      WideContent2 = "The tile has been updated",
                                      WideContent3 = "with success"
                                  };

        Uri navigationUri = new Uri("/MainPage.xaml?Id=5", UriKind.Relative);
        ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri == navigationUri).Update(tile);
    }
}

We just define a new template using the IconicTileData class and we set only the properties that describe the information that we want to change compared with the original template definition (in the example, we change just the text displayed in the wide tile).

After that the update procedure is the same that we’ve learned to use in Windows Phone 7.5, since it’s indipendent from the template we use: we retrieve the tile to update by using the ShellTile.ActiveTiles collection according to the deep link uri, then we call the Update method, passing as parameter the updated template. Since this method accepts a ShellTileData object, which is the base class which every template inherits from, we can pass any supported template object, even the new ones that are defined in Mangopollo.

The code we’ve just seen to update a tile can be used also in a background agent, so that the tile can be periodically updated: the only thing you’ll have to remember, as I’ve anticipated in the introduction of this post, is to install the Mangopollo.Light package in your agent’s project.

In the end

In this post we have seen how to use some of the new Windows Phone 8 features in a Windows Phone 7 application, so that you’ll be able to improve the user experience for new device’s owners without forcing you to keep two different projects.

This is a very good solution, even if it has a lot of limitations compared to a real upgrade to a Windows Phone 8 project: the new features, in fact aren’t only some new launchers or the new tile sizes, but there are a lot more like NFC, Wallet, Lens Apps that are not available by using one of the strategies that are described in this post.

It’s up to you (and to your application’s category) to choose the best path!

Posted in Windows Phone | Tagged , | 9 Comments

Windows Phone and SQL Lite: what’s the current situation?

The last week I spoke at a Italian conference in Microsoft Italy called Windows Phone Developer Day about sharing code between Windows Phone and Windows 8. One of the topics was data access and how to share code to interact with a database between Windows Phone and Windows 8.

People was a bit confused and I got many questions because I told them that SQL Lite is supported by Windows Phone 8 but can’t be used at the moment. What does it mean?

Let’s make a step back: Windows Phone 7.5 has introduced support to relational databases thanks to SQL CE (as database engine) and LINQ to SQL (as manipulation library, to interact with the database using objects and classes instead of making queries). In Windows Phone 8 Microsoft has decided to go another way, in order to use a solution easier to port to Windows 8 and to other platforms: SQL Lite. In fact, this technology is cross platform and it’s available for Android, iOS, web application, client applications and much more. Probably you’ll have to rewrite the data access layer (due to the differences between technologies and languages), but you’ll be able to reuse the database.

Microsoft has worked with the team to provide an easy way to add SQL Lite to your Windows 8 and Windows Phone 8 project: the result is that, in the Visual Studio Gallery, you’ll find two extensions (one per platform) that can be used to add the SQL Lite engine to your project. The engine is written in native code: this means that you’ll need native code to interact with it and perform operations with the database.

And here comes the confusion I talked about in the beginning of the post: this extension allows you just to add the SQL Lite engine to your application, but doesn’t include a library to work with it using a high level language like C# or VB.NET. The problem is that, for the moment, this library doesn’t exist for Windows Phone 8: the result is that, even if you can add it, you don’t have a way to perform operations with a SQL Lite database, unless you write by yourself a wrapper to the native libraries.

Microsoft is committed into delivering a library as soon as possible, but at the moment we don’t have a release date yet.

On Windows 8 the situation is a bit different, because such libraries already exist: one of the most popular is sqlite-net, on which I talked about in a previous post. Unlucky, this library doesn’t work on Windows Phone 8, because it uses some features of the Windows Runtime that aren’t available in the Windows Phone subset.

In case you’re developing a Windows Phone application and you need to use a database, which are the possible solutions?

The first one is to keep using SQL CE, that works just fine in Windows Phone 8: it’s a very good solution in case you don’t need to port your application to Windows 8 or to another platform.

The second one is to use csharp-sqlite, that is a library published on Google Code that allows to use the SQL Lite engine in a C# application. The library is supported by Windows Phone 8, so you can use it to reuse your SQL Lite database in a Windows Phone application. The downside? The C# library is based on code that is part of the .NET framework and that is not available in the Windows Runtime. This means that you’ll be able to reuse the database, but not the data access layer of your application.

And the third solution? Simply just wait that a native library for Windows Phone 8 will be available Smile

Tagged , | 5 Comments

How to deal with WebView and overlaying elements in Windows 8

The WebView control is very useful to display HTML pages and elements into a Windows Store application. For example, I use in my blog’s application to display the content of a post, formatted to be easily read on a tablet using the Instapaper engine.

If you have played a bit with the WebView control you would have find that it has a particular behavior: no matter how many XAML controls you are going to place over the WebView, they will always be displayed below the view. This is not a bug, but a specific security feature: since in the past developers were able to do dirty tricks by simply placing an hidden web view and by executing dangerous Javascript code in the back, Microsoft has chosen not to allow this anymore. No matter how many efforts you’ll spend trying to find a workaround, you won’t be able to place a WebView below another control (neither fully or partial).

During the development of my blog’s application this security feature caused me some troubles: in the latest version I’ve developed I’ve added support both for Italian and English. The application automatically sets the correct language according to the language of the operating system, but the user is able to change it from the Settings panel. For this reason I’ve added an item in the Settings panel called Language: when the user taps on it, a flyout panel with two radio buttons is displayed.

The problem is that, if the user tries to change the language while he’s reading a post, the flyout goes behind the WebView and he’s not able to fully see it. You can see what I’m talking about in the image below:

image

How to fix it? Since, as I’ve already said, there’s absolutely no way to change the overlay of the WebView control, the only available workaround is to hide the WebView until the user has done interacting with the controls and the elements that are placed over it.

In my case, I needed to hide the WebView every time the Settings panel was displayed and to show it back as soon as the Settings panel was closed. Since there’s no way, within a Windows Store apps, to know when the charm bar is activated, we have to find another approach: by managing the page’s focus.

The page exposes two events, LostFocus and GotFocus: the first one is invoked when the current page lost its focus (because, for example, the user is interacting with the settings flyout), the second one instead when the focus is reassigned to the app.

You can subscribe to these two events in the XAML and, more precisely, in the page’s declaration, like in the following example:

<common:LayoutAwarePage
    x:Name="pageRoot"
    x:Class="qmatteoq.com.Views.DetailPage"
    LostFocus="pageRoot_LostFocus" GotFocus="pageRoot_GotFocus">

Once you’ve done it, you can mange these events in the code behind. In my case I simply change the WebView’s control (which, in my app, is called PostDetail) visibility according to the focus:

private void pageRoot_LostFocus(object sender, RoutedEventArgs e)
{
    PostDetail.Visibility = Visibility.Collapsed;
}

private void pageRoot_GotFocus(object sender, RoutedEventArgs e)
{
    PostDetail.Visibility = Visibility.Visible;
}

And here is the final result: when the settings panel is opened the WebView is hided. Plus, I’ve added a message to notify the user that the post is just hidden and that will reappear when the settings panel will be closed.

image

Posted in Windows 8 | Tagged | 2 Comments

Nokia Premium Developer Program

Nokia has recently announced a new initiative for Windows Phone developer that is really interesting. At the same price of a standard Windows Phone account for developers (which is 99 $) you will have access to the following benefits:

  • A token to subscribe for one year to the Windows Phone Dev Center, so that you can publish your apps and unlock up to 3 devices. The token can be used to register for the first time or to renew an existing subscription.
  • A license for the Windows Phone suite by Telerik, that offers many useful and powerful controls.
  • A one year subscription to Buddy.com, that offers many cloud services that can be integrated into a Windows Phone application to manage push notifications, authentication or real time messaging. With these services developer will just have to configure and connect to these services (using standard protocols), without bothering about developing and maintaining them. Buddy.com offers different subscriptions plans: the one included in the Nokia offer allows you to make up to 1 million of API calls per month.
  • 2 tickets to ask support to Nokia if you have problems while developing your application.

The total value of these benefits is 1500 $: if you’re thinking about subscribing to the Store or you have an existing subscription that you want to renew, you don’t want to miss this chance!

You’ll find all the information and the link to purchase the offer in this page of the Nokia Developer portal.

Posted in Windows Phone | Tagged , | Leave a comment

A lap around Windows Phone 8 SDK: file association – Part 2

In the previous post we started to take a deep look to one of the most interesting new features in Windows Phone 8: file association. The example we’re using in this tutorial is made by two applications: in the last post we’ve created the “launcher” app, that generates a text file and tries to open it. In this post, instead, we’re going to create the “reader” app, that will receive the file from the launcher app and will open and display it.

The “reader” app: how to register for a file extensions

Let’s start to create the reader application: create a new Windows Phone 8 project (you can just use the basic Windows Phone App template) and let’s edit the manifest file. Unlucky, as I’ve already mentioned in the post I wrote with a summary of all the new Windows Phone 8 features, the new visual editor is not perfect and it doesn’t support all the scenarios: to register the file extensions we’ll need to manually edit the file, so you have to right click on the WMAppManifest.xml file into the Properties folder and choose View code.

File and protocol associations are registered in the Extensions section: in case it’s missing, you have to manually add it below the Tokens section. Here is how we register the .log extension:

      <FileTypeAssociation Name="LogFile" TaskID="_default" NavUriFragment="fileToken=%s">
        <SupportedFileTypes>
          <FileType ContentType="text/plain">.log</FileType>
        </SupportedFileTypes>
      </FileTypeAssociation>

Every file type association is identified by a FileTypeAssociation node, with a unique Name property. The attributes TaskID and NavUriFragment defines how the file is passed: these two values are fixed and can’t be changed, they should always be exactly like you see in the code example.

Inside this node you can specify the file types you’re going to support, by adding a FileType node with the correct content type and extension. You have also the option to include a logo that identifies the custom file type, that is displayed by the operating system when needed (for example, near the file name of an attachment inside the Mail application). In this case, you have to create three different images (with size 33×33, 69×69 and 176×176), add them to your project and include them in the FileTypeAssociation definition, like in the following example:

 <FileTypeAssociation Name="LogFile" TaskID="_default" NavUriFragment="fileToken=%s">
<Logos>
           <Logo Size="Small">log-33x33.png</Logo>
           <Logo Size="Medium">log-69x69.png</Logo>
           <Logo Size="Large">log-176x176.png</Logo>
       </Logos>
        <SupportedFileTypes>
          <FileType ContentType="text/plain">.log</FileType>
        </SupportedFileTypes>
      </FileTypeAssociation>

Once you’ve registered your application it’s time to write some code. There are two steps here: to define a UriMapper and to create a page that will handle the received file.

The UriMapper

Before talking about the UriMapper, it’s better to explain how the OS handles file association. When an application is launched as a consequence of a file request (in our example, another application is trying to open a .log file), it’s opened using a special Uri that has the following structure:

/FileTypeAssociation?fileToken=89819279-4fe0-4531-9f57-d633f0949a19

After the fixed keyword FileTypeAssociation there’s a unique parameter called fileToken, which is a GUID that identifies the file. As we’ll see later, Windows Phone 8 exposes an API to get the file using this token.

Now that you have understood how file association works under the hood, it should be easy to understand what is the UriMapper class: basically, it’s a central class that gets called when the application is started and it’s able to check if the app was called using a special Uri so that it can redirect the user to a specific page of the application.

In our case, we’re going to check if the app was opened since another application has requested to open a log file: if the answer is yes, we’re going to redirect the user to a specific detail page, where the log will be displayed. Here is the code:

    public class UriMapper : UriMapperBase
    {
        private string tempUri;

        public override Uri MapUri(Uri uri)
        {
            tempUri = uri.ToString();

            // File association launch
            if (tempUri.Contains("/FileTypeAssociation"))
            {
                // Get the file ID (after "fileToken=").
                int fileIDIndex = tempUri.IndexOf("fileToken=") + 10;
                string fileID = tempUri.Substring(fileIDIndex);

                // Get the file name.
                string incomingFileName =
                    SharedStorageAccessManager.GetSharedFileName(fileID);

                // Get the file extension.
                int extensionIndex = incomingFileName.LastIndexOf('.') + 1;
                string incomingFileType =
                    incomingFileName.Substring(extensionIndex).ToLower();

                // Map the .log files to the appropriate pages.
                switch (incomingFileType)
                {
                    case "log":
                        return new Uri("/LogDetail.xaml?fileToken=" + fileID, UriKind.Relative);
                    default:
                        return new Uri("/MainPage.xaml", UriKind.Relative);
                }

            }
            // Otherwise perform normal launch.
            return uri;
        }
    }

First you have to create a new class in your project, that should inherit from the UriMapperBase class. This way you’ll have to implement the MapUri method, that is called when the application is initialized and that carries, as a parameter, the Url.

If the Url contains the FileTypeAssociation string the app is opened after that another application has requested to open a file: in this case we get the token of the file by simply playing with string properties (since FileTypeAssociation and fileToken are always fixed). After that, let’s welcome the SharedStoreAccessManager, which is the class that is able to handle operations with files that are opened this way: for this scenario we’ll use just the GetSharedFileName method that, passing the token, returns the name of the file as it was defined by the original application.

Using the name, and using some other strings voodoo magic, we finally get the information we need: the extension of the file. This way we’re able to identify the file type and we’re able to redirect the user to the page that is able to process that kind of file. In our example we manage just the .log extension, so the switch statement contains just two entries: the log extension and the default, which is a redirect to the MainPage of the application.

In case we receive a log file, we redirect the user to a specific page called LogDetail.xaml and we attach the token to the Uri: as we’ll see in a few moments, the token will be needed to get the real file.

The last thing we have to do is to tell the application that we have a UriMapper, that should be parsed every time a navigation is issued: to do this we have to go in the App.xaml.cs and, in the InitializePhoneApplication() method, right after the RootFrame has been initialized, set the UriMapper property to the class we have created, like in the following example:

private void InitializePhoneApplication()
{
    if (phoneApplicationInitialized)
        return;

    // Create the frame but don't set it as RootVisual yet; this allows the splash
    // screen to remain active until the application is ready to render.
    RootFrame = new PhoneApplicationFrame();
    RootFrame.Navigated += CompleteInitializePhoneApplication;
    RootFrame.UriMapper = new Helpers.UriMapper();

    // Handle navigation failures
    RootFrame.NavigationFailed += RootFrame_NavigationFailed;

    // Handle reset requests for clearing the backstack
    RootFrame.Navigated += CheckForResetNavigation;

    // Ensure we don't initialize again
    phoneApplicationInitialized = true;
}

Let’s get this file!

Now it’s time to create the LogDetail.xaml page, that we’re going to use to display the content of the file. Add a new empty Windows Phone page to the application and give it the name LogDetail.xaml: in the code behind we’re going to manage the OnNavigatedTo event, that is invoked when the user navigates towards this page.

In this event we’re going to get the file token and use it to get the real file that has been “sent” by the other application. Here is the code:

        protected override async void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            if (NavigationContext.QueryString.ContainsKey("fileToken"))
            {
                await SharedStorageAccessManager.CopySharedFileAsync(ApplicationData.Current.LocalFolder, "rss.log",
                                                               NameCollisionOption.ReplaceExisting,
                                                               NavigationContext.QueryString["fileToken"]);

            }
        }

The mechanism should be familiar if you’re a Windows Phone developer, since it’s similar to the one adopted by the OS for other scenarios (like navigation from a secondary tile): if the NavigationContext contains a query string parameter which name is fileToken we’re going to use again the SharedStorageAccessManager class and, this time, specifically the CopySharedFileAsync.

This method simply translates the token into a real file and copies it into the local storage of the current application. The requested parameter are:

  • The folder in the storage where to save the file, identified by a StorageFolder object. In the example we simply pass the LocalFolderobject: this way the file is copied into the root of the storage.
  • The name of the file to save.
  • What to do in case the file already exists (in the example, we overwrite it).
  • The file token (that we retrieve from the query string parameter)

Once we have the file in our storage, we can simply do whatever we want. For example, we can read it as a string and display it in a TextBlock using the following ReadFromFile extension method:

public static class FileExtensions
{
    public static async Task<string> ReadFromFile(string fileName,StorageFolder folder = null)
    {
        folder = folder ?? ApplicationData.Current.LocalFolder;
        var file = await folder.GetFileAsync(fileName);

        using (var fs = await file.OpenAsync(FileAccessMode.Read))
        {
            using (var inStream = fs.GetInputStreamAt(0))
            {
                using (var reader = new DataReader(inStream))
                {
                    await reader.LoadAsync((uint)fs.Size);
                    string data = reader.ReadString((uint)fs.Size);
                    reader.DetachStream();
                    return data;
                }
            }
        }
    }
}

Now, thanks to this extension method, in the OnNavigatedTo event of the LogDetail page we can do something like this:

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    if (NavigationContext.QueryString.ContainsKey("fileToken"))
    {
        SharedStorageAccessManager.CopySharedFileAsync(ApplicationData.Current.LocalFolder, "rss.log",
                                                       NameCollisionOption.ReplaceExisting,
                                                       NavigationContext.QueryString["fileToken"]);

        string content = await FileExtensions.ReadFromFile("rss.log");
        log.Text = content;
    }
}

It’s debugging time!

Debugging this scenario is very easy: just deploy both applications in the emulator or in the device (by right clicking on the two projects and choosing Deploy from the menu). Then execute the launcher app we’ve developed in the previous post, create the log file and then launch it using the Open file button. If you did everything correctly, you’ll see the reader application open up directly in the LogDetail, with the content of the RSS that has been downloaded by the launcher app.

How cool is that? Smile

You can download a sample project from here.

Posted in Windows Phone | Tagged | 2 Comments