共享数据
本文将说明如何在桌面或通用 Windows 平台 (UWP) 应用中支持“共享”合约。 “共享”合约是一种在应用之间快速共享文本、链接、照片和视频等数据的简便方法。 例如,用户可能希望使用社交网络应用与其好友共享网页,或者将链接保存在笔记应用中以供日后参考。
注意
本文中的代码示例来自 UWP 应用。 桌面应用应使用 IDataTransferManagerInterop。 有关详细信息和代码示例,请参阅显示依赖于 CoreWindow 的 WINRT UI 对象。 另请参阅 WPF 共享内容源应用示例。
设置事件处理程序
添加一个 DataRequested 事件处理程序,以便在用户调用共享时调用。 这种情况在用户点击应用程序中的控件(例如按钮或应用程序栏命令)发生,或者在特定场景(例如,如果用户完成关卡并获得高分)下自动发生。
DataTransferManager dataTransferManager = DataTransferManager.GetForCurrentView();
dataTransferManager.DataRequested += DataTransferManager_DataRequested;
当发生 DataRequested 事件时,你的应用程序会收到一个 DataRequest 对象。 其中包含一个 DataPackage,可以使用它来提供用户想要共享的内容。 必须提供要共享的标题和数据。 说明是选填的,但建议填写它。
DataRequest request = args.Request;
选择数据
可以共享各种类型的数据,包括:
- 纯文本
- 统一资源标识符 (URI)
- HTML
- 带格式文本
- 位图
- 文件
- 自定义开发人员定义的数据
DataPackage 对象可以包含一个或多个这些格式(以任意组合形式)。 下面的示例演示了共享文本。
request.Data.SetText("Hello world!");
设置属性
打包数据以供共享时,可以提供各种属性,以提供有关所共享内容的附加信息。 这些属性有助于目标应用程序改善用户体验。 例如,当用户与多个应用共享内容时,说明会有所帮助。 共享图像或网页链接时添加缩略图可为用户提供视觉参考。 有关详细信息,请参阅 DataPackagePropertySet。
警告
除标题之外的所有属性都是可选的。 标题属性是必需的,必须设置。
request.Data.Properties.Title = "Share Example";
request.Data.Properties.Description = "A demonstration on how to share";
启动共享 UI
用于共享的 UI 由系统提供。 若要启动它,请调用 ShowShareUI 方法。
DataTransferManager.ShowShareUI();
处理错误
在大多数情况下,共享内容的过程非常简单。 不过,事事都有例外。 例如,应用可能要求用户选择要共享的内容,但用户没有选择任何内容。 若要处理这种情况,请使用 FailWithDisplayText 方法,该方法会在出现问题时向用户显示一条消息。
延迟共享与代理
有时,立即准备用户想要共享的数据可能没有意义。 例如,如果你的应用支持以多种不同的可能格式发送大型图像文件,那么在用户做出选择之前创建所有这些图像的效率会很低。
为了解决此问题,DataPackage 可以包含委托,即接收应用程序请求数据时调用的函数。 建议在用户想要共享的数据属于资源密集型数据时使用代理。
async void OnDeferredImageRequestedHandler(DataProviderRequest request)
{
// Provide updated bitmap data using delayed rendering
if (this.imageStream != null)
{
DataProviderDeferral deferral = request.GetDeferral();
InMemoryRandomAccessStream inMemoryStream = new InMemoryRandomAccessStream();
// Decode the image.
BitmapDecoder imageDecoder = await BitmapDecoder.CreateAsync(this.imageStream);
// Re-encode the image at 50% width and height.
BitmapEncoder imageEncoder = await BitmapEncoder.CreateForTranscodingAsync(inMemoryStream, imageDecoder);
imageEncoder.BitmapTransform.ScaledWidth = (uint)(imageDecoder.OrientedPixelWidth * 0.5);
imageEncoder.BitmapTransform.ScaledHeight = (uint)(imageDecoder.OrientedPixelHeight * 0.5);
await imageEncoder.FlushAsync();
request.SetData(RandomAccessStreamReference.CreateFromStream(inMemoryStream));
deferral.Complete();
}
}