Using a File Association
Like the custom protocol, the file association
enables you to launch your app from other parts of the phone. The
difference is that you are really launching a file, not just the app.
You can specify a file extension for your application to handle. You can
choose any file extension except for the reserved file extensions (see http://shawnw.me/WPReservedFiles for a complete list of reserved file extensions).
To get started, you must modify the
WMAppManifest.xml file as text. File associations use the application
manifest file to specify the different file extensions. You can open the
WMAppManifest.xml file as text by right-clicking the file and selecting
View Code.
Just after the Tokens
element, you must add a new element called Extensions
. Inside the Extensions
element, you will create a FileTypeAssociation
element, as shown here:
<Deployment xmlns="..."
AppPlatformVersion="8.0">
<App ...>
...
<Tokens>
...
</Tokens>
<Extensions>
<FileTypeAssociation TaskID="_default"
Name="SAMPLE"
NavUriFragment="fileToken=%s">
<Logos>
<Logo Size="small"
IsRelative="true">Assets/Logo33x33.png</Logo>
<Logo Size="medium"
IsRelative="true">Assets/Logo69x69.png</Logo>
<Logo Size="large"
IsRelative="true">Assets/Logo176x176.png</Logo>
</Logos>
<SupportedFileTypes>
<FileType
ContentType="application/sample">.sample</FileType>
</SupportedFileTypes>
</FileTypeAssociation>
</Extensions>
...
</App>
</Deployment>
The FileTypeAssociation
element has
several parts. First is a set of logos that are used in various parts
of the operating system. You must specify all three logo sizes and
supply them. The SupportedFileTypes
element contains an extension name and the related ContentType
. If you do not have a standard content type, you can use application/YOURAPPNAME
. This means that you can now deal with the files that end in .foo
. The FileTypeAssociation
element’s NavigationUriFragment
and TaskID
attributes must both have the same values as is shown in the example.
When your application is launched, it will be
executed with a special URI that contains information about the file
that was launched.You’ll need to create a UriMapperBase
derived class. Unlike the earlier example, though, the URI you’re looking for is /FileTypeAssociation
:
public class AssociationMapper : UriMapperBase
{
public override Uri MapUri(Uri uri)
{
var fileUri = uri.ToString();
if (fileUri.Contains("/FileTypeAssociation"))
{
// Get the File Token
var index = fileUri.IndexOf("fileToken=") + 10;
var token = fileUri.Substring(index);
// Create path to the XAML to Show File
var path = string.Concat("/ShowFile.xaml?token=", token);
return new Uri(path, UriKind.Relative);
}
else
{
// Let normal navigation happen
return uri;
}
}
}
As you can see here, the operating system is passing in a query string value called fileToken
that contains a token to the file that was launched. In this case we’re
just post-pending it to the URI for the page we want to launch when a
file is shown.
After you have created this new UriMapperBase
derived class, you can register it with the application class as shown earlier in the protocol association example.
Back on the page that will handle the file, you can get that token from the query string and use it to interact with the file:
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var token = NavigationContext.QueryString["token"];
if (!string.IsNullOrWhiteSpace(token))
{
var fileName =
SharedStorageAccessManager.GetSharedFileName(token);
IStorageFile file = await
SharedStorageAccessManager.
CopySharedFileAsync(ApplicationData.Current.LocalFolder,
fileName,
NameCollisionOption.GenerateUniqueName,
token);
// ...
}
}
After you’re in the OnNavigatedTo
method of the page that is handling the file association, you can use the SharedStorageAccessManager
class to get the name of the file by passing in the token. If you need the contents of the file, you can also use the CopySharedFileAsync
to copy the file into a local folder (shown here as the ApplicationData
.Current
.LocalFolder
). The CopyShareFileAsync
copies the file into a location from which your application can access it and then returns an IStorageFile
object that contains the file.