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

概述Overview

本教程演示如何使用 Azure 通知中心来广播突发新闻通知。This tutorial shows you how to use Azure Notification Hubs to broadcast breaking news notifications. 本教程涵盖 Windows 应用商店或 Windows Phone 8.1(非 Silverlight)应用程序。This tutorial covers Windows Store or Windows Phone 8.1 (non-Silverlight) applications. 如果你的目标是 Windows Phone 8.1 Silverlight,请参阅使用 Azure 通知中心向特定 Windows Phone 设备推送通知If you're targeting Windows Phone 8.1 Silverlight, see Push notifications to specific Windows Phone devices by using Azure Notification Hubs.

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

在通知中心创建注册时,可通过加入一个或多个标记来启用广播方案 。To enable broadcast scenarios, include one or more tags when you create a registration in the notification hub. 将通知发送到标记时,已注册该标记的所有设备将接收通知。When notifications are sent to a tag, all devices that are registered for the tag receive the notification. 有关标记的详细信息,请参阅路由和标记表达式For more information about tags, see Routing and tag expressions.

备注

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

在本教程中,你将执行以下任务:In this tutorial, you do the following tasks:

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

先决条件Prerequisites

在开始学习本教程之前完成[教程:使用 Azure 通知中心向通用 Windows 平台应用发送通知][get-started]。Complete the [Tutorial: Send notifications to Universal Windows Platform apps by using Azure Notification Hubs][get-started] 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, it creates a device registration 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. 在“解决方案资源管理器” 中,右键单击该项目,然后选择“添加” > “类”。In Solution Explorer, right-click the project, select Add > Class. 在“添加新项”中,将类命名为 Notifications,然后选择“添加”。 In Add New Item, name the class Notifications, and select Add. 必要时向类定义添加 public 修饰符。If necessary, add the public modifier to the class definition.

  3. 向新文件添加以下 using 语句:Add the following using statements to the new file:

    using Windows.Networking.PushNotifications;
    using Microsoft.WindowsAzure.Messaging;
    using Windows.Storage;
    using System.Threading.Tasks;
    
  4. 将以下代码复制到新的 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.

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

    备注

    通过通知中心,设备可使用同一标记注册多个模板。With Notification Hubs, a device can register multiple templates by using the same tag. 在这种情况下,针对该标签的传入的邮件将导致系统向设备发送多个通知(每个通知对应一个模板)。In this case, an incoming message that targets the tag results in multiple notifications being delivered to the device, one for each template. 此过程可以在多个可视通知中显示同一消息,如显示为 Windows 应用商店应用中的徽章和 toast 通知。This process enables you to display the same message in multiple visual notifications, such as both as a badge and as a toast notification in a Windows Store app.

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

  5. 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.

    备注

    使用客户端应用分发的凭据通常不安全,因此请使用客户端应用仅分发具有侦听访问权限的密钥 。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.

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

    using Windows.UI.Popups;
    
  7. 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 change, 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.

备注

由于 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, say, 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. 并请求注册这些类别。It then requests registration of these categories. 我们已在[使用 Azure 通知中心向通用 Windows 平台应用发送通知][get-started]教程中创建 InitNotificationsAsync 方法。You created the InitNotificationsAsync method as part of the [Send notifications to Universal Windows Platform apps by using Azure Notification Hubs][get-started] 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. 当用户更改类别选择时,保存的类别用于向通知中心注册。When users change the category selection, the saved categories are used to register with the notification hub. 下一部分将定义一个后端,该后端可将类别通知发送到此应用。In the next section, you define a back end that can send category notifications to this app.

运行 UWP 应用Run the UWP app

  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 select Subscribe.

    应用程序将所选类别转换为标签并针对所选标签从通知中心请求注册新设备。The app converts the selected categories into tags and requests a new device registration for the selected tags from the notification hub. 应用在对话框中显示注册的类别。The app displays the registered categories 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# 控制台应用程序:In Visual Studio, create a new Visual C# console application:

    1. 在菜单中,选择“文件” > “新建” > “项目” 。On the menu, select File > New > Project.
    2. 在“创建新项目”中,选择模板列表中适用于 C# 的“控制台应用(.NET Framework)”,然后选择“下一步”。 In Create a new project, select Console App (.NET Framework) for C# in the list of templates, and select Next.
    3. 输入应用程序的名称。Enter a name for the app.
    4. 对于“解决方案” ,选择“添加到解决方案” ,然后选择“创建” 以创建项目。For Solution, choose Add to solution, and select Create to create the project.
  2. 选择“工具” > “NuGet 包管理器” > “包管理器控制台”,然后在控制台窗口中运行以下命令 :Select Tools > NuGet Package Manager > Package Manager Console and then, in the console window, run the following command:

    Install-Package Microsoft.Azure.NotificationHubs
    

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

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

    using Microsoft.Azure.NotificationHubs;
    
  4. 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>");
    
        // Apple requires the apns-push-type header for all requests
        var headers = new Dictionary<string, string> {{"apns-push-type", "alert"}};
    
        // 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.

  5. 在前面的代码中,将 <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.

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

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

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

运行上一部分中创建的应用。Run the app created in the previous section. 所选类别的通知作为 toast 通知显示。Notifications for the selected categories appear as toast notifications.

后续步骤Next steps

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