WAD-B305 Windows 10 新特性详解 微软中国技术顾问佘泽鹏
用户交互 应用通信 UI 媒体 Inking Background Task Adaptive Layout HTTP Live Streaming Cortana Drag & Drog Continuum Media Cast Notification & Action Center App Service Adaptive Tiles Web 平台 Windows Hello Socket Broker Lock Screen Microsoft Edge App to App Web App
应用服务 App Service
什么是 AppService? Windows 10 提供了很多 API 来跟系统交互 Windows.ApplicationModel.Contacts Windows.ApplicationModel.Email Windows.System.Launcher.LaunchUriAsync to launch settings, maps, store etc more 同时也提供了很多 API 来跟其他应用交互 Uri Associations using LaunchUriAsync File associations using LaunchFileAsync Launch for results using LaunchUriForResultsAsync AppService http://windows.microsoft.com
通过 AppService, 你的商店应用可以向其他商店应用提供服务
类似于说 设备上的 Web Service Client App A App with App Service Background Task Client App B http://windows.microsoft.com
应用场景 : 二维码扫描 Bar Code decoding App Service Image bytes in ValueSet or FileToken Decoded data http://windows.microsoft.com
应用场景 : 企业级整体解决方案 Client App A App Service Maintains Inventory cache Interact with cloud services Client App B App Service Proximity Reading Services http://windows.microsoft.com
App Services Client AppServiceConnection connection = new AppServiceConnection(); connection.appservicename = "microsoftdx-appservicesdemo"; connection.packagefamilyname = "24919ArunjeetSingh.InstapaperIt"; AppServiceConnectionStatus connectionstatus = await connection.openasync(); if (connectionstatus == AppServiceConnectionStatus.Success) { //Send data to the service var message = new ValueSet(); message.add("command", "CalcSum"); message.add("value1", Int32.Parse(Value1.Text)); message.add("value2", Int32.Parse(Value2.Text)); //Send message and wait for response AppServiceResponse response = await connection.sendmessageasync(message); if (response.status == AppServiceResponseStatus.Success) { int sum = (int)response.message["result"]; new MessageDialog("Result=" + sum).showasync(); } } else { //Drive the user to store to install the app that provides the app service } http://windows.microsoft.com
App Services Service (1/2) namespace AppServicesDemoTask { public sealed class AppServiceTask : IBackgroundTask { private static BackgroundTaskDeferral _servicedeferral; public void Run(IBackgroundTaskInstance taskinstance) { // Associate a cancellation handler with the background task. taskinstance.canceled += TaskInstance_Canceled; // Get the deferral object from the task instance _servicedeferral = taskinstance.getdeferral(); var appservice = taskinstance.triggerdetails as AppServiceTriggerDetails; if (appservice.name == "microsoftdx-appservicesdemo") { //Maybe ValidateCaller(appService.CallerPackageFamilyName)?? appservice.appserviceconnection.requestreceived += RequestReceived; } }... http://windows.microsoft.com
App Services Service (2/2) private async void RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) { var message = args.request.message; // This service uses a Command keyed entry for the client to invoke services from the App Service string command = message["command"] as string; switch (command) { case "DoIt": { var messagedeferral = args.getdeferral(); int value1 = (int)message["value1"];... Do some processing } } //Set a result to return to the caller var returnmessage = new ValueSet(); returnmessage.add("result", result); var responsestatus = await args.request.sendresponseasync(returnmessage); messagedeferral.complete(); break; } case "Quit": { //Service was asked to quit. Complete service deferral so platform can terminate servicedeferral.complete(); break; } http://windows.microsoft.com
声明 AppService <?xml version="1.0" encoding="utf-8"?> <Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"... > <Applications> <Application Id="App"... > <Extensions> <uap:extension Category="windows.appService" EntryPoint="AppServicesDemoTask.AppServiceTask"> <uap:appservice Name="microsoftDX-appservicesdemo" /> </uap:extension> </Extensions> </Application> </Applications> <Capabilities> <Capability Name="internetClient" /> </Capabilities> </Package> http://windows.microsoft.com
双工通信 服务器端与客户端将会保持一个双工通信的通道 客户端能够在自己的 AppServiceConnection 实例上帮上 RequestReceived 来监听处理事件实例 AppServiceConnectionStatus connectionstatus = await connection.openasync(); if (connectionstatus == AppServiceConnectionStatus.Success) { connection.requestreceived += OnRequestReceived; } 服务器端与客户端都能够收发消息 http://windows.microsoft.com
取得 PackageFamilyName 应用商店 将应用程序与应用商店关联 来设置正确的 PackageFamilyName 调试的时候可以使用 Package.Current.Id.FamilyName 来取得的值 http://windows.microsoft.com
调试 App Services 1. 在程序中设置断点 2. 在项目勾选 Do not launch but debug my code when it starts 3. 运行服务器端应用 什么事情都没有发生 4. 运行客户端应用连接应用服务 5. 调试器开始工作, 触发断点 http://windows.microsoft.com
AppService 提供了应用间通信的另外一种方法
AppService DEMO http://windows.microsoft.com
App Service 生命周期 服务是有需要才激活后台任务是通过 AppServiceTrigger 来激活的 客户端可以设置或者发送消息来结束服务端的服务 一旦激活的客户端被挂起, 那么相应的应用服务就会被系统结束 资源不足的时候可能会调用失败或者服务异常客户端在连接的时候会收到 AppServiceConnectionStatus.ResourcesNotAvailable 的错误在发送消息的话会收到 ppserviceresponsestatus.resourcelimitsexceeded 的错误 http://windows.microsoft.com
能不能限制别的应用访问我的 AppService? 建议在 AppService 之上自行建立鉴权机制 最简单的可以通过将应用的 PackageFamilyName 加入白名单, 非白名单的应用无法访问 PackageFamilyName of caller is passed with every request 普通的推荐做法是在连接建立之后基于 ValueSet 建立起更加复杂的调用者鉴权 Whitelist could be followed by explicit X.509 certificate exchange http://windows.microsoft.com
版本更新 建议参考 Web REST API 的版本更新模型 If you need to make a breaking change to an App Service endpoint, you must expose a new endpoint and provide backward compatibility with the old one http://windows.microsoft.com
全新的电子墨水平台
书写是非常人性化的一种方式 实时 富于表现力 个性化 http://windows.microsoft.com
As easy as pen & paper with the power of a computer
电子墨水平台的作用 电子笔 作为 Inking 数据存储 添加元数据 ( 比如用于搜索 ) 手指 转换 ( 可以转成图形或者文字 ) http://windows.microsoft.com
http://windows.microsoft.com
http://windows.microsoft.com
http://windows.microsoft.com
http://windows.microsoft.com
What about this? As easy as pen & paper, but as powerful as a computer. J-K Copy Paste Convert to text http://windows.microsoft.com
What about this? As easy as pen & paper, but as powerful as a computer. J-K Copy Paste Convert to text http://windows.microsoft.com
http://windows.microsoft.com
开始使用 DirectInk InkCanvas InkPresenter http://windows.microsoft.com
InkCanvas 元素 <Grid> </Grid> <InkCanvas x:name="inkcanvas" /> http://windows.microsoft.com
利用 InkPresenter 做更多的事情 配置输入类型 ( 支持 Pen Touch Mouse) 改变渲染的属性 管理 Ink 笔画数据 管理更多自定义的选项 InkCanvas InkPresenter http://windows.microsoft.com
现有的属性以及功能 http://windows.microsoft.com
InkToolbar (Beta) Add inking tools UI to your app <InkCanvas Name="myCanvas" /> <inking:inktoolbar TargetInkCanvas="{x:Bind mycanvas}" /> Available through the Visual Studio Gallery http://aka.ms/inktoolbar http://windows.microsoft.com
Windows 10 上的全新电子墨水平台 DEMO http://windows.microsoft.com
Advanced Input Processing 自定义电子墨水的渲染 自定义渲染模式的墨迹的删除和选择 独立输入处理 多点电子墨水处理 InkCanvas InkPresenter http://windows.microsoft.com
吐司与磁贴
吐司 通知 (Toast)
ScheduledToastNotification
// build toast var template = ToastTemplateType.ToastText01; var xml = ToastNotificationManager.GetTemplateContent(template); xml.documentelement.setattribute("launch", "Args"); // set value var text = xml.createtextnode(content); var elements = xml.getelementsbytagname("text"); elements[0].appendchild(text); // show toast var toast = new ToastNotification(xml); var notifier = ToastNotificationManager.CreateToastNotifier(); notifier.show(toast);
// build toast // show toast var notifier = ToastNotificationManager.CreateToastNotifier(); notifier.show(toast);
if (args.kind == ActivationKind.Launch && args.arguments!= null && args.tileid!= "App") { /* handle toast */ } if (args.kind == ActivationKind.Launch && args.arguments == null && args.tileid!= "App") { /* handle primary tile (or toast) */ }
吐司怎么 吐 呢
<toast> <visual> <binding template="toastgeneric"> <image placement="applogooverride" src="torrance Shum.png" /> <text>torrance Shum</text> <text>media content attached.</text> <image placement="inline" src="attachment.png" /> <text>hey check out this photo. Isn t it awesome?</text> </binding> </visual> </toast>
<toast>... <actions> <input title= Snooze for id="snoozetime" type="selections" defaultselection= 5"> <selection id="5" content="5 minutes" /> <selection id="10" content="10 minutes" /> <selection id="20" content="20 minutes" /> </input>... </actions> </toast>
<toast>... <actions>... <action activationtype="system" arguments="snooze" hint-inputid="snoozetime" content=""/> <action activationtype="system" arguments="dismiss" content=""/> </actions> </actions> </toast>
<toast scenario= alarm...> <visual>... </visual> <actions> <action activationtype='system' arguments='snooze' content='' /> <action activationtype='system' arguments='dismiss' content=''/> </actions> </toast>
<toast>... <image placement="applogooverride" src="logo.png" />... <actions>... <action activationtype="background" arguments="dismiss" imageuri="send.png" hint-inputid="1" /> </actions> </toast>
<action activationtype="foreground" /> Tap button App launches Retrieve Args Take actions <action activationtype="background" /> Tap button Task launches Retrieve Args Take actions <action activationtype="protocol" /> Tap button Protocol activates Web / app <action activationtype="system" /> Tap button System handles
可交互吐司消息
动态磁贴
TileSmall TileMedium TileWide TileLarge Basic State Semi-Live State Live State
Basic State Semi-Live State Live State Plate App Logo Short Name Plate App Logo Badge Short Name Plate Content App Icon Badge Short Name Short Name App Logo Plate Badge Short Name App Logo Plate Badge App Icon Short Name Content Plate
// 创建 badge var type = BadgeTemplateType.BadgeNumber; var xml = BadgeUpdateManager.GetTemplateContent(type); // 更新元素 var elements = xml.getelementsbytagname("badge"); var element = elements[0] as Windows.Data.Xml.Dom.XmlElement; element.setattribute("value", "47"); // 发送更新 var updator = BadgeUpdateManager.CreateBadgeUpdaterForApplication(); var notification = new BadgeNotification(xml); updator.update(notification);
磁贴模板
var tileid = "DetailsTile"; var pinned = SecondaryTile.Exists(tileId); if (!pinned) { var tile = new SecondaryTile(tileId) { DisplayName = "Record details", Arguments = "123" }; // extra details } var success = await tile.requestcreateasync();
自适应磁贴
<tile> <visual> <binding template="tilemedium"> <group> <subgroup> <text hint-style="subtitle">john Doe</text> <text hint-style="subtle">photos from our trip</text> <text hint-style="subtle">thought you might </text> </subgroup> </group> <group> <subgroup> </subgroup> </group> </binding> </visual> Min. Med Size </tile> Max Med. Size
<tile> <visual> <binding template="tilemedium"> <image source="assets\image.png" placement="background" /> <text hint-wrap="true"> Microsoft HoloLens: A Sensational Vision of the PC s Future </text> </binding> </visual> </tile> Min. Med Size Max Med. Size
binding binding
binding text 9:50 AM, Wednesday text text 263 Grove St, San Francisco, CA 94102 text binding
binding group subgroup image subgroup subgroup text 9:50 AM, Wednesday text 263 Grove St, San Francisco, CA 94102 subgroup group binding
binding group subgroup image subgroup subgroup text 9:50 AM, Wednesday text text 263 Grove St, San Francisco, CA 94102 text subgroup group image binding
Adaptive Templates
自定义磁贴
用户交互 应用通信 UI 媒体 Inking Background Task Adaptive Layout HTTP Live Streaming Cortana Drag & Drog Continuum Media Cast Notification & Action Center App Service Adaptive Tiles Web 平台 Windows Hello Socket Broker Lock Screen Microsoft Edge App to App Web App
课后提醒
MSDN 论坛帮您解决开发中遇到的问题是我们最大的心愿 1 2 3 Windows10 通用应用及 Web App 技术讨论区 http://aka.ms/win10appde v Windows10 应用商店讨论区 http://aka.ms/win10appstore 微软云 Azure 开发技术讨论区 http://aka.ms/azurediscussion
https://channel9.msdn.com/events/ignite/ Microsoft-Ignite-China-2015 http://aka.ms/ignitechina2015