教程:向运行通用 Windows 平台应用程序的特定 Windows 设备推送通知Tutorial: Push notifications to specific Windows devices running Universal Windows Platform applications

概述Overview

本教程演示如何使用 Azure 通知中心将突发新闻通知广播到 Windows 应用商店或 Windows Phone 8.1(非 Silverlight)应用程序。This tutorial shows you how to use Azure Notification Hubs to broadcast breaking news notifications to a Windows Store or Windows Phone 8.1 (non-Silverlight) applications. 如果要以 Windows Phone 8.1 Silverlight 为目标,请参阅 Windows Phone 版本。If you are targeting Windows Phone 8.1 Silverlight, see Windows Phone version.

本教程介绍如何使用 Azure 通知中心将通知推送到运行通用 Windows 平台 (UWP) 应用程序的特定 Windows 设备。In this tutorial, you learn how to use Azure Notification Hubs to push notifications to specific Windows devices running Universal Windows Platform (UWP) application. 完成本教程后,可注册感兴趣的突发新闻类别,之后你仅会收到这些类别的推送通知。After you complete the tutorial, you can register for the breaking news categories that you are interested in, and you'll receive push notifications for those categories only.

在通知中心创建注册时,通过加入一个或多个标记来启用广播方案。Broadcast scenarios are enabled by including one or more tags when you create a registration in the notification hub. 将通知发送到标记时,已注册该标记的所有设备将接收通知。When notifications are sent to a tag, all devices that have registered for the tag receive the notification. 有关标记的详细信息,请参阅注册中的标记For more information about tags, see Tags in Registrations.

Note

Visual Studio 2017 中不支持 Windows 应用商店和 Windows Phone 项目 8.1 及更早的版本。Windows Store and Windows Phone project versions 8.1 and earlier are not supported in Visual Studio 2017. 有关详细信息,请参阅 Visual Studio 2017 平台目标以及兼容性For more information, see Visual Studio 2017 Platform Targeting and Compatibility.

在本教程中,我们将执行以下步骤:In this tutorial, you take the following steps:

  • 向移动应用添加类别选择Add category selection to the mobile app
  • 注册通知Register for notifications
  • 发送带标记的通知Send tagged notification
  • 运行应用并生成通知Run the app and generate notifications

先决条件Prerequisites

在开始本教程之前完成教程:使用 Azure 通知中心向通用 Windows 平台应用发送通知Complete the Tutorial: Send notifications to Universal Windows Platform apps by using Azure Notification Hubs before starting this tutorial.

向应用程序中添加类别选择Add category selection to the app

第一步是向现有主页添加 UI 元素,以便用户选择要注册的类别。The first step is to add UI elements to your existing main page so that users can select categories to register. 所选类别会存储在设备上。The selected categories are stored on the device. 应用启动时,系统会将所选类别当做标记在通知中心创建设备注册。When the app starts, a device registration is created in your notification hub, with the selected categories as tags.

  1. 打开 MainPage.xaml 项目文件,并复制 Grid 元素中的以下代码:Open the MainPage.xaml project file, and then copy the following code in the Grid element:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"  TextWrapping="Wrap" Text="Breaking News" FontSize="42" VerticalAlignment="Top" HorizontalAlignment="Center"/>
        <ToggleSwitch Header="World" Name="WorldToggle" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center"/>
        <ToggleSwitch Header="Politics" Name="PoliticsToggle" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Center"/>
        <ToggleSwitch Header="Business" Name="BusinessToggle" Grid.Row="3" Grid.Column="0" HorizontalAlignment="Center"/>
        <ToggleSwitch Header="Technology" Name="TechnologyToggle" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center"/>
        <ToggleSwitch Header="Science" Name="ScienceToggle" Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center"/>
        <ToggleSwitch Header="Sports" Name="SportsToggle" Grid.Row="3" Grid.Column="1" HorizontalAlignment="Center"/>
        <Button Name="SubscribeButton" Content="Subscribe" HorizontalAlignment="Center" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" Click="SubscribeButton_Click"/>
    </Grid>
    
  2. 在“解决方案资源管理器”中,右键单击项目,然后添加新类:NotificationsIn Solution Explorer, right-click the project, add a new class: Notifications. 向类定义添加 public 修饰符,然后将以下 using 语句添加到新的代码文件:Add the public modifier to the class definition, and then add the following using statements to the new code file:

    using Windows.Networking.PushNotifications;
    using Microsoft.WindowsAzure.Messaging;
    using Windows.Storage;
    using System.Threading.Tasks;
    
  3. 将以下代码复制到新的 Notifications 类:Copy the following code to the new Notifications class:

    private NotificationHub hub;
    
    public Notifications(string hubName, string listenConnectionString)
    {
        hub = new NotificationHub(hubName, listenConnectionString);
    }
    
    public async Task<Registration> StoreCategoriesAndSubscribe(IEnumerable<string> categories)
    {
        ApplicationData.Current.LocalSettings.Values["categories"] = string.Join(",", categories);
        return await SubscribeToCategories(categories);
    }
    
    public IEnumerable<string> RetrieveCategories()
    {
        var categories = (string) ApplicationData.Current.LocalSettings.Values["categories"];
        return categories != null ? categories.Split(','): new string[0];
    }
    
    public async Task<Registration> SubscribeToCategories(IEnumerable<string> categories = null)
    {
        var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    
        if (categories == null)
        {
            categories = RetrieveCategories();
        }
    
        // Using a template registration to support notifications across platforms.
        // Any template notifications that contain messageParam and a corresponding tag expression
        // will be delivered for this registration.
    
        const string templateBodyWNS = "<toast><visual><binding template=\"ToastText01\"><text id=\"1\">$(messageParam)</text></binding></visual></toast>";
    
        return await hub.RegisterTemplateAsync(channel.Uri, templateBodyWNS, "simpleWNSTemplateExample",
                categories);
    }
    

    此类使用本地存储区存储此设备必须接收的新闻类别。This class uses the local storage to store the categories of news that this device must receive. 使用模板注册来注册类别时,应调用 RegisterTemplateAsync 方法,而不能调用 RegisterNativeAsyncInstead of calling the RegisterNativeAsync method, call RegisterTemplateAsync to register for the categories by using a template registration.

    如果需要注册多个模板(例如一个模板针对 toast 通知,一个模板针对磁贴),请提供模板名称(例如“simpleWNSTemplateExample”)。If you want to register more than one template (for example, one for toast notifications and one for tiles), provide a template name (for example, "simpleWNSTemplateExample"). 为模板命名以便更新或删除模板。You name the templates so that you can update or delete them.

    Note

    如果一个设备使用同一标记注册多个模板,针对该标记的传入消息会导致系统向该设备发送多个通知(每个通知对应一个模板)。If a device registers multiple templates with the same tag, an incoming message that targets the tag causes multiple notifications to be delivered to the device (one for each template). 当同一逻辑消息必定导致多个可视化通知时(例如,在 Windows 应用商店应用程序中同时显示徽章和 toast),此行为很有用。This behavior is useful when the same logical message must result in multiple visual notifications (for example, showing both a badge and a toast in a Windows Store application).

    有关详细信息,请参阅模板For more information, see Templates.

  4. 在 App.xaml.cs 项目文件中,将以下属性添加到 App 类:In the App.xaml.cs project file, add the following property to the App class:

    public Notifications notifications = new Notifications("<hub name>", "<connection string with listen access>");
    

    使用此属性创建和访问 Notifications 实例。You use this property to create and access a Notifications instance.

    在代码中,将 <hub name><connection string with listen access> 占位符替换为通知中心的名称和之前获取的 DefaultListenSharedAccessSignature 的连接字符串。In the code, replace the <hub name> and <connection string with listen access> placeholders with your notification hub name and the connection string for DefaultListenSharedAccessSignature, which you obtained earlier.

    Note

    使用客户端应用分发的凭据通常不安全,因此请使用客户端应用仅分发具有侦听访问权限的密钥。Because credentials that are distributed with a client app are not usually secure, distribute only the key for listen access with your client app. 拥有侦听访问权限后,应用可注册通知,但是无法修改现有注册,也无法发送通知。With listen access, your app can register for notifications, but existing registrations cannot be modified, and notifications cannot be sent. 在受保护的后端服务中使用完全访问权限密钥,以便发送通知和更改现有注册。The full access key is used in a secured back-end service for sending notifications and changing existing registrations.

  5. MainPage.xaml.cs 文件中添加以下行:In the MainPage.xaml.cs file, add the following line:

    using Windows.UI.Popups;
    
  6. MainPage.xaml.cs 文件中添加以下方法:In the MainPage.xaml.cs file, add the following method:

    private async void SubscribeButton_Click(object sender, RoutedEventArgs e)
    {
        var categories = new HashSet<string>();
        if (WorldToggle.IsOn) categories.Add("World");
        if (PoliticsToggle.IsOn) categories.Add("Politics");
        if (BusinessToggle.IsOn) categories.Add("Business");
        if (TechnologyToggle.IsOn) categories.Add("Technology");
        if (ScienceToggle.IsOn) categories.Add("Science");
        if (SportsToggle.IsOn) categories.Add("Sports");
    
        var result = await ((App)Application.Current).notifications.StoreCategoriesAndSubscribe(categories);
    
        var dialog = new MessageDialog("Subscribed to: " + string.Join(",", categories) + " on registration Id: " + result.RegistrationId);
        dialog.Commands.Add(new UICommand("OK"));
        await dialog.ShowAsync();
    }
    

    此方法创建一个类别列表并使用 Notifications 类将该列表存储在本地存储中。This method creates a list of categories and uses the Notifications class to store the list in the local storage. 它还会向通知中心注册相应的标记。It also registers the corresponding tags with your notification hub. 类别有更改时,会使用新类别重新创建注册。When the categories are changed, the registration is re-created with the new categories.

现在,应用可在设备的本地存储中存储一组类别。Your app can now store a set of categories in local storage on the device. 每当用户更改类别选择时,应用都会向通知中心注册。The app registers with the notification hub whenever users change the category selection.

注册通知Register for notifications

本部分中将使用存储在本地存储中的类别,在启动时向通知中心注册。In this section, you register with the notification hub on startup by using the categories that you've stored in local storage.

Note

由于 Windows 通知服务 (WNS) 分配的通道 URI 随时可能更改,因此应该经常注册通知以避免通知失败。Because the channel URI that's assigned by the Windows Notification Service (WNS) can change at any time, you should register for notifications frequently to avoid notification failures. 此示例在每次应用程序启动时注册通知。This example registers for notification every time that the app starts. 对于经常运行(一天一次以上)的应用,如果距上次注册时间不到一天,可以跳过注册,以节省带宽。For apps that you run frequently (more than once a day), you can probably skip registration to preserve bandwidth if less than a day has passed since the previous registration.

  1. 若要使用 notifications 类基于类别订阅,请打开 App.xaml.cs 文件,然后更新 InitNotificationsAsync 方法。To use the notifications class to subscribe based on categories, open the App.xaml.cs file, and then update the InitNotificationsAsync method.

    // *** Remove or comment out these lines ***
    //var channel = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
    //var hub = new NotificationHub("your hub name", "your listen connection string");
    //var result = await hub.RegisterNativeAsync(channel.Uri);
    
    var result = await notifications.SubscribeToCategories();
    

    此过程可确保应用启动时会从本地存储区检索类别并请求注册这些类别。This process ensures that when the app starts, it retrieves the categories from local storage and requests registration of these categories. 你已在通知中心入门教程中创建 InitNotificationsAsync 方法。You created the InitNotificationsAsync method as part of the Get started with Notification Hubs tutorial.

  2. MainPage.xaml.cs 项目文件的 OnNavigatedTo 方法中添加以下代码:In the MainPage.xaml.cs project file, add the following code to the OnNavigatedTo method:

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        var categories = ((App)Application.Current).notifications.RetrieveCategories();
    
        if (categories.Contains("World")) WorldToggle.IsOn = true;
        if (categories.Contains("Politics")) PoliticsToggle.IsOn = true;
        if (categories.Contains("Business")) BusinessToggle.IsOn = true;
        if (categories.Contains("Technology")) TechnologyToggle.IsOn = true;
        if (categories.Contains("Science")) ScienceToggle.IsOn = true;
        if (categories.Contains("Sports")) SportsToggle.IsOn = true;
    }
    

    此代码基于以前保存的类别状态更新主页。This code updates the main page, based on the status of previously saved categories.

应用现已完成。The app is now complete. 它可以在设备的本地存储中存储一组类别,当用户更改类别选择时,使用它向通知中心注册。It can store a set of categories in the device local storage that's used to register with the notification hub when users change the category selection. 下一部分将定义一个后端,该后端可将类别通知发送到此应用。In the next section, you define a back end that can send category notifications to this app.

发送带标记的通知Send tagged notifications

本部分说明如何从 .NET 控制台应用以标记模板通知的形式发送突发新闻。In this section, you send breaking news as tagged template notifications from a .NET console app.

  1. 在 Visual Studio 中创建新的 Visual C# 控制台应用程序:a.In Visual Studio, create a new Visual C# console application: a. 在菜单中,选择“文件” > “新建” > “项目”。On the menu, select File > New > Project. b.b. 展开“Visual C#”,然后选择“Windows 桌面”。Expand Visual C#, and select Windows Desktop. c.c. 在模板列表中选择“控制台应用(.NET Framework)”。Select Console App (.NET Framework) in the list of templates. d.d. 输入应用的名称Enter a name for the app. e.e. 为应用选择文件夹Select a folder for the app. f.f. 选择“确定”创建该项目。Select OK to create the project.

  2. 在 Visual Studio 主菜单中,选择“工具” > “NuGet 包管理器” > “包管理器控制台”,并在控制台窗口中输入以下字符串:On the Visual Studio main menu, select Tools > NuGet Package Manager > Package Manager Console and then, in the console window, enter the following string:

    Install-Package Microsoft.Azure.NotificationHubs
    
  3. EnterSelect Enter.
    此操作会使用 Microsoft.Azure.Notification Hubs NuGet 包添加对 Azure 通知中心 SDK 的引用。This action adds a reference to the Azure Notification Hubs SDK by using the Microsoft.Azure.Notification Hubs NuGet package.

  4. 打开文件 Program.cs 并添加以下 using 语句:Open the Program.cs file, and add the following using statement:

    using Microsoft.Azure.NotificationHubs;
    
  5. Program 类中,添加以下方法,或替换此方法(如果已存在):In the Program class, add the following method, or replace it if it already exists:

    private static async void SendTemplateNotificationAsync()
    {
        // Define the notification hub.
        NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString("<connection string with full access>", "<hub name>");
    
        // Create an array of breaking news categories.
        var categories = new string[] { "World", "Politics", "Business", "Technology", "Science", "Sports"};
    
        // Send the notification as a template notification. All template registrations that contain
        // "messageParam" and the proper tags will receive the notifications.
        // This includes APNS, WNS, and MPNS template registrations.
    
        Dictionary<string, string> templateParams = new Dictionary<string, string>();
    
        foreach (var category in categories)
        {
            templateParams["messageParam"] = "Breaking " + category + " News!";
            await hub.SendTemplateNotificationAsync(templateParams, category);
        }
    }
    

    此代码针对字符串数组中的所有 6 个标记发送模板通知。This code sends a template notification for each of the six tags in the string array. 使用标记是为了确保设备仅接收已注册类别的通知。The use of tags ensures that devices receive notifications only for the registered categories.

  6. 在前面的代码中,将 <hub name><connection string with full access> 占位符替换为通知中心名称和从通知中心仪表板获取的 DefaultFullSharedAccessSignature 的连接字符串。In the preceding code, replace the <hub name> and <connection string with full access> placeholders with your notification hub name and the connection string for DefaultFullSharedAccessSignature from the dashboard of your notification hub.

  7. Main 方法中添加以下行:In the Main method, add the following lines:

    SendTemplateNotificationAsync();
    Console.ReadLine();
    
  8. 生成控制台应用。Build the console app.

运行应用并生成通知Run the app and generate notifications

  1. 在 Visual Studio 中,选择 F5 编译并启动应用。In Visual Studio, select F5 to compile and start the app. 应用 UI 提供了一组开关,可以使用它们选择要订阅的类别。The app UI provides a set of toggles that lets you choose the categories to subscribe to.

    突发新闻应用

  2. 启用一个或多个类别切换,然后单击“订阅”。Enable one or more category toggles, and then click Subscribe.

    应用程序将所选类别转换为标签并针对所选标签从通知中心请求注册新设备。The app converts the selected categories into tags and requests a new device registration for the selected tags from the notification hub. 返回注册的类别并显示在对话框中。The registered categories are returned and displayed in a dialog box.

    类别切换和订阅按钮

创建一个控制台应用以发送带标记的通知Create a console app to send tagged notifications

本部分说明如何从 .NET 控制台应用以标记模板通知的形式发送突发新闻。In this section, you send breaking news as tagged template notifications from a .NET console app.

  1. 在 Visual Studio 中创建新的 Visual C# 控制台应用程序:a.In Visual Studio, create a new Visual C# console application: a. 在菜单中,选择“文件” > “新建” > “项目”。On the menu, select File > New > Project. b.b. 展开“Visual C#”,然后选择“Windows 桌面”。Expand Visual C#, and select Windows Desktop. c.c. 在模板列表中选择“控制台应用(.NET Framework)”。Select Console App (.NET Framework) in the list of templates. d.d. 输入应用的名称Enter a name for the app. e.e. 为应用选择文件夹Select a folder for the app. f.f. 选择“确定”创建该项目。Select OK to create the project.

  2. 在 Visual Studio 主菜单中,选择“工具” > “NuGet 包管理器” > “包管理器控制台”,并在控制台窗口中输入以下字符串:On the Visual Studio main menu, select Tools > NuGet Package Manager > Package Manager Console and then, in the console window, enter the following string:

    Install-Package Microsoft.Azure.NotificationHubs
    
  3. EnterSelect Enter.
    此操作会使用 Microsoft.Azure.Notification Hubs NuGet 包添加对 Azure 通知中心 SDK 的引用。This action adds a reference to the Azure Notification Hubs SDK by using the Microsoft.Azure.Notification Hubs NuGet package.

  4. 打开文件 Program.cs 并添加以下 using 语句:Open the Program.cs file, and add the following using statement:

    using Microsoft.Azure.NotificationHubs;
    
  5. Program 类中,添加以下方法,或替换此方法(如果已存在):In the Program class, add the following method, or replace it if it already exists:

    private static async void SendTemplateNotificationAsync()
    {
        // Define the notification hub.
        NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString("<connection string with full access>", "<hub name>");
    
        // Create an array of breaking news categories.
        var categories = new string[] { "World", "Politics", "Business", "Technology", "Science", "Sports"};
    
        // Send the notification as a template notification. All template registrations that contain
        // "messageParam" and the proper tags will receive the notifications.
        // This includes APNS, WNS, and MPNS template registrations.
    
        Dictionary<string, string> templateParams = new Dictionary<string, string>();
    
        foreach (var category in categories)
        {
            templateParams["messageParam"] = "Breaking " + category + " News!";
            await hub.SendTemplateNotificationAsync(templateParams, category);
        }
    }
    

    此代码针对字符串数组中的所有 6 个标记发送模板通知。This code sends a template notification for each of the six tags in the string array. 使用标记是为了确保设备仅接收已注册类别的通知。The use of tags ensures that devices receive notifications only for the registered categories.

  6. 在前面的代码中,将 <hub name><connection string with full access> 占位符替换为通知中心名称和从通知中心仪表板获取的 DefaultFullSharedAccessSignature 的连接字符串。In the preceding code, replace the <hub name> and <connection string with full access> placeholders with your notification hub name and the connection string for DefaultFullSharedAccessSignature from the dashboard of your notification hub.

  7. Main 方法中添加以下行:In the Main method, add the following lines:

    SendTemplateNotificationAsync();
    Console.ReadLine();
    
  8. 生成控制台应用。Build the console app.

运行控制台应用以发送带标记的通知Run the console app to send tagged notifications

  1. 运行上一部分中创建的应用。Run the app created in the previous section.

  2. 所选类别的通知作为 toast 通知显示。Notifications for the selected categories appear as toast notifications. 如果选择通知,则会看到第一个 UWP 应用窗口。If you select the notification, you see the first UWP app window.

    Toast 通知

后续步骤Next steps

我们已通过本文了解了如何按类别广播突发新闻。In this article, you learned how to broadcast breaking news by category. 后端应用程序将带标记的通知推送到特定设备,这些设备已注册接收该标记的通知。The backend application pushes tagged notifications to devices that have registered to receive notifications for that tag. 若要了解如何向特定用户推送通知而不管这些用户使用什么设备,请转到以下教程:To learn how to push notifications to specific users irrespective of what device they use, advance to the following tutorial: