导出 (0) 打印
全部展开
信息
您所需的主题如下所示。但此主题未包含在此库中。

使用 Windows Phone 8 的文件和 URI 关联自动启动应用

2014/6/18

仅适用于:Windows Phone 8 和 Windows Phone Silverlight 8.1

当另一个应用启动特定的文件类型或 URI 方案时,您可以使用 Windows Phone 8 中的文件和 URI 关联自动启动您的应用。启动后,深层链接 URI 将被用来向应用发送文件(对文件的引用)或 URI。您也可以使用关联启动 API 以相同的方式启动另一个应用。本主题描述了文件和 URI 关联以及如何在应用中使用它们。

提示提示:

类似于 Windows 8,Windows Phone 8 使用 LaunchFileAsync 启动文件,并使用 LaunchUriAsync 启动 URI。但是,Windows Phone XAML 应用接收文件或 URI 的方式却是不同的。此外,Windows Phone 没有“默认的”商店 应用。如果存在多个能够处理某个特定文件或 URI 关联的 商店 应用,用户可以从菜单中选择接收应用。

本主题包括以下部分。

当用户想要打开某个特定文件时,文件关联允许您的应用自动启动。该文件可能来自不同的来源,这包括但不限于以下来源:

  • 电子邮件附件

  • Internet Explorer 中的网站

  • 近距离无线通信 (NFC) 标记

  • 商店 中的其他应用

文件关联还可以用来确定,通过使用外部存储 API,应用可以从 SD 卡读取哪些文件类型。有关这些 API 的更多信息,请参见 Windows Phone 8 的数据

注册文件关联

要处理特定的文件类型,请在应用清单文件中注册文件关联。应用能够指定任何可处理的文件关联。但是,任何由内置应用保留的文件关联将被忽略。有关更多信息,请参见 Windows Phone 8 的保留文件和 URI 关联

说明注意:

有时 Internet Explorer 重写文件关联:它启动内置的媒体播放器来处理所有的音乐和视频文件类型。具体来说,具有 audio/video/ 内容类型的任何文件。例如,应用从电子邮件附件启动时,它可以处理(非保留的)音乐和视频文件。但是如果从 Internet Explorer 启动相同的文件,则内置的媒体播放器将处理该文件。

要向在内置应用中显示的自定义文件类型提供“集成”外观,您可以选择是否提供在文件旁边显示的徽标(图像文件)。例如,如果文件(您自定义的类型)被附加到电子邮件,下载附件后,附件的旁边将显示一个小型的徽标。

文件类型徽标显示在白色背景前,请确保在测试应用时,检查您的徽标在手机上的显示方式。还请注意,如果不止一个应用注册了相同的文件类型,那么您将看不到您的徽标。在这种情况下,则使用常规徽标。下表列出了三种可向每个文件关联提供的图像大小。

徽标大小

使用

维度

电子邮件附件

33x33 像素

Office 中心列表视图

69x69 像素

浏览器下载

176x176 像素

提示提示:

作为最佳做法,我们建议您将徽标存储在应用包的资产文件夹中。

要注册文件关联,您必须使用 XML(文本)编辑器编辑 WMAppManifest.xml。在“解决方案资源管理器”中,右键单击 WMAppManifest.xml 文件,然后单击“打开方式”。在“打开方式”窗口中,选择“XML(文本)编辑器”,然后单击“确定”

在应用清单文件的 Extensions 元素中,文件关联是使用 FileTypeAssociation 元素指定的。请注意,Extensions 元素必须紧跟在 Tokens 元素之后。下面的示例演示了称为“Windows Phone SDK 测试文件类型”的假想文件类型的文件关联,该关联能够处理两种不同文件扩展名:

<Extensions>
   <FileTypeAssociation Name="Windows Phone SDK test file type" TaskID="_default" NavUriFragment="fileToken=%s">
       <Logos>
           <Logo Size="small" IsRelative="true">Assets/sdk-small-33x33.png</Logo>
           <Logo Size="medium" IsRelative="true">Assets/sdk-medium-69x69.png</Logo>
           <Logo Size="large" IsRelative="true">Assets/sdk-large-176x176.png</Logo>
       </Logos>
       <SupportedFileTypes>
         <FileType ContentType="application/sdk">.sdkTest1</FileType>
         <FileType ContentType="application/sdk">.sdkTest2</FileType>

       </SupportedFileTypes>
   </FileTypeAssociation>
</Extensions>

下表描述了所有这些元素。

元素

父元素

描述

Extensions

App

必须跟在 Tokens 元素之后。

FileTypeAssociation

Extensions

描述文件关联。您最多可以注册 20 个文件关联,但是每个文件关联只能列出一次。必须提供 Name 特性,但您可以选择自己的友好名称。根据指示指定 TaskIDNavUriFragment 元素。

Logos

FileTypeAssociation

列出文件关联的所有徽标。如果没有指定任何徽标,这是可选的。

Logo

Logos

可选项。列出要显示在文件旁边的图像文件。若要提供大小,您必须提供所有大小(小、中等和大)。IsRelative 特性必须存在并等于 true

SupportedFileTypes

FileTypeAssociation

列出与文件类型相关联的所有文件扩展名。

FileType

SupportedFileTypes

列出与文件类型相关的文件扩展名,包括句点 (‘.’)。每个文件关联最多可以关联 20 个文件扩展名,但是每个扩展名只能使用一次。若您的应用从 SD 卡读取文件,您还必须指定 ContentType 特性以描述文件的类型。

侦听文件启动

当您的应用启动以处理某个特定的文件类型时,深层链接 URI 用于将用户带到您的应用。在 URI 中,FileTypeAssociation 字符串指定 URI 的源为文件关联且 fileToken 参数包含文件标记。例如,以下代码显示了文件关联的深层链接 URI。


/FileTypeAssociation?fileToken=89819279-4fe0-4531-9f57-d633f0949a19

启动时,将传入的深层链接 URI 映射到能够处理该文件的应用页面。如果您拥有用于处理多个文件类型的多个页面,请在映射 URI 之前使用自定义的 URI 映射器和 GetSharedFileName 方法检查文件类型。例如,以下代码演示了用于分析深层链接 URI 并根据文件的类型映射不同页面的 URI 映射器。如果映射器不是从文件关联启动的,它会在保持 URI 不变的情况下,将完整的 URI 字符串发回到 App 对象。

using System;
using System.IO;
using System.Windows.Navigation;
using Windows.Phone.Storage.SharedAccess;

namespace sdkAutoLaunch
{
    class AssociationUriMapper : UriMapperBase
    {
        private string tempUri;

        public override Uri MapUri(Uri uri)
        {
            tempUri = uri.ToString();

            // File association launch
            if (tempUri.Contains("/FileTypeAssociation"))
            {
                // Get the file ID (after "fileToken=").
                int fileIDIndex = tempUri.IndexOf("fileToken=") + 10;
                string fileID = tempUri.Substring(fileIDIndex);

                // Get the file name.
                string incomingFileName =
                    SharedStorageAccessManager.GetSharedFileName(fileID);

                // Get the file extension.
                string incomingFileType = Path.GetExtension(incomingFileName);

                // Map the .sdkTest1 and .sdkTest2 files to different pages.
                switch (incomingFileType)
                {
                    case ".sdkTest1":
                        return new Uri("/sdkTest1Page.xaml?fileToken=" + fileID, UriKind.Relative);
                    case ".sdkTest2":
                        return new Uri("/sdkTest2Page.xaml?fileToken=" + fileID, UriKind.Relative);
                    default:
                        return new Uri("/MainPage.xaml", UriKind.Relative);
                }
            }
            // Otherwise perform normal launch.
            return uri;
        }
    }
}

在此类情况下,若要在您的应用中使用 URI 映射器类,请将其分配到该应用在 App.xaml.cs 文件中所对应的框架。在 InitializePhoneApplication 方法中,在 RootFrame.Navigated 已被分配后,紧接着将 RootFrame.UriMapper 属性设置为与您的 URI 映射器类相等。在下列示例中,AssociationUriMapper 类被分配给框架的 UriMapper 属性。

private void InitializePhoneApplication()
{
    if (phoneApplicationInitialized)
        return;

    // Create the frame but don't set it as RootVisual yet; this allows the splash
    // screen to remain active until the application is ready to render.
    RootFrame = new PhoneApplicationFrame();
    RootFrame.Navigated += CompleteInitializePhoneApplication;

    // Assign the URI-mapper class to the application frame.
    RootFrame.UriMapper = new AssociationUriMapper();

    // Handle navigation failures
    RootFrame.NavigationFailed += RootFrame_NavigationFailed;

    // Ensure we don't initialize again
    phoneApplicationInitialized = true;
}

启动应用后,它将在初始化期间分配 URI 映射器。在启动任何页面之前,应用将调用 URI 映射器的 MapUri 方法确定要启动的页面。URI 映射器返回的 URI 即应用所启动的页面。

启动页面时,通过使用页面的 NavigationContext 对象的 QueryString 属性,页面可以访问 URI(启动了该页面)中的所有参数。例如,以下代码将所有的 URI 参数和值都放置在 IDictionary 对象中。


// Get a dictionary of URI parameters and values.
IDictionary<string, string> queryStrings = this.NavigationContext.QueryString;

检索文件

当您获得了深层链接 URI 的文件标记后,使用 Windows.Phone.Storage.SharedAccess 命名空间中的 SharedStorageAccessManager 静态类访问该文件。SharedStorageAccessManager 提供了以下方法。

方法

返回类型

描述

GetSharedFileName

System.String

返回文件名(包括文件扩展名)。

CopySharedFileAsync

Windows.Storage.StorageFile

将文件复制到特定的位置并返回副本。

启动文件

如前所述,您的应用也可以启动文件,以便另一个应用能够打开它。为此,请使用 Windows.System 命名空间的启动器对象的 LaunchFileAsync 方法。例如,下列代码从本地存储启动了一个假想 Contoso Bug 查询文件。


private async void LaunchFileButton_Click(object sender, RoutedEventArgs rea)
{

    // Access isolated storage.
    StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;

    // Access the bug query file.
    StorageFile bqfile = await local.GetFileAsync("file1.bqy");

    // Launch the bug query file.
    Windows.System.Launcher.LaunchFileAsync(bqfile);

}

URI 关联允许应用在另一个应用启动了特殊的 URI 时自动启动。URI 的特别之处在于,它以应用注册的 URI 方案名为开头。URI 方案名是 URI 的一部分,它位于冒号 (‘:’) 之前。URI 方案包括 URI 方案名以及跟随在冒号后的所有 URI。例如,在下面的 URI 方案中,contoso 为 URI 方案名。

contoso:ShowProducts?CategoryID=aea6ae1f-9894-404e-8bca-ec47ec5b9c6c

不论您是否愿意,冒号之后的其余 URI 始终将公开以允许使用 URI 关联。您的应用启动后,它可以检查 URI 并根据 URI 的内容呈现不同的行为。在本示例中,接收应用用于显示特定类别中所有的产品。

提示提示:

如果您只感兴趣启动您自己的应用,则考虑使用来自 Windows.Phone.Management.Deployment 命名空间的 API。您可以使用该 API 来检查您已经发布的其他应用,如果它们已经安装,则启动它们。有关更多信息,请参见 Windows Phone 8 的启动、恢复和多任务处理

注册 URI 关联

要处理 URI 关联,请在应用清单文件 WMAppManifest.xml 中指定相应的 URI 方案名。您的 URI 方案名可以是字母和数字的任意组合;但是任何由内置应用保留的 URI 方案名都将被忽略。有关更多信息,请参见 Windows Phone 8 的保留文件和 URI 关联

要注册 URI 关联,您必须使用 XML(文本)编辑器编辑 WMAppManifest.xml。在“解决方案资源管理器”中,右键单击 WMAppManifest.xml 文件,然后单击“打开方式”。在“打开方式”窗口中,选择“XML(文本)编辑器”,然后单击“确定”

在应用清单文件的 Extensions 元素中,URI 关联是使用 Protocol 元素指定的。请注意,Extensions 元素必须紧跟在 Tokens 元素之后。每个应用中最多可以注册 10 个 URI 关联。下面的示例演示了能够处理 contoso URI 方案名的假想应用的 URI 关联。


<Extensions>
  <Protocol Name="contoso" NavUriFragment="encodedLaunchUri=%s" TaskID="_default" />
</Extensions>

Protocol 元素由以下特性组成。

属性

描述

名称

自定义的 URI 方案的前缀。包含数字、小写字母、句点 (‘.’) 或连字符 (‘-’) 且长度介于 3 和 39 个字符的字符串。它不包含冒号 (‘:’) 或任何紧跟其后的 URI 中的内容。

NavUriFragment

必须始终等于 encodedLaunchUri=%s

TaskID

必须始终等于 _default

侦听 URI

当您的应用自动启动以处理某个 URI 关联时,深层链接 URI 用于将用户带到您的应用。在 URI 中,Protocol 字符串指定 URI 的源为 URI 关联。名为 encodedLaunchuri 的 URI 参数等于从源应用发送的整个 URI 方案的 URI 编码版本。例如,以下代码演示了当假想应用作为 contoso URI 关联的结果被启动后,该应用将显示的启动 URI。


/Protocol?encodedLaunchUri=contoso%3AShowProducts%3FCategoryID%3Daea6ae1f-9894-404e-8bca-ec47ec5b9c6c

重要说明重要说明:

启动应用后,URI 方案中所有保留的字符都将自动进行百分比编码。例如,一个应用启动 URI“contoso:NewProducts”后,会导致另一个应用接收深层链接 URI“/Protocol?encodedLaunchUri=contoso%3ANewProducts”。

应用启动时,将传入的深层链接 URI 映射到能够处理 URI 关联的应用页面。以下示例演示了使用 ShowProducts.xaml 页面映射 Contoso“显示产品”请求的自定义 URI 映射器。如果没有使用 Contoso URI 方案名,完整的 URI 将被发送到 MainPage.xaml 页面。

using System;
using System.Windows.Navigation;

namespace sdkAutoLaunch
{
    class AssociationUriMapper : UriMapperBase
    {
        private string tempUri;

        public override Uri MapUri(Uri uri)
        {
            tempUri = System.Net.HttpUtility.UrlDecode(uri.ToString());

            // URI association launch for contoso.
            if (tempUri.Contains("contoso:ShowProducts?CategoryID="))
            {
                // Get the category ID (after "CategoryID=").
                int categoryIdIndex = tempUri.IndexOf("CategoryID=") + 11;
                string categoryId = tempUri.Substring(categoryIdIndex);

                // Map the show products request to ShowProducts.xaml
                return new Uri("/ShowProducts.xaml?CategoryID=" + categoryId, UriKind.Relative);
            }

            // Otherwise perform normal launch.
            return uri;
            }
        }
}

在此类情况下,若要在您的应用中使用 URI 映射器类,请将其分配到该应用在 App.xaml.cs 文件中所对应的框架。在 InitializePhoneApplication 方法中,在 RootFrame.Navigated 已分配后,紧接着将 RootFrame.UriMapper 属性分配给您的 URI 映射器类。在下列示例中,AssociationUriMapper 类被分配给框架的 UriMapper 属性。

private void InitializePhoneApplication()
{
    if (phoneApplicationInitialized)
        return;

    // Create the frame but don't set it as RootVisual yet; this allows the splash
    // screen to remain active until the application is ready to render.
    RootFrame = new PhoneApplicationFrame();
    RootFrame.Navigated += CompleteInitializePhoneApplication;

    // Assign the URI-mapper class to the application frame.
    RootFrame.UriMapper = new AssociationUriMapper();

    // Handle navigation failures
    RootFrame.NavigationFailed += RootFrame_NavigationFailed;

    // Ensure we don't initialize again
    phoneApplicationInitialized = true;
}

启动应用后,它将在初始化期间分配 URI 映射器。在启动任何页面之前,应用将调用 URI 映射器的 MapUri 方法确定要启动的页面。URI 映射器返回的 URI 即应用所启动的页面。

启动页面时,通过使用页面的 NavigationContext 对象的 QueryString 属性,页面可以访问 URI(启动了该页面)中的所有参数。例如,以下代码将所有的 URI 参数和值都放置在 IDictionary 对象中。


// Get a dictionary of URI parameters and values.
IDictionary<string, string> queryStrings = this.NavigationContext.QueryString;

启动 URI

通过使用关联启动 API,您的应用可以通过启动自定义的 URI 自动启动另一个应用。为此,请使用 Windows.System 命名空间的启动器对象的 Launcher.LaunchUriAsync(Uri) 方法。例如,以下代码启动了一个假想 Contoso 应用以显示新产品。


private async void LaunchContosoNewProductsButton_Click(object sender, RoutedEventArgs rea)
{
    // Launch URI.
    Windows.System.Launcher.LaunchUriAsync(new System.Uri("contoso:NewProducts"));
}

当您的 URI 被传递到附带 URI 关联的接收应用,已启动 URI 中所有的保留字符都将自动进行百分比编码。例如,一个应用启动 URI“contoso:NewProducts”后,会导致另一个应用接收深层链接 URI“/Protocol?encodedLaunchUri=contoso%3ANewProducts”。

使用邻近感应启动 URI

Windows Phone 8 支持使用近场通信 (NFC) 的邻近感应通信。但是在使用邻近感应 API 时,您的应用会在另一台手机上启动另一个应用。如果另一台手机是 Windows Phone 8 设备,并且支持 NFC,则会以对本地启动 URI 相同的方式来处理 URI 关联。有关使用应用中的邻近感应的更多信息,请参见 Windows Phone 8 的邻近感应

ProximityDevice device = ProximityDevice.GetDefault();

// Make sure NFC is supported
if (device != null)
{
    long Id = device.PublishUriMessage(new System.Uri("contoso:NewProducts"));
    Debug.WriteLine("Published Message. ID is {0}", Id);

    // Store the unique message Id so that it 
    // can be used to stop publishing this message
}

用户从应用启动文件或 URI 后,接下来将发生的情况取决于手机上安装了哪种应用。如果手机上的应用无法处理该特定文件或 URI 关联,用户可以选择是否获取可处理这些情况的应用。

如果特定文件或 URI 关联在手机上只注册了一个应用,当用户要打开它时,该应用将自动启动。如果用户在手机上拥有多个为文件或 URI 关联注册的应用,每次用户打开文件时,系统都会询问要使用哪个应用。

提示提示:

不要注册文件或 URI 关联,除非您可以使用它执行有用的操作。如果您的应用导致应用菜单频繁出现,用户可能会干脆选择卸载它来避免不断作出选择。

显示:
© 2014 Microsoft