This article is Day #26 in a series called 31 Days of Mango, and was written by guest author Gary Johnson. Gary can be reached on Twitter at @GaryGJohnson.
Yesterday we created a project using a Background Agent, one of the multitasking features new to Windows Phone 7.5. Today we will use Background File Transfer to perform a file download that continues even when our application is not running. We will download a video from Channel 9 and play it when completed.
Getting Started
Launch Visual Studio and create a new project. Under Silverlight for Windows Phone, select Windows Phone Application. Name it “MyFileTransferApp”.
You’ve now created the main application. It will be responsible for:
1) Starting our video download
2) Displaying the status of the download
3) Playing the video once download has completed
Creating the Application
Now it’s time to actually wire everything up. Open MainPage.xaml and add two Buttons for downloading and playing the video. Then, add two TextBlocks for displaying download progress and status.
<Button x:Name="downloadButton" Click="downloadButton_Click">Start Download</Button>
<Button x:Name="playVideoButton" Click="playVideo_Click" IsEnabled="False">Play Video</Button>
<TextBlock x:Name="progressText" Margin="10"/>
<TextBlock x:Name="statusText" Margin="10"/>
</StackPanel>
I won’t include the entirety of MainPage.xaml.cs here, but it is available in the attached solution. First, we define some instance variables to hold the location of our video to be downloaded, the location where we will save the video, and the current transfer request:
private Uri videoDownloadUri = new Uri("http://video.ch9.ms/ch9/02df/0a2774a9-a010-4b9b-b654-9f88014102df/xboxCompanion_med_ch9.mp4");
private Uri saveLocationUri = new Uri(SAVE_LOCATION, UriKind.RelativeOrAbsolute);
private BackgroundTransferRequest _currentRequest = null;
Note that when downloading directly to Isolated Storage, all downloads must go into shared/transfers/. We will be downloading a video from Channel 9 and saving it as “MyDownloadedVideo.mp4”.
When a user clicks “Start Download”, we will create a new BackgroundTransferRequest and tell it what we want to download, and where we want the download to be saved. By default, a download can only be performed when the device is plugged in and has a Wi-Fi connection. We adjust this by setting BackgroundTransferRequest.TransferPreferences to AllowCellularAndBattery. Finally, we add our request to the BackgroundTransferService.
_currentRequest.TransferPreferences = TransferPreferences.AllowCellularAndBattery;
BackgroundTransferService.Add(_currentRequest);
We also need to be notified of the request status and progress so we can update our UI. We can subscribe to changes by handling the TransferProgressChanged and TransferStatusChanged events:
_currentRequest.TransferStatusChanged += new EventHandler<BackgroundTransferEventArgs>(_currentRequest_TransferStatusChanged);
When we get notified of those events, we can check several properties on our BackgroundTransferRequest to see the current state of the download:
- BytesRecieved / TotalBytesToRecieve for progress of a download
- BytesSent / TotalBytesToSend for progress of an upload
- TransferStatus for the current status of the download (transferring, completed, etc.)
- TransferError for information about a failed transfer.
Note that whether or not the transfer was successful, TransferStatus will report Completed when finished. Because of this, once TransferStatus reports a Completed status, you should check TransferError to see if an error occurred.
When the transfer is completed, you should remove it from the BackgroundTransferService:
Finally, one of the trickier aspects of implementing a background file transfer is dealing with your application getting closed. When we re-enter the application, we need our status to continue updating, even through _currentRequest is going to be null and our events are no longer wired up. To deal with this, we reset our _currentRequest and wire up the events in OnNavigatedTo:
{
base.OnNavigatedTo(e);
foreach (BackgroundTransferRequest request in BackgroundTransferService.Requests)
{
_currentRequest = request;
break;
}
InitializeCurrentTransferRequest();
InitializeTransferRequestEventHandlers();
RefreshTransferUI();
}
While functional, this example is overly simplistic. It is recommended that you also check out the Background File Transfers Overview on MSDN for a more complete reference.
Running the Application
Now that our application is ready to go, deploy it to the device emulator or Windows Phone and run the MyFileTransferApp. Click “Start Download” and you should see download progress reported:
Hit the Start button and leave the application. Wait for a while, and then re-open the application. You should notice that the progress of the download has continued even when the application was not running. Once the status is Complete, you can click “Play Video” to watch the video that was downloaded.
Summary
So, today we created a BackgroundTransferRequest that downloads a video. When making transfer requests of your own, keep in mind what we covered:
- Start a BackgroundTransferRequest and add it to the BackgroundTransferService to begin a download or upload
- Save downloads in share/transfers/ when saving to Isolated Storage
- Handle the BackgroundTransferRequest.TransferProgressChanged and BackgroundTransferRequest.TransferStatusChanged events to be notified of changes in transfer state
- When BackgroundTransferRequest.TransferStatus is Complete, remember to check BackgroundTransferRequest.TransferError to see if the transfer was successful
- Handle scenarios where the user leaves and returns to your application
To download a complete Windows Phone project that includes all of the code from this article, click the Download Code button below.
Tomorrow, Parag Joshi is back to discuss the Microphone API, and how we can use it to capture audio from a Windows Phone device. See you then!
Leave a Reply