如何支持拉操作 (HTML)

[ 本文适用于编写 Windows 运行时应用的 Windows 8.x 和 Windows Phone 8.x 开发人员。如果你要针对 Windows 10 进行开发,请参阅 最新文档 ]

大多数情况下,应用会立即从其 datarequested 事件处理程序提供共享数据。但是,有时你的应用可能需要一些时间才能准备好数据进行共享。遇到这种情况时,你可以提供一个受支持格式列表,但在目标应用请求该内容之前,请延迟准备和提供该内容。在目标应用请求之前推迟提供内容,这称为拉操作(或延迟共享)。

要支持拉操作,你首先要创建一个函数,该函数打包用户希望共享的数据。然后,你可以提供一个委托函数,而不是向目标应用提供实际数据。当目标应用尝试获取数据时,系统将调用你的委托函数。此操作的优点是你的应用可以在后台共享数据,从而允许用户继续使用你的应用进行其他活动。

你需要了解的内容

技术

先决条件

  • 你应当熟悉 Visual Studio 及其关联模板。
  • 你应当熟悉 JavaScript。
  • 你应当了解如何获取文件和其他数据(比如通过使用 FileOpenPicker)。你可以在使用文件选取器访问文件中了解详细信息。

说明

步骤 1: 创建按钮处理程序函数以让用户选择图像文件

使用以下按钮处理程序代码,用户可以选取一个图像文件。在本快速入门的剩余步骤中会使用此文件。

注意  

以下代码使用 pickSingleFileAsync。在 Windows Phone 8.1 上,应改用 pickSingleFileAndContinue

var imageFile = null;
function pickImageFile() {
    var picker = new Windows.Storage.Pickers.FileOpenPicker();
    picker.fileTypeFilter.replaceAll([".jpg", ".bmp", ".gif", ".png"]);
    picker.pickSingleFileAsync().done(function (file) {
        imageFile = file;
    });
}

步骤 2: 创建一个委托函数来提供用户要共享的内容。

委托函数的确切性质取决于你的应用。以下是一个示例。

function onDeferredImageRequested(request) {
    if (imageFile) {
        var imageStreamRef = Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(imageFile);
        request.setData(imageStreamRef);
    }
}

请注意,委托函数使用 setData 来添加内容,而不是格式特定的函数(如 setBitmapsetStorageItems)。只要你使用委托函数,就必须使用 setData 来提供内容。

步骤 3: 将你的应用设置为共享源

DataTransferManager 对象是任何共享操作的主起点。当用户想要调用“共享”时,添加要引发的 DataRequested 事件处理程序。在 Windows 应用商店应用中,当用户调用“共享”超级按钮时,将自动执行此操作。如果你面向 Windows Phone 进行开发,则没有内置的“共享”超级按钮,因此你将需要为用户添加一个控件,以便点击和触发该处理程序。

var dataTransferManager = Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();
dataTransferManager.addEventListener("datarequested", sharePullHandler);

剩下的步骤用于实现 sharePullHandler 函数。

步骤 4: 获取 DataRequest 对象

当发生 datarequested 事件时,你的应用会收到 DataRequest 对象。该对象包含一个 DataPackage,通常可用来提供用户要共享的内容。但在拉操作中,你指定委托函数而不是实际数据。

var request = e.request;

步骤 5: 设置标题和描述属性

request.data.properties.title = "Share Pull Example";
request.data.properties.description = "Demonstrates how to pull operations in share.";

步骤 6: 设置文件类型,如果需要。

如果使用委托函数共享文件,则需要指定应用支持的文件类型。

request.data.properties.fileTypes.replaceAll([".jpg", ".bmp", ".gif", ".png"]);

步骤 7: 向 DataPackage 对象添加委托函数

setDataProvider 方法指定你所创建的用于提供实际内容的委托函数。

request.data.setDataProvider(Windows.ApplicationModel.DataTransfer.StandardDataFormats.bitmap, onDeferredImageRequested);

此时,当用户点击“共享”超级按钮时,应用可能会使用包含委托函数的 DataPackage 对象即时响应。共享操作现在可以在后台继续执行,从而使用户可以继续进行他们希望进行的任何其他活动。

请牢记,如果你使用 setStorageItems 方法共享文件,则此方法会创建用于共享的只读 StorageFile 对象并保留原始对象。这意味着,如果你在调用 setStorageItems 之后向原始文件中添加扩展属性,则共享的 StorageFile 对象中将不会包含这些新的扩展属性。这就是我们建议你直到完全准备好后才添加文件的原因。

备注

使用延迟呈现来共享数据的应用应该是单一页面的应用,以避免页面之间的导航。而且,如果你的应用支持框架内导航,则应该使用顶级脚本上下文来注册委派函数,而不是在框架级别注册委派。导航导致丢失脚本上下文,这会使委派函数无效并且会导致延迟呈现失败。

完整示例

var imageFile = null;
function pickImageFile() {
    var picker = new Windows.Storage.Pickers.FileOpenPicker();
    picker.fileTypeFilter.replaceAll([".jpg", ".bmp", ".gif", ".png"]);
    picker.pickSingleFileAsync().done(function (file) {
        imageFile = file;
    });
}

function onDeferredImageRequested(request) {
    if (imageFile) {
        var imageStreamRef = Windows.Storage.Streams.RandomAccessStreamReference.createFromFile(imageFile);
        request.setData(imageStreamRef);
    }
}

function sharePullHandler(e) {
    var request = e.request;
    request.data.properties.title = "Share Pull Example";
    request.data.properties.description = "Demonstrates how to support pull operations in share.";
    request.data.properties.fileTypes.replaceAll([".jpg", ".bmp", ".gif", ".png"]);
    request.data.setDataProvider(Windows.ApplicationModel.DataTransfer.StandardDataFormats.bitmap, onDeferredImageRequested);
}

app.onactivated = function (args) {
    if (args.detail.kind === activation.ActivationKind.launch) {
        if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
            // This app is newly launched; register it as a share source.
            var dataTransferManager = Windows.ApplicationModel.DataTransfer.DataTransferManager.getForCurrentView();
            dataTransferManager.addEventListener("datarequested", sharePullHandler);
            // Set up the button handler to pick an image file.
            document.getElementById("chooseImageButton").addEventListener("click", pickImageFile, false);
        } else {
            // TODO: This app was reactivated from suspension.
            // Restore the app state here.
        }
        args.setPromise(WinJS.UI.processAll());
    }
};

相关主题

共享内容源应用示例

共享和交换数据

如何异步生成请求的数据

快速入门:共享内容

DataPackage

Windows.ApplicationModel.DataTransfer

Windows.ApplicationModel.DataTransfer.Share