如何支援提取作業 (HTML)
[ 本文的目標對象是撰寫 Windows 執行階段 App 的 Windows 8.x 和 Windows Phone 8.x 開發人員。如果您正在開發適用於 Windows 10 的 App,請參閱 最新文件 ]
在大部分的情況下,應用程式會立即從它的 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 來新增內容,而不是使用格式特定的函式,如 setBitmap 或 setStorageItems。只要您使用委派函式,就必須使用 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());
}
};