In the Managing app lifecycle post, Adam Barrus described the new app lifecycle introduced in Windows 8. The most common question we hear is “what if my app has to do something important when it is not on screen, for example, download a file or email or play music”? In this two part series, I’ll tell you about the different types of activities that an app can do when it’s in the background and show some code examples to that support these scenarios.

Windows 8 background model

Efficient battery usage has been one of the fundamental building blocks in the design of Windows 8 and its app model. Pat Stemen’s post on the Building Windows 8 blog goes in depth into why this is such an important factor in the design of Windows 8 and describes some of the techniques that we’ve incorporated in the system for increased battery life. As you can imagine, one of the biggest factors that determine the battery life of a device is the apps that run on them. And with this in mind, we designed the Windows 8 app lifecycle for maximum battery life. But that doesn’t mean the app model precludes background activities. This post explains the background scenarios supported in Windows 8. For more info about this approach, see Ben Srour’s and Sharif Farag’s post Improving power efficiency for applications on the Building Windows 8 blog.

To design the background model of Windows 8, we identified the typical scenarios you want an app in the background to perform and added APIs that accomplish this power efficiently. These are the scenarios Windows 8 supports (also defined in the improving power efficiency post):

Scenario

Description

Background download or upload

Apps can use the background transfer API to upload and download data in the background. The OS itself performs the upload or download here, which takes the app code out of the picture, and helps maximize battery life.

Background audio

We definitely want you to be able to listen to music in the background. Any media or communications app can play audio in the background. To maximize system and power efficiency, we suspend the app when the user pauses the audio.

Sharing

If your app is sending content to a cloud service using the Share charm, that operation completes in the background. More info about transferring data during a Share operation is available on the Dev Center.

Device sync

You can synchronize content between a connected device (like a camera) and your PC even though the app is not visible on screen.

Live tiles

Apps can display the latest content on their tiles (even if they are suspended) by sending push notifications to your Windows 8 PC. More info in the post Creating a great tile experience.

Scheduled notifications

Apps can notify you of an event at a particular time by either updating a tile (like calendar appointments) or by popping a notification. The app schedules these events, but Windows is responsible for delivering the notification, which helps minimize battery impact. More info is on the Dev Center.

Background tasks

If a suspended app must run its own code to provide functionality, Windows 8 provides you with the ability to create background tasks. These background tasks run in response to external triggers (like time or system events or incoming push notification) and have resource constraints imposed on them to make it easy to perform background activity in a power-friendly manner. The most common examples of apps that use them are email, VoIP, and IM apps. These apps can sync your data, in the background while on battery, or in Connected Standby mode. These will be described in the next post in this series.

Now let’s show you how to implement some common scenarios in Metro style apps. We also go in depth into some of the technical details of these features and explain some of their finer points.

The scenarios that we describe in this series are listed here. The first two items are described in this post while the last two scenarios will be described in our next post.

  • Background download or upload
  • Background audio
  • Background tasks – Doing work in the background when the device is on AC power
  • Background tasks – Downloading mail from a POP3 mail server every 15 minutes

Now let’s dive into the code and see how simple it is to get this done on Windows 8. The sample code included here is intended to be examples and not complete code samples in all aspects; for example, we don’t cover error handling.

Background download or upload

Transferring content (such as uploading photos, downloading videos or music) is a common scenario for many apps. The BackgroundTransfer namespace provides a simple and rich API that you can use for transferring data both in the foreground and background. The API does a lot of the hard work for you, so you can focus on what your app does best. It’s optimized for power efficiency, is resilient to network glitches, and is network cost aware. Let’s look at a specific example: how to download a file using BackgroundTransfer.

BackgroundDownloader is the main class that lets you accomplish most of the background download or upload scenarios. The below example demonstrates creating a new DownloadOperation object using the BackgroundDownloader class, which takes in a source URI and a destination file. With the download configured, HandleDownloadAsync is called to kick off the download. In the JavaScript example, we start the download inline without calling another function.

JavaScript

function downloadFile(uri, destinationFile) 
{
// Create a new download operation.
download = downloader.createDownload(uri, newFile);
// Start the download and persist the promise to be able to cancel the download.
promise = download.startAsync().then(complete, error, progress);
}
                

C#

private async void DownloadFile(Uri source, StorageFile destinationFile)
{
BackgroundDownloader downloader = new BackgroundDownloader();
DownloadOperation download = downloader.CreateDownload(source, destinationFile);

// Attach progress and completion handlers.
await HandleDownloadAsync(download, true);
}
             

This code example demonstrates attaching handlers to a new DownloadOperation before calling StartAsync to actually initiate the download. This same method is also used to re-attach your handlers by calling AttachAsync when enumerating download operations as explained below.

C#

private async Task HandleDownloadAsync(DownloadOperation download, bool start)
{
// Create progress callback
Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress);
// Create cancellation token
CancellationTokenSource cts = new CancellationTokenSource();

if (start)
{
// Start the download and attach a progress handler.
await download.StartAsync().AsTask(cts.Token, progressCallback);
}
else
{
// The download was scheduled in a previous session, re-attach the progress handler.
await download.AttachAsync().AsTask(cts.Token, progressCallback);
}
}


After an app starts a background download operation, even if it gets suspended, these download operations continue in the background. The next time your app is resumed, you will receive the progress and completion callbacks of these download operations. If your app was terminated after being suspended, enumerating your download operations will restart previously queued background download operations. These next code examples show you how to enumerate your download operations in C# and JavaScript.

C#

// Enumerate downloads that were running in the background before the app was closed.
private async Task DiscoverActiveDownloadsAsync()
{
activeDownloads = new List<DownloadOperation>();

// Get all current download operations
IReadOnlyList<DownloadOperation> downloads = await BackgroundDownloader.GetCurrentDownloadsAsync();

if (downloads.Count > 0)
{
List<Task> tasks = new List<Task>();
foreach (DownloadOperation download in downloads)
{
// Attach progress and completion handlers.
tasks.Add(HandleDownloadAsync(download, false));
}

await Task.WhenAll(tasks);
}
}
               
JavaScript
function discoverActiveDownloads() 
{
// Enumerate outstanding downloads.
Windows.Networking.BackgroundTransfer.BackgroundDownloader.getCurrentDownloadsAsync().done
(function (downloads) {
// If downloads from previous app state exist, reassign callbacks and persist to global array.
for (var i = 0; i < downloads.size; i++) {
download[i].attachAsync().then(complete, error, progress);
}
}
}

Download and upload operations are subject to the same resource constrains as other background tasks explained in the next post in this series. To learn more about BackgroundTransfer, see the overview of transferring data in the background, API namespace, Background transfer download sample, or watch //BUILD session Making apps social and connected with HTTP services.

Background audio

In Windows 8, we made it really easy for you to develop an app that plays audio in a simple and power efficient manner. Windows 8 provides system level controls that are designed to improve the user experience within the MediaControl class, using stream categorization, and media transport controls. In this section, we look at how to make your app play audio in the background. We don’t go into details about actually playing audio or the Media Control classes. For more info about the audio technologies, see the Audio playback in a Metro style app white paper.

There are three important requirements that the app must meet to play audio in the background:

  • A background audio declaration must be in the app manifest.
  • You must set the stream category (msAudioCategory) to either Communications or BackgroundCapableMedia.
  • Your app must register for media transport controls.

To add the background audio declaration to your app, simply open your app’s manifest in Visual Studio. On the Declarations tab, pick Background Tasks from the declaration drop down and add that to manifest. From supported task types, select Audio and specify the Start page of your JavaScript app or specify the Entry point if your app is C# or C++ or VB.

Manifest declarations in Visual Studio

The easiest method to play audio in an app is through the HTML5 <audio> element. Adding a msAudioCategory attribute in your <audio> element allows the system to optimize performance and improve the user experience for your application’s audio. For example, it allows utilizing low power playback mechanisms when possible, allowing certain sounds to play while the application is in the background, or in some cases decreasing the volume or muting certain sounds to ensure other sounds are clearly heard.

This is sample HTML code to play audio and set its audio category appropriately.

<audio msAudioCategory="BackgroundCapableMedia" controls="controls"> 
<source src="song.mp3"/>
</audio>

Here is JavaScript code to perform the same functionality. You must set the msAudioCategory attribute before you set the source element, otherwise the system won’t see the audio category.

JavaScript
function PlayAudio () 
{
// Create new audio tag for "BackgroundCapableMedia" class
if(!audtag)
{
audtag = document.createElement('audio');
audtag.setAttribute("id", "audtag");
audtag.setAttribute("controls", "true");
audtag.setAttribute("msAudioCategory", "backgroundcapablemedia");
audtag.setAttribute("src", "song.mp3");
document.getElementById("scenario1Output").appendChild(audtag);
audtag.load();
}
}
        

This is a C# code example to set the audio category on an output audio stream. The function SelectFile is used to select a file using FileOpenPicker and then you set the AudioCategory on the selected stream by calling SetAudioCategory.

C#
public async void SelectFile()
{
// Choose file using the picker
Windows.Storage.Pickers.FileOpenPicker picker = new Windows.Storage.Pickers.FileOpenPicker();
picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.MusicLibrary;

// Add a filter so only mp3 files are displayed
picker.FileTypeFilter.Add(".mp3");
Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();
if (file != null)
{
var stream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
OutputMedia.AutoPlay = false;

// Run on the UI thread because it updates UI controls
await cw.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
OutputMedia.SetSource(stream, file.ContentType);
});
}
}

// Set the audio category on the output stream
public void SetAudioCategory(AudioCategory category)
{
OutputMedia.AudioCategory = category;
}
      

There are two audio categories that are background capable (meaning, they allow your app to play audio in the background): BackgroundCapableMedia and Communications. Depending on the type of audio stream being played, choose the appropriate audio category, so that the system can choose the best performance characteristics for your audio stream.

Audio stream type

Description

BackgroundCapableMedia

For audio that needs to continue playing in the background. Examples include:

· Local media playback:

· Local playlist

· Streaming radio

· Streaming playlist

· Music videos

· Streaming audio/radio, YouTube, Netflix, and so on

Communications

For audio streaming communication audio such as:

· Voice over IP (VoIP)

· Real-time chat or other type of phone call

A Windows 8 Metro style app is full screen, which means that if a user of your app is listening to music in the background, there is no quick way to stop the music without registering for the transport controls. The system transport controls appear on-screen, if the app has registered for them and the user presses one of the hardware volume buttons. For more info about how to add media transport controls to your Metro style app, see System Transport Controls Developer Guide.

And that’s it. Your app can now play audio in the background without being suspended. But because playing audio in the background leaves the app active, you have a responsibility to ensure that your app doesn’t eat up system performance or battery life. As soon as your app stops playing audio, Windows will suspend it. More detailed info is in the Audio playback in a Metro style app white paper.

Summary

With this, we finish the first part of our series on how to be productive in the background. In this post, you learned how to play audio in the background and perform uploads or downloads in the background while your app is suspended. In the next part, you learn how to write your own code to provide functionality in the background while your app is suspended, using background tasks.

-- Hari Pulapaka
    Program Manager, Windows

Resources

Link

Type

Highlights

Transferring data in the background

Quick start

Conceptual documentation on background transfer

API namespace

API Docs

Background transfer API namespace

Background transfer download sample

Sample Project

Sample app demonstrating usage of background transfer API

Making apps social and connected with HTTP services

//BUILD session

//BUILD session describing the how to build connected apps

Audio playback in a Metro style app

White paper

Whitepaper on how to play audio in the background

System Transport Controls Developer Guide

White paper

Whitepaper on using media transport controls to develop music applications

API namespace

API Docs

Basic media support APIs