Being productive when your app is offscreen

AWS

Owner
FPCH Owner
Joined
Nov 19, 2003
Messages
10,976
Location
Florida U.S.A.
In the Windows 8 background model[/size]
Efficient battery usage has been one of the fundamental building blocks in the design of Windows 8 and its app model. Pat Stemens [url=http://blogs.msdn.com/b/b8/archive/2011/11/08/building-a-power-smart-general-purpose-windows.aspx" target="_blank">post</a> 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 weve 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 doesnt 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 Srours and Sharif Farags post [url=http://blogs.msdn.com/b/b8/archive/2012/02/07/improving-power-efficiency-for-applications.aspx" target="_blank">Improving power efficiency for applications</a> 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):


<tbody>


Scenario


Description




[b]Background download or upload[/b]


Apps can use the [url=http://msdn.microsoft.com/en-us/library/windows/apps/br207242%28v=VS.85%29.aspx" target="_blank">background transfer API</a> 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.




[b]Background audio[/b]


We definitely want you to be able to listen to music in the background. Any media or communications app can play [url=http://channel9.msdn.com/Events/BUILD/BUILD2011/PLAT-776T" target="_blank">audio in the background</a>. To maximize system and power efficiency, we suspend the app when the user pauses the audio.




[b]Sharing[/b]


If your app is sending content to a cloud service [url=http://channel9.msdn.com/Events/BUILD/BUILD2011/APP-405T" target="_blank">using the Share charm</a>, that operation completes in the background. More info about transferring data during a Share operation is available on the [url=http://go.microsoft.com/fwlink/?LinkId=227498" target="_blank">Dev Center</a>.




[b]Device sync[/b]


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 [url=http://blogs.msdn.com/b/b8/archive/2011/11/02/updating-live-tiles-without-draining-your-battery.aspx" target="_blank">sending push notifications to your Windows 8 PC</a>. More info in the post [url=http://blogs.msdn.com/b/windowsappdev/archive/2012/04/16/creating-a-great-tile-experience-part-1.aspx" target="_blank">Creating a great tile experience</a>.




[b]Scheduled notifications[/b]


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 [url=http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.notifications.scheduledtoastnotification.aspx" target="_blank">Dev Center</a>.




[b]Background tasks[/b]


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.


</tbody>


Now lets 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 lets 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 dont 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. Its optimized for power efficiency, is resilient to network glitches, and is network cost aware. Lets 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.
<h4>JavaScript</h4>
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)
}</pre>
<h4>C#</h4>
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)
}</pre>
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.
<h4>C#</h4>
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)
}
}</pre>

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.
<h4>C#</h4>
// 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)
}
}</pre>
<h5>JavaScript</h5>
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.attachAsync().then(complete, error, progress)
}
}
}</pre>


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 [url=http://msdn.microsoft.com/en-us/library/windows/apps/hh452979.aspx" target="_blank">transferring data in the background</a>, [url=http://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.aspx" target="_blank">API namespace</a>, [url=http://msdn.microsoft.com/en-us/windows/apps/br229512.aspx" target="_blank">Background transfer download</a> [url=http://code.msdn.microsoft.com/windowsapps/Background-Transfer-Sample-d7833f61" target="_blank">sample</a>, or watch //BUILD [url=http://channel9.msdn.com/events/BUILD/BUILD2011/PLAT-581T" target="_blank">session Making apps social and connected with HTTP services</a>.
[size=5]Background audio[/size]
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 dont go into details about actually playing audio or the Media Control classes. For more info about the audio technologies, see the [url=http://msdn.microsoft.com/en-us/library/windows/hardware/hh770517" target="_blank">Audio playback in a Metro style app</a> white paper.
There are three important requirements that the app must meet to play audio in the background:
[list]
[*]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.
[/list]
To add the background audio declaration to your app, simply open your apps 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.
[url=http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/4682.declarations_2D00_page_5F00_6FFADA72.png"><img style="border: 0px currentcolor margin-right: auto margin-left: auto float: none display: block background-image: none" title="Manifest declarations in Visual Studio" border="0" alt="Manifest declarations in Visual Studio" src="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-51-31-metablogapi/3443.declarations_2D00_page_5F00_thumb_5F00_3A82184D.png" width="700" height="470" /></a>
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 applications 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.
[quote]

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

[/quote]
Here is JavaScript code to perform the same functionality. You must set the msAudioCategory attribute before you set the source element, otherwise the system wont see the audio category.
<h5>JavaScript</h5>
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()
}
}</pre>
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.
<h5>C#</h5>
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
}</pre>
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.


<tbody>


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


</tbody>


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 [url=http://msdn.microsoft.com/en-us/library/windows/hardware/hh833781" target="_blank">System Transport Controls Developer Guide</a>.
And thats 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 doesnt 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 [url=http://msdn.microsoft.com/en-us/library/windows/hardware/hh770517" target="_blank">Audio playback in a Metro style app</a> white paper.
[size=5]Summary[/size]
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


<tbody>


Link


Type


Highlights




[url=http://msdn.microsoft.com/en-us/library/windows/apps/hh452979.aspx" target="_blank">Transferring data in the background</a>


Quick start


Conceptual documentation on background transfer




[url=http://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.backgroundtransfer.aspx" target="_blank">API namespace</a>


API Docs


Background transfer API namespace




[url=http://msdn.microsoft.com/en-us/windows/apps/br229512.aspx" target="_blank">Background transfer download sample</a>


Sample Project


Sample app demonstrating usage of background transfer API




[url=http://channel9.msdn.com/events/BUILD/BUILD2011/PLAT-581T" target="_blank">Making apps social and connected with HTTP services</a>


//BUILD session


//BUILD session describing the how to build connected apps




[url=http://msdn.microsoft.com/en-us/library/windows/hardware/hh770517" target="_blank">Audio playback in a Metro style app</a>


White paper


Whitepaper on how to play audio in the background




[url=http://msdn.microsoft.com/en-us/library/windows/hardware/hh833781" target="_blank">System Transport Controls Developer Guide</a>


White paper


Whitepaper on using media transport controls to develop music applications




[url=http://msdn.microsoft.com/en-us/library/windows/apps/br243045.aspx" target="_blank">API namespace</a>


API Docs


Basic media support APIs


</tbody>

[img]http://freepchelp.forum/data/MetaMirrorCache/ddbb0b2b11be84f30c5787072be1726c._.gif[/img]

[url=http://blogs.msdn.com/b/windowsappdev/archive/2012/05/16/being-productive-when-your-app-is-offscreen.aspx]View the full article
 
Last edited:
Back
Top