背水一战 Windows 10 (109) - 通知(Tile): 按计划显示 tile 通知, 轮询服务端以更新 tile 通知
作者:webabcd
介绍
背水一战 Windows 10 之 通知(Tile)
- 按计划显示 tile 通知
- 轮询服务端以更新 tile 通知
示例
1、演示如何按计划显示 tile 通知(在指定的时间显示指定的 tile 通知,此特性在 application tile 和 secondary tile 中均支持)
Notification/Tile/Schedule.xaml
<Page x:Class="Windows10.Notification.Tile.Schedule" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Notification.Tile" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <TextBlock Name="lblMsg" Margin="5" /> <!--显示指定 secondary tile 的全部 ScheduledTileNotification 列表--> <ListBox Name="listBox" Width="800" Height="400" Margin="5" HorizontalAlignment="Left"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Id}" VerticalAlignment="Center" /> <TextBlock Text="{Binding Tag}" Margin="15 0 0 0" VerticalAlignment="Center" /> <HyperlinkButton Name="btnRemoveScheduledTile" Content="删除此 ScheduledTileNotification" Tag="{Binding Id}" Margin="15 0 0 0" Click="btnRemoveScheduledTile_Click" /> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <Button Name="btnAddScheduledTile" Content="添加指定的 ScheduledTileNotification 到指定的 secondary tile 的计划列表中" Click="btnAddScheduledTile_Click" Margin="5" /> </StackPanel> </Grid> </Page>
Notification/Tile/Schedule.xaml.cs
/* * 演示如何按计划显示 tile 通知(在指定的时间显示指定的 tile 通知,此特性在 application tile 和 secondary tile 中均支持) * * ScheduledTileNotification - 按计划显示的 Tile 通知 * Content - Tile 的内容,XmlDocument 类型的数据,只读,其需要在构造函数中指定 * DeliveryTime - 显示 Tile 通知的时间,只读,其需要在构造函数中指定 * ExpirationTime - Tile 通知的过期时间,超过这个时间就会清除这个 Tile * Id - ScheduledTileNotification 的标识 * Tag - 在启用 tile 的队列功能时,如果 tile 的 Tag 相同则新的内容会更新旧的内容(Tag 值的前 16 个字符相同则认为是相同的 Tag) * 不指定的 Tag 的话则认为 Tag 都是不同的 * * TileUpdater - 磁贴的 Tile 更新器 * AddToSchedule() - 将指定的 ScheduledTileNotification 对象添加到计划列表 * RemoveFromSchedule() - 从计划列表中移除指定的 ScheduledTileNotification 对象 * GetScheduledTileNotifications() - 获取全部 ScheduledTileNotification 对象列表 */ using System; using System.Collections.Generic; using Windows.Data.Xml.Dom; using Windows.UI.Notifications; using Windows.UI.StartScreen; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; namespace Windows10.Notification.Tile { public sealed partial class Schedule : Page { private const string TILEID = "tile_schedule"; public Schedule() { this.InitializeComponent(); } // 在开始屏幕固定一个 secondary tile 磁贴 protected async override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); Uri square150x150Logo = new Uri("ms-appx:///Assets/Square150x150Logo.png"); Uri wide310x150Logo = new Uri("ms-appx:///Assets/Wide310x150Logo.png"); Uri square310x310Logo = new Uri("ms-appx:///Assets/Square310x310Logo.png"); SecondaryTile secondaryTile = new SecondaryTile(TILEID, "name", "arguments", square150x150Logo, TileSize.Wide310x150); secondaryTile.VisualElements.Wide310x150Logo = wide310x150Logo; secondaryTile.VisualElements.Square310x310Logo = square310x310Logo; try { bool isPinned = await secondaryTile.RequestCreateAsync(); lblMsg.Text = isPinned ? "固定成功" : "固定失败"; } catch (Exception ex) { lblMsg.Text = "固定失败: " + ex.ToString(); } ShowScheduledTiles(); } // 添加指定的 ScheduledTileNotification 到指定的 secondary tile 的计划列表中 private void btnAddScheduledTile_Click(object sender, RoutedEventArgs e) { string tileXml = $@" <tile> <visual> <binding template='TileSmall'> <text>Small(小){DateTime.Now.ToString("HH:mm:ss")}</text> </binding> <binding template='TileMedium'> <text>Medium(中){DateTime.Now.ToString("HH:mm:ss")}</text> </binding> <binding template='TileWide'> <text>Wide(宽){DateTime.Now.ToString("HH:mm:ss")}</text> </binding> <binding template='TileLarge'> <text>Large(大){DateTime.Now.ToString("HH:mm:ss")}</text> </binding> </visual> </tile>"; XmlDocument tileDoc = new XmlDocument(); tileDoc.LoadXml(tileXml); // 实例化 ScheduledTileNotification 对象(15 秒后显示此 Tile 通知) DateTime dt = DateTime.Now.AddSeconds(15); ScheduledTileNotification tileNotification = new ScheduledTileNotification(tileDoc, dt); tileNotification.Id = new Random().Next(100000, 1000000).ToString(); ; tileNotification.Tag = $"在 {dt.ToString("HH:mm:ss")} 时显示此 tile 通知"; // 将指定的 ScheduledTileNotification 对象添加进指定的 secondary tile 的计划列表 TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(TILEID); tileUpdater.AddToSchedule(tileNotification); tileUpdater.EnableNotificationQueue(true); // 启用 tile 的队列功能(最多可容纳 5 个 tile) ShowScheduledTiles(); } // 删除指定 secondary tile 的指定 ScheduledTileNotification 对象 private void btnRemoveScheduledTile_Click(object sender, RoutedEventArgs e) { string notificationId = (string)(sender as FrameworkElement).Tag; // 获取指定 secondary tile 的全部 ScheduledTileNotification 对象列表 TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(TILEID); IReadOnlyList<ScheduledTileNotification> notifications = tileUpdater.GetScheduledTileNotifications(); int notificationCount = notifications.Count; for (int i = 0; i < notificationCount; i++) { if (notifications[i].Id == notificationId) { // 从计划列表中移除指定的 ScheduledTileNotification 对象 tileUpdater.RemoveFromSchedule(notifications[i]); break; } } ShowScheduledTiles(); } // 显示指定 secondary tile 的全部 ScheduledTileNotification 列表 private void ShowScheduledTiles() { // 获取指定 secondary tile 的全部 ScheduledTileNotification 对象列表 TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(TILEID); IReadOnlyList<ScheduledTileNotification> notifications = tileUpdater.GetScheduledTileNotifications(); listBox.ItemsSource = notifications; } } }
2、演示如何轮询服务端以更新 tile 通知
Notification/Tile/Periodic.xaml
<Page x:Class="Windows10.Notification.Tile.Periodic" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Windows10.Notification.Tile" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="10 0 10 10"> <TextBlock Name="lblMsg" Margin="5" /> <Button Name="btnStartPeriodicUpdate" Content="启动一个“轮询服务端获取数据,然后更新 Tile 通知”的任务" Click="btnStartPeriodicUpdate_Click" Margin="5" /> </StackPanel> </Grid> </Page>
Notification/Tile/Periodic.xaml.cs
/* * 演示如何轮询服务端以更新 tile 通知 * * TileUpdater - 磁贴的 Tile 更新器 * StartPeriodicUpdate(Uri tileContent, DateTimeOffset startTime, PeriodicUpdateRecurrence requestedInterval) - 启动一个“轮询服务端获取数据,然后更新 Tile 通知”的任务 * StartPeriodicUpdateBatch(IEnumerable<Uri> tileContents, DateTimeOffset startTime, PeriodicUpdateRecurrence requestedInterval) - 启动一个“轮询服务端获取数据,然后更新 Tile 通知”的任务 * tileContent - Tile 通知的内容(xml 格式数据)的 uri 地址(通过 StartPeriodicUpdateBatch 方法指定多个则会循环显示) * startTime - 可以指定启动此任务的时间 * 指定此值时的逻辑为:首先会立刻请求服务端获取数据,然后在到达 startTime 指定的时间点后再次获取数据,最后再每次按 requestedInterval 指定的间隔轮询服务端 * requestedInterval - 轮询服务端的周期(PeriodicUpdateRecurrence 枚举) * HalfHour, Hour, SixHours, TwelveHours, Daily * StopPeriodicUpdate() - 停止“轮询服务端获取数据,然后更新 Tile 通知”的任务 * * * 注:服务端代码请参见 WebApi/Controllers/TileContentController.cs(有指定 X-WNS-Expires 标头和 X-WNS-Tag 标头的示例) */ using System; using Windows.UI.Notifications; using Windows.UI.StartScreen; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Navigation; namespace Windows10.Notification.Tile { public sealed partial class Periodic : Page { private const string TILEID = "tile_periodic"; public Periodic() { this.InitializeComponent(); } // 在开始屏幕固定一个 secondary tile 磁贴 protected async override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); Uri square150x150Logo = new Uri("ms-appx:///Assets/Square150x150Logo.png"); Uri wide310x150Logo = new Uri("ms-appx:///Assets/Wide310x150Logo.png"); Uri square310x310Logo = new Uri("ms-appx:///Assets/Square310x310Logo.png"); SecondaryTile secondaryTile = new SecondaryTile(TILEID, "name", "arguments", square150x150Logo, TileSize.Wide310x150); secondaryTile.VisualElements.Wide310x150Logo = wide310x150Logo; secondaryTile.VisualElements.Square310x310Logo = square310x310Logo; try { bool isPinned = await secondaryTile.RequestCreateAsync(); lblMsg.Text = isPinned ? "固定成功" : "固定失败"; } catch (Exception ex) { lblMsg.Text = "固定失败: " + ex.ToString(); } } // 启动一个“轮询服务端获取数据,然后更新 Tile 通知”的任务 private void btnStartPeriodicUpdate_Click(object sender, RoutedEventArgs e) { // 启动一个循环更新 Tile 通知的任务,并指定 Tile 通知的数据源和轮询周期 TileUpdater tileUpdater = TileUpdateManager.CreateTileUpdaterForSecondaryTile(TILEID); tileUpdater.EnableNotificationQueue(true); // 启用 tile 的队列功能(最多可容纳 5 个 tile) // 马上请求服务端获取数据,然后 45 分钟之后再次获取数据,最后再每半个小时获取一次数据 tileUpdater.StartPeriodicUpdate(new Uri("http://localhost:44914/api/TileContent", UriKind.Absolute), DateTimeOffset.UtcNow.AddMinutes(45), PeriodicUpdateRecurrence.HalfHour); // Tile 通知的数据源示例请参见 WebApi/Controllers/TileContentController.cs } } }
/WebApi/Controllers/TileContentController.cs(服务端代码)
/* * 用于演示“轮询服务端以更新 tile 通知”的服务端部分 */ using System; using System.Net.Http; using System.Text; using System.Web.Http; namespace WebApi.Controllers { public class TileContentController : ApiController { private Random _random = new Random(); [HttpGet] public HttpResponseMessage Get() { string tileXml = $@" <tile> <visual> <binding template='TileSmall'> <text>Small(小){DateTime.Now.ToString("HH:mm:ss")}</text> </binding> <binding template='TileMedium'> <text>Medium(中){DateTime.Now.ToString("HH:mm:ss")}</text> </binding> <binding template='TileWide'> <text>Wide(宽){DateTime.Now.ToString("HH:mm:ss")}</text> </binding> <binding template='TileLarge'> <text>Large(大){DateTime.Now.ToString("HH:mm:ss")}</text> </binding> </visual> </tile>"; HttpResponseMessage result = new HttpResponseMessage { Content = new StringContent(tileXml, Encoding.UTF8, "text/html") }; // Tile 通知的过期时间,超过这个时间就会清除这个 Tile(对于“轮询服务端以更新 Tile 通知”来说,如果不指定此值,则默认 3 天后过期) // 通过 ToString("R") 可以把日期格式化为“RFC 1123”格式 result.Headers.Add("X-WNS-Expires", DateTime.UtcNow.AddSeconds(60).ToString("R")); // 60 秒后过期 // 在启用 tile 的队列功能时,如果 tile 的 Tag 相同则新的内容会更新旧的内容(Tag 值的前 16 个字符相同则认为是相同的 Tag) // 不指定的 Tag 的话则认为 Tag 都是不同的 result.Headers.Add("X-WNS-Tag", _random.Next().ToString()); return result; } } }
OK
[源码下载]