Windows Phone 8.1 for Developers–Contracts
This blog post is part of a series about how Windows Phone 8.1 affects developers. This blog post talks about how contracts work and is written by Robert Hedgate (@roberthedgate) at Jayway and was originally posted here.
Introduction
In this blog post I will do a quick overview of what is new with contracts in Windows Phone 8.1. This is the first impression of the functions so I do recommend you to take a look at MSDN if you want a deeper understanding of how it works.
File Open Picker contract
In Windows Phone 8.1 there has popped up a new functions named PickSingleFileAndContinue and PickMultipleFilesAndContinue. It is not async because the app will suspend if it needs to when calling these functions. This is because if the phone has low memory it will run out of it so the solution is to suspend your app when the picker is open and then resume it when it is done.
So how do one get hold of the selected file? You have to add code to the OnActivated function in App.xaml.cs. Here is an example of how to use PickSingleFileAndContinue:
private void Button_Click(object sender, RoutedEventArgs e)
{
var openPicker = new FileOpenPicker
{
ViewMode = PickerViewMode.Thumbnail,
SuggestedStartLocation = PickerLocationId.PicturesLibrary
};
openPicker.FileTypeFilter.Add(".jpg");
openPicker.PickSingleFileAndContinue();
}
protected override void OnActivated(IActivatedEventArgs args)
{
var root = Window.Current.Content as Frame;
var mainPage = root.Content as MainPage;
if (mainPage != null && args is FileOpenPickerContinuationEventArgs)
{
mainPage.ContinueFileOpenPicker(args as FileOpenPickerContinuationEventArgs);
}
}
public void ContinueFileOpenPicker(FileOpenPickerContinuationEventArgs fileOpenPickerContinuationEventArgs)
{
if (fileOpenPickerContinuationEventArgs.Files != null)
{
// Do something with selected file/s
}
}
File Save Picker contract
This works in very similar way as the open picker contract does.
Share contract
Windows Phone 8.0
The old way is pretty straight forward:
var shareLinkTask = new ShareLinkTask { Title = "my title", LinkUri = new Uri("https://www.someuri.com"), Message = "my message"};
shareLinkTask.Show();
The share classes ShareLinkTask, ShareMediaTask or ShareStatusTask can be called from most places in your code and the show UI from the operation system will be shown.
Windows Phone 8.1
Share
The new way of sharing is like the one in Windows store apps. Windows can ask the program if it has anything to share, and what that might be. For this you need to implement a function in your views which can share and set it in the DataTransferManager. A complete code might look like:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// Register the current page as a share source.
_dataTransferManager = DataTransferManager.GetForCurrentView();
_dataTransferManager.DataRequested += OnDataRequested;
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
// Unregister the current page as a share source.
_dataTransferManager.DataRequested -= OnDataRequested;
}
protected void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs e)
{
e.Request.Data.Properties.Title = "Some title";
e.Request.Data.Properties.Description = "Some description"; // Optional
e.Request.Data.SetUri(new Uri("https://www.some_uri.com"));
}
In the example we use the SetUri to share an Uri. There are many different shares which is used to share different things:
SetBitmap(RandomAccessStreamReference value)
SetApplicationLink(Uri value)
SetData(string formatId, object value)
SetDataProvider(string formatId, DataProviderHandler delayRenderer)
SetStorageItems(IEnumerable value)
SetStorageItems(IEnumerable value, bool readOnly)
SetText(string value)
SetUri(Uri value)
SetWebLink(Uri value)
SetHtmlFormat(string value)
SetRtf(string value)
If the OnDataRequested will take a little time you can use deferral to tell the operating system that your app has not stopped working. You can also call the share view from code to show it. Example if you have share in a menu and want to show it when user selects it. When you have to call this function from somewhere:
DataTransferManager.ShowShareUI();
Receive
If you want to implement an app which will be a share target you need to specify what you want to receive in the appxmanifest. For example an app which want to receive pictures may look something like this:
When your app is selected to be a share target your app is started and you capture the shared object in OnShareTargetActivated which shall be set in App.xaml.cs. Example:
protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{
// Do something with args.ShareOperation.Data
}
Inside args.ShareOperation.Data there are many function to call to get the shared content. You already know what functions to use since this is stated in the appxmainfest. In the example above we would use args.ShareOperation.Data.GetStorageItemsAsync(). After the share is done call ReportCompleted to tell the system to return to the calling app.
Summary
Using file pickers is a bit harder than before but it is for a good cause that even low end devices will be able to work with Windows Phone 8.1.
Also share in Windows Phone 8.1 is a bit more tedious than before, but the up side is that it is more like Windows store apps and have all that benefits of share between apps and more. We can also share more thing than before.
Comments
Anonymous
April 16, 2014
Hello, I have write an app with share contract, but only Title is share with mail client or onenote, other data never appear in receive app. I have tried SetHtmlFormat and SetText and result are same, no data only Title Have you an idea ? Best regards, MarcAnonymous
April 21, 2014
SetText works fine when I try it. One thing that I found is that if you have multiple share possiblity it might not work. Try to use only SetText and see if that works.Anonymous
April 22, 2014
Hello, SetText is okay for me if I add before a Title. But I can't send a picture with SetBitmap like this : protected void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs e) { e.Request.Data.Properties.Title = "My Titre"; var rasr = RandomAccessStreamReference.CreateFromFile(imgFile); e.Request.Data.SetBitmap(rasr); } have you an example ?Anonymous
April 22, 2014
it good by using SetStorageItems : var imageItems = new List<IStorageItem>(); imageItems.Add(this.imgFile); e.Request.Data.SetStorageItems(imageItems); var imageStreamRef = RandomAccessStreamReference.CreateFromFile(this.imgFile); e.Request.Data.Properties.Thumbnail = imageStreamRef; e.Request.Data.SetBitmap(imageStreamRef);Anonymous
May 27, 2014
Hi I use DataTransferManager to share a file in WP8.1, it works. but there is a situation strange. If I chose a target app(like Messaging), and stay in target App long time(one minute or more), then press Back , it should back to my App, but my App is closed. If I use ShareMediaTask to share a file, and stay in target App long time, then press back, it always back to my App. Could you give me a suggestion to check this strange behavior of using DataTransferManager . thank you.Anonymous
August 12, 2015
The comment has been removed