Porting a Windows Phone 8.0 Silverlight app to Windows Phone 8.1 Universal app - Background Transfers

Another major thing to port is the BackgroundTransfer stuff in the P | Cast app. Although the API is similar there was a lot of code that I needed to port, though a lot of this code could be deleted as well.

Starting a BackgroundTransfer

Let’s start with the easy part. We want to start a BackgroundTransfer. We are no longer bound to save the files to /Shared/Transfers which was required in Windows Phone 8.0, which makes it all much easier. Actually I think we can even download directly to a SD-card if we would like. We just create a StorageFile where we want to store the file to download. We create an instance of a BackgroundDownloader and use that to create a DownloadOperation out of the RequestUri and the StorageFile. Then we construct a CancellationTokenSource which we can use to cancel the download operation. We also construct a Progress feedback delegate. We end by starting the operation and attaching the CancellationToken and the Progress delegate.

Uri requestUri = new Uri("http://someurl.com/largefile", UriKind.RelativeOrAbsolute);

StorageFile downloadTo = await ApplicationData.Current.LocalFolder
var cts = new CancellationTokenSource(); 
BackgroundDownloader downloader = new BackgroundDownloader { Method = "GET" };
DownloadOperation operation = downloader.CreateDownload(requestUri, downloadTo);

Progress<DownloadOperation> downloadProgress = new Progress<DownloadOperation>(DownloadProgress);
await operation.StartAsync().AsTask(cts.Token, downloadProgress);

Getting a bit of feedback from the DownloadOperation

We already attached a Progress handler in the previous section. The implementation depends on what you want to do with it. Just a small example of what I used during testing.

private void DownloadProgress(DownloadOperation operation)
    Debug.WriteLine("Download: {0}: {1:P2}",
        operation.Progress.BytesReceived * 1.0 / operation.Progress.TotalBytesToReceive);


Of course we don’t only want feedback on newly created DownloadOperations but also on stuff we created in a previous app-run but which didn’t complete yet. We can easily get all the CurrentDownloads via the BackgroundDownloader. We also construct a CancellationTokenSource and a Progress delegate. We use AttachAsync to attach the Progress delegate and the CancellationTokenSource to the existing DownloadOperation.

var currentTransfers = await BackgroundDownloader.GetCurrentDownloadsAsync();

var cts = new CancellationTokenSource();
Progress<DownloadOperation> downloadProgress = new Progress<DownloadOperation>(DownloadProgress);

foreach (var currentTransfer in currentTransfers)
    await currentTransfer.AttachAsync().AsTask(cts.Token, downloadProgress);

How do I cancel that DownloadOperation?

I was trying to port the code by just using the code intellisense, but I couldn’t find a way to cancel a specific BackgroundTransfer. In the end I found something, but for comparison first the Windows Phone 8.0 method to cancel a backgroundtransfer.



The explanation of Microsoft: “Because BT is based on the BackgroundTask infrastructure, you cancel a transfer simply by canceling the task”. Sounds nice, but the amount of code is much more than you expect.

public static class DownloadOperationExtensions
    public static async Task CancelAsync(this DownloadOperation operation)
        var cts = new CancellationTokenSource();
        await operation.AttachAsync().AsTask(cts.Token);



In Windows Phone 8.0 we explicitly had to remove the completed downloads from the BackgroundTransfer queue, I couldn’t find anything pointing towards this requirement on Universal apps. So I tried doing BackgroundTransfers without explicitly removing them. And my conclusion is, you don’t need to explicitly remove them from the queue. When the transfer completed without the app running it will be in the queue the first time you start the app again. So you can handle it.

Handling very large files and how to read the different policies

One of the things you had to be aware of was even though you want to allow downloading while running on a battery this wasn’t allowed for files over 100MB. I handled this by trying to download it on battery and check if the TransferError.Message was “The transfer file size is bigger than the allowed limit”. The new BackgroundTransfer API handles this automatically.

In the old API you could set policies that were pretty simple, there were combinations of Allow Cellular and Allowing Battery. You can no longer set policies around the battery because those are handled automatically. Now you can set a policy to UnrestrictedOnly, Default and Always. This is something that needs a bit of clarification with scenario’s I found here.


Unrestricted Only

Default Always
Wi-Fi Allow Allow Allow
Metered connection, not roaming, under data limit, on track to stay under limit Deny Allow Allow
Metered connection, not roaming, under data limit, on track to exceed limit Deny Deny Allow
Metered connection, roaming, under data limit Deny Deny Allow
Metered connection, over data limit. This state only occurs when the user enables “Restrict background data in the Data Sense UI. Deny Deny Deny


Transfer Status

The possible statuses of the Transfer has changed. I tried to map them like below. You can read the details of the original TransferStatus and the new BackgroundTransferStatus if you want to know more.

TransferStatus (8.0) BackgroundTransferStatus (8.1)
Transferring Running
None / Waiting Idle
WaitingForWifi PausedCostedNetwork
Paused PausedByApplication
Completed Completed


One of the things I noticed is the grouping of the TransferStatus.WaitingForX that I couldn’t map directly but are all captured within the BackgroundTransferStatus.PausedBySystemPolicy.

We do see a status Completed in the enum, but in practice I have never seen this status. Even when the transfer is actually completed, based on the BytesReceived is equal to TotalBytesToReceive. This is for both Windows and Windows Phone, so status is still Running but all bytes are already received.

Calculate Progress

Things have been moved around a bit, but calculating progress is still easy to do. So my previous code on Windows Phone 8.0.

private double CalculateProgress(BackgroundTransferRequest request)
    if (request.TotalBytesToReceive == 0)
        return 0.0;
    return request.BytesReceived*1.0/request.TotalBytesToReceive;

Is easily rewritten to Windows Phone 8.1.

private double CalculateProgress(DownloadOperation request)
    if (request.Progress.TotalBytesToReceive == 0)
        return 0.0;
    return request.Progress.BytesReceived * 1.0 / request.Progress.TotalBytesToReceive;

Background Transfer Queue

The old BackgroundTransferService had a hard limit of 25 active and pending download requests per application. This caused any app to manage it’s queue. This limit doesn’t exist in the new Background Transfer API, it has a system limit of 1000 however. Nice, no longer managing the queue myself!

Background Transfer behaviors

There’s an important difference between the behavior of background transfers within Windows and Windows Phone. When the Windows Universal app is terminated the background transfers will be terminated as well. This is different from what we are used to within Windows Phone, where the background transfers continue without the app running.

Porting a Windows Phone 8.0 Silverlight app to Windows Phone 8.1 Universal app - Database / SQLite

Two weeks ago I wrote about the preparation of porting my P | Cast app to Windows Phone 8.1 Universal.

After this I started investigating if I would be able to port my database including the data access code.

Prepare the Windows Phone project

So of course we need to have the SQLite database engine for Windows Phone 8.1. So download this Visual Studio Extensions: SQLite for Windows Phone 8.1. Now it’s time to add a reference to the SQLite engine on the Windows Phone project. It will also add a reference to the Microsoft.VCLibs.

While in the past a special C++ project would have to be added to your Windows Phone 8.0 solution, this is much easier.


Prepare the Windows Project

While I’m still not sure if the Windows version of P | Cast will ever see the light, I want to know if my code is compatible. So I downloaded the Visual Studio Extension: SQLite for Windows Runtime (windows 8.1). So this time add a reference to the SQLite engine on the Windows project.


Time for some Data Access

As always I try to decouple the data access from the UI. It’s a best practice I always try to follow. Nowadays we have Portable Class Libraries so I add a new PCL project to the solution.


I reference this project from both the Windows Phone and the Windows project.

Next I add the same NuGet package I’m used to use in the P | Cast app, called sqlite-net.

Everything compiles, time to migrate code. First I took the code from a table definition. Actually I copied all of my table definition classes, but for this article I’ll show the Subscription definition.

public class Subscription
    [AutoIncrement, PrimaryKey]
    public int Id { get; set; }

    public string Uri { get; set; }

    public string Title { get; set; }
    public string Description { get; set; }
    public string Copyright { get; set; }
    public string ArtUri { get; set; }

    public string ExternalId { get; set; }
    public DateTime LastUpdated { get; set; }


So I tried to do actually create the database, insert data and query the data. I called the below method from the OnLaunched.

private async void TryDatabaseStuff()
    var connection = new SQLiteAsyncConnection(Path.Combine(ApplicationData.Current.LocalFolder.Path, "podcasts.db"));
    await connection.CreateTablesAsync<Subscription, Track>();

    await connection.InsertAsync(new Subscription { Uri = "http://hanselminutes.com/subscribe" });
    Debug.Assert(await connection.Table<Subscription>().CountAsync() > 0);


So to assure you, all this code works like a charm on both Windows Phone and Windows. Now it’s time to migrate some more parts.

Porting a Windows Phone 8.0 Silverlight app to Windows Phone 8.1 Universal app - Preparation

As many of you readers probably know, I wrote a Podcast app called P | Cast. I did this in the early days of Windows Phone 8.0 because it lacked an internal podcast player (for most regions), and all the alternatives from the store weren’t working for me at that moment.

But then came Windows Phone 8.1, it included a podcast player, again. I thought this would be the death of my app. But it isn’t at least it isn’t for myself, I don’t like the internal podcast player that much. So I can of course expand P | Cast to become better, but one of the most requested features, modify playbackspeed, can’t be done on the Windows Phone 8.0 model. Time to port the P | Cast app to Windows Phone 8.1 Universal app. Not an easy task though.

User Interface

Yes both User Interfaces are in Xaml, but there are significant differences, in the controls that are available and also their richness. I’m currently using the Telerik UI for Windows Phone controls. They work perfectly right now, but I can’t use them on an universal app, and their Telerik UI for Windows Universal isn’t as rich as their Windows Phone counter part yet. On the other the current xaml can probably be a good base to start with.

Background Audio

In the Windows Phone 8.0 timeframe, all you have is a Background Audio Agent. There were a lot little quirks in the events that are or aren’t called in the Background Audio Agent. I had to do a lot to make sure track progress could be saved. Hope we don’t have to worry about that anymore. Even using NamedEvents to make sure the BackgroundAudio could somehow communicate with the UI.

The background audio architecture has changed a lot. It changed so much actually that I’m sure I will have to redo all the audio code. But all will come with a very interesting feature: the ability to change the playbackrate. So in a new version we will finally be able to play podcasts at 1.5 speed or 2.0 speed if you would like to.

Background Transfers

Because the sizes of podcasts can be very large I used the BackgroundTransferService to make sure the OS handles all the issues of resuming of transfers and even keep downloading if the app isn’t running in the foreground. Universal apps have a different API for handling Background Transfers which are very similar but have some differences in limitations it seems. I hope they can be started from a background task, which couldn’t be done on Windows Phone 8.0.

Background Processing

P | Cast includes a background agent which is responsible for syncing all podcast feeds and eventually clean up of played podcasts. When the phone is plugged in for charging an even more intense version of the background agent launches which will do background downloading of podcasts. Although the Background Task API is different for Universal apps, the concepts are similar. Just Run code on the background!


All meta-data of the podcasts is stored in a SQLite database. I know you have to do something different to actually use SQLite in the app, but I hope I can still use SQLite-Net library to access the database.

Posted: Porting a Windows Phone 8.0 Silverlight app to Windows Phone 8.1 Universal app - Database / SQLite

Windows 8 app?

Yes the big question is of course, will there also be a Windows 8 app? Maybe there will be, there’s a lot of code that can be shared in Universal Apps. A new UI design will be required for a Windows 8 app of course. And every user would expect the Windows Phone and Windows apps to be in sync, always. That would require some additional thinking for me. Because I have no idea on how to do that, yet.

What’s next?

So I will write blogposts for each of the above mentioned things. I will explain what I needed to do to implement the different parts, and if possible if I could reuse code or not. If you have any tips for me, please share them in the comments.

Windows Store Apps, Error: The certificate specified has expired.

Today I tried to update one of my Windows Store Apps. When I tried to create an App Package for the Store I got an error. One that was completely new to me.

The certificate specified has expired. For more information about renewing certificates, see http://go.microsoft.com/fwlink/?LinkID=241478.

We’re lucky this time, renewing the certificate is very easy. Just follow below steps (copied from MSDN).

  1. In Solution Explorer, open the shortcut menu for the .appxmanifest file, choose Open With, and then choose App Manifest Designer.
  2. In the App Manifest Designer, choose the Packaging tab, and then choose the Choose Certificate button.
  3. In the Choose Certificate dialog box, expand the Configure Certificate list, and then choose Create test certificate.
  4. In the Create test certificate dialog box, click the OK button.

In the end Visual Studio will generate the new certificate with a new expiry date. The new certificate will be valid for a full year.

A small tale of bringing push notifications to Windows Azure

Some time ago I got more and more problems on my shared hosting because it couldn’t handle the amount of push notifications I wanted to send. I heard my hosting provider tell me that I was quite often taking more than 90% of the CPU on the server. So I thought to give Windows Azure a try.

I wanted to make optimal use of Windows Azure so I designed my solution to make use of Windows Azure Table Storage to store registered devices and pushchannels. When making use of Azure Table Storage it’s important to choose your RowKey and PartitionKey carefully.

To start with the PartitionKey, I chose to put the ApplicationName in there. I want to send push notifications to different applications I created, like Fokke & Sukke and iBood. So far I haven’t found a reason I made a wrong decision.

And now the RowKey, something that I need to use more carefully. The combination of PartitionKey and RowKey needs to be unique. So I wanted to put the DeviceId of the Device that should receive the PushNotification in there, that combined with the platform identifier. As far as I know there’s nothing that guarantees that the DeviceId is unqiue over different platforms. So I prefix the DeviceId with “WP|” for Windows Phone and “RT|” for Windows 8. The rest was just the copy of the DeviceId. I tested this using the emulator, and everything seems to work fine.

Windows Phone app trouble

After a while I notices reviews telling me that Push Notification don’t work, even further, it didn’t work on my own Windows Phone. After searching for many different reasons for this trouble, I found the source, more or less.

When saving an entity to the Azure Table Storage, every now and then a StorageException occurred. There aren’t many details in the exception, so after attaching Fiddler to my Nokia Lumia 920, I saw interesting stuff happening on the line.

The DeviceId contained special characters. I didn’t notice this when using the emulator, because the DeviceId on the emulator didn’t contain any special characters. So in total I had a percentage of users that could never register because of the StorageException, I still have no idea how large that percentage is, DeviceIds at least regularly contain the ‘/’ character.

Lesson learned, make sure the RowKey and PartitionKey don’t contain special characters: /, \, #, ?

Windows Style app trouble

Besides the Windows Phone issues, I had a very strange behavior on Windows 8 as well. It happened that I was sending a push notification to my local (installed through Visual Studio) app that did not appear. For example I sent a BadgeNotification with value 1 and sometimes the value 17 appeared. I have been trying to find the reason behind it, I never found it. Because when I tried to debug it explicitly with a value like 4 it did show 4. I never got feedback about issues with the push notifications on Windows 8 since my move to Windows Azure, but my dev-machine had troubles.

So after a couple of weeks trying to find causes for the problem I did something that was my final call. I did uninstall the app, and installed the app from the Store. What happened? The pushnotifications started behaving correctly. I have no understanding about the differences between the apps, but it’s good to be aware that there seem to be differences between the app installed from the store and the app installed by Visual Studio.