Mobile Zone is brought to you in partnership with:

I love technology. Plain and simple. You can generally find me writing software, figuring out how to get rid of cable, playing on my Xbox, or traveling around this country speaking about software development. If you're doing something cool with technology, let me know. I'd love to hear your story about something amazing. You can find my blog at jeffblankenburg.com Jeff is a DZone MVB and is not an employee of DZone and has posted 71 posts at DZone. You can read more from them at their website. View Full User Profile

31 Days of Mango | Day #26: Background File Transfer

11.28.2011
| 4513 views |
  • submit to reddit

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.

Day26-BackgroundFileTransfers

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”.

clip_image002

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.

<StackPanel VerticalAlignment="Center">
    <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 const String SAVE_LOCATION = "shared/transfers/MyDownloadedVideo.mp4";
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 = new BackgroundTransferRequest(videoDownloadUri, saveLocationUri);
_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.TransferProgressChanged += new EventHandler<BackgroundTransferEventArgs>(_currentRequest_TransferProgressChanged);
                _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:

BackgroundTransferService.Remove(_currentRequest);

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:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    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:

clip_image003

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.

download

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!

toolsbutton


Source: http://www.jeffblankenburg.com/2011/11/26/31-days-of-mango-day-26-background-file-transfer
Published at DZone with permission of Jeff Blankenburg, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)