Zelfstudie: Push-melding voor gebruikers van de specifieke Android-toepassing met behulp van Azure Notification Hubs en Google Cloud Messaging (afgeschaft)Tutorial: Push notification to specific Android application users by using Azure Notification Hubs and Google Cloud Messaging (deprecated)

Waarschuwing

Vanaf 10 April 2018, is Google afgeschaft in Google Cloud Messaging (GCM).As of April 10, 2018, Google has deprecated Google Cloud Messaging (GCM). De GCM server en client-API's zijn afgeschaft en wordt verwijderd zodra 29 mei 2019.The GCM server and client APIs are deprecated and will be removed as soon as May 29, 2019. Zie voor meer informatie, GCM en FCM Frequently Asked Questions.For more information, see GCM and FCM Frequently Asked Questions.

In deze zelfstudie wordt uitgelegd hoe u met Azure Notification Hubs pushmeldingen kunt verzenden naar een specifieke app-gebruiker op een specifiek apparaat.This tutorial shows you how to use Azure Notification Hubs to send push notifications to a specific app user on a specific device. Er wordt een WebAPI-back-end van ASP.NET gebruikt om clients te verifiëren en meldingen te genereren, zoals u kunt lezen in het artikel Registering from your App Backend (Registreren vanuit uw app-back-end).An ASP.NET WebAPI backend is used to authenticate clients and to generate notifications, as shown in the guidance article Registering from your app backend. Deze zelfstudie bouwt voort op de Notification Hub die u hebt gemaakt in de Zelfstudie: Pushmeldingen naar Android-apparaten met Azure Notification Hubs en Google Cloud Messaging.This tutorial builds on the notification hub that you created in the Tutorial: Push notifications to Android devices by using Azure Notification Hubs and Google Cloud Messaging.

In deze zelfstudie voert u de volgende stappen uit:In this tutorial, you take the following steps:

  • Het Web API-project voor de back-end maken waarmee gebruikers worden geverifieerd.Create the backend Web API project that authenticates users.
  • De Android-toepassing bijwerken.Update the Android application.
  • De app testenTest the app

VereistenPrerequisites

U moet de Zelfstudie: Pushmeldingen verzenden naar Android-apparaten met behulp van Azure Notification Hubs en Google Cloud Messaging voltooien voordat u aan deze zelfstudie begint.Complete the Tutorial: Push notifications to Android devices by using Azure Notification Hubs and Google Cloud Messaging before doing this tutorial.

Het WebAPI-project makenCreate the WebAPI project

In de volgende secties wordt het maken van een nieuwe ASP.NET WebAPI-back-end besproken.The following sections discuss the creation of a new ASP.NET WebAPI backend. Dit proces heeft drie hoofddoelen:This process has three main purposes:

  • Clients verifiëren: U voegt een bericht-handler toe voor het verifiëren van client aanvragen en het koppelen van de gebruiker aan de aanvraag.Authenticate clients: You add a message handler to authenticate client requests and associate the user with the request.
  • Registreer u voor meldingen met behulp van de WebAPI-back-end: U voegt een controller toe voor het afhandelen van nieuwe registraties voor een client apparaat om meldingen te ontvangen.Register for notifications by using the WebAPI backend: You add a controller to handle new registrations for a client device to receive notifications. De naam van de geverifieerde gebruiker wordt automatisch aan de registratie toegevoegd als een tag.The authenticated username is automatically added to the registration as a tag.
  • Meldingen verzenden naar clients: U voegt een controller toe om gebruikers in staat te stellen een beveiligde push naar apparaten en clients te activeren die zijn gekoppeld aan het label.Send notifications to clients: You add a controller to provide a way for users to trigger a secure push to devices and clients associated with the tag.

Maak de nieuwe ASP.NET WebAPI-back-end door de volgende acties uit te voeren:Create the new ASP.NET WebAPI backend by doing the following actions:

Belangrijk

Als u Visual Studio 2015 of eerder gebruikt, moet u voordat u deze zelfstudie begint controleren of u de meest recente versie van NuGet Package Manager voor Visual Studio hebt geïnstalleerd.If you are using Visual Studio 2015 or earlier, before starting this tutorial, ensure that you have installed the latest version of NuGet Package Manager for Visual Studio.

Start Visual Studio om dit te controleren.To check, start Visual Studio. Selecteer Extensies en updates in het menu Extra.On the Tools menu, select Extensions and Updates. Zoek naar NuGet Package Manager in uw versie van Visual Studio en controleer of u de meest recente versie hebt.Search for NuGet Package Manager in your version of Visual Studio, and make sure you have the latest version. Als uw versie niet de nieuwste versie is, verwijdert u deze en installeert u NuGet Package Manager.If your version is not the latest version, uninstall it, and then reinstall the NuGet Package Manager.

Notitie

Controleer of u de Visual Studio Azure SDK voor website-implementatie hebt geïnstalleerd.Make sure you have installed the Visual Studio Azure SDK for website deployment.

  1. Start Visual Studio of Visual Studio Express.Start Visual Studio or Visual Studio Express.

  2. Selecteer Server Explorer en meld u aan bij uw Azure-account.Select Server Explorer, and sign in to your Azure account. U moet zijn aangemeld om de websiteresources voor uw account te maken.To create the web site resources on your account, you must be signed in.

  3. Klik in Visual Studio met de rechtermuisknop op de Visual Studio-oplossing, houd de muisaanwijzer op Toevoegen en klik op Nieuw item.In Visual Studio, right-click Visual Studio solution, point to Add, and click New Project.

  4. Vouw Visual C# uit, selecteer Web, en klik op SP.NET-webtoepassing.Expand Visual C#, select Web, and click ASP.NET Web Application.

  5. Typ AppBackend in het vak Naam en selecteer OK.In the Name box, type AppBackend, and then select OK.

    Het venster Nieuw project

  6. Selecteer in het venster Nieuw ASP.NET-project het selectievakje Web-API en selecteer vervolgens OK.In the New ASP.NET Project window, select the Web API check box, and then select OK.

    Het venster Nieuw ASP.NET-project

  7. Selecteer een abonnement in het venster Microsoft Azure Web App configureren en voer in de lijst App Service-plan een van de volgende acties uit:In the Configure Microsoft Azure Web App window, select a subscription and then, in the App Service plan list, do either of the following actions:

    • Selecteer een App Service-plan dat u al hebt gemaakt.Select an app service plan that you've already created.
    • Selecteer Een nieuw App Service-plan maken, en maak er vervolgens een.Select Create a new app service plan, and then create one.

    U hebt geen database nodig voor deze zelfstudie.You do not need a database for this tutorial. Nadat u uw App Service-plan hebt geselecteerd, selecteert u OK om het project te maken.After you have selected your app service plan, select OK to create the project.

    Het venster Microsoft Azure Web App configureren

    Als u deze pagina voor het configureren van het app service-abonnement niet ziet, gaat u verder met de zelf studie.If you don't see this page for configure app service plan, continue with the tutorial. U kunt deze configureren terwijl u de app later publiceert.You can configure it while publishing the app later.

Clients verifiëren bij de WebAPI-back-endAuthenticate clients to the WebAPI backend

In deze sectie maakt u een nieuwe berichtenhandlerklasse met de naam AuthenticationTestHandler voor de nieuwe back-end.In this section, you create a new message-handler class named AuthenticationTestHandler for the new backend. Deze klasse wordt afgeleid van DelegatingHandler en toegevoegd als een berichtenhandler zodat deze alle aanvragen die de back-end ontvangt, kan verwerken.This class is derived from DelegatingHandler and added as a message handler so that it can process all requests that come into the backend.

  1. Klik in Solution Explorer met de rechtermuisknop op het project AppBackend, selecteer Toevoegen en selecteer vervolgens Klasse.In Solution Explorer, right-click the AppBackend project, select Add, and then select Class.

  2. Geef de nieuwe klasse de naam AuthenticationTestHandler.cs en selecteer Toevoegen om de klasse te genereren.Name the new class AuthenticationTestHandler.cs, and then select Add to generate the class. Deze klasse verifieert gebruikers met behulp van Basisverificatie om het eenvoudig te houden.This class authenticates users by using Basic Authentication for simplicity. Uw app kan een willekeurig verificatieschema gebruiken.Your app can use any authentication scheme.

  3. Voeg in AuthenticationTestHandler.cs de volgende using-instructies toe:In AuthenticationTestHandler.cs, add the following using statements:

    using System.Net.Http;
    using System.Threading;
    using System.Security.Principal;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    
  4. Vervang in AuthenticationTestHandler.cs de AuthenticationTestHandler-klassedefinitie door de volgende code:In AuthenticationTestHandler.cs, replace the AuthenticationTestHandler class definition with the following code:

    Deze handler verifieert de aanvraag wanneer de volgende drie voorwaarden waar zijn:The handler authorizes the request when the following three conditions are true:

    • De aanvraag bevat een autorisatieheader.The request includes an Authorization header.
    • De aanvraag maakt gebruik van basisverificatie.The request uses basic authentication.
    • De gebruikersnaamtekenreeks en de wachtwoordtekenreeks zijn dezelfde tekenreeks.The user name string and the password string are the same string.

    Anders wordt de aanvraag geweigerd.Otherwise, the request is rejected. Deze verificatie is geen bestaande benadering op verificatie en autorisatie.This authentication is not a true authentication and authorization approach. Dit is slechts een eenvoudig voorbeeld voor deze zelfstudie.It is only a simple example for this tutorial.

    Als het aanvraagbericht is geverifieerd en geautoriseerd door AuthenticationTestHandler, wordt de basisverificatiegebruiker toegevoegd aan de huidige aanvraag in HttpContext.If the request message is authenticated and authorized by AuthenticationTestHandler, the basic authentication user is attached to the current request on HttpContext. Gebruikersgegevens in HttpContext worden later gebruikt door een andere controller (RegisterController) om een tag toe te voegen aan de aanvraag voor meldingen van registraties.User information in HttpContext will be used by another controller (RegisterController) later to add a tag to the notification registration request.

    public class AuthenticationTestHandler : DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, CancellationToken cancellationToken)
        {
            var authorizationHeader = request.Headers.GetValues("Authorization").First();
    
            if (authorizationHeader != null && authorizationHeader
                .StartsWith("Basic ", StringComparison.InvariantCultureIgnoreCase))
            {
                string authorizationUserAndPwdBase64 =
                    authorizationHeader.Substring("Basic ".Length);
                string authorizationUserAndPwd = Encoding.Default
                    .GetString(Convert.FromBase64String(authorizationUserAndPwdBase64));
                string user = authorizationUserAndPwd.Split(':')[0];
                string password = authorizationUserAndPwd.Split(':')[1];
    
                if (verifyUserAndPwd(user, password))
                {
                    // Attach the new principal object to the current HttpContext object
                    HttpContext.Current.User =
                        new GenericPrincipal(new GenericIdentity(user), new string[0]);
                    System.Threading.Thread.CurrentPrincipal =
                        System.Web.HttpContext.Current.User;
                }
                else return Unauthorized();
            }
            else return Unauthorized();
    
            return base.SendAsync(request, cancellationToken);
        }
    
        private bool verifyUserAndPwd(string user, string password)
        {
            // This is not a real authentication scheme.
            return user == password;
        }
    
        private Task<HttpResponseMessage> Unauthorized()
        {
            var response = new HttpResponseMessage(HttpStatusCode.Forbidden);
            var tsc = new TaskCompletionSource<HttpResponseMessage>();
            tsc.SetResult(response);
            return tsc.Task;
        }
    }
    

    Notitie

    Opmerking over beveiliging: De AuthenticationTestHandler klasse biedt geen echte authenticatie.Security note: The AuthenticationTestHandler class does not provide true authentication. Het wordt alleen gebruikt om basisverificatie na te bootsen en is niet beveiligd.It is used only to mimic basic authentication and is not secure. U moet een veilig verificatiemechanisme implementeren in uw productietoepassingen en -services.You must implement a secure authentication mechanism in your production applications and services.

  5. Voeg de volgende code toe aan het einde van de Register-methode in de klasse App_Start/WebApiConfig.cs om de berichtenhandler te registreren:To register the message handler, add the following code at the end of the Register method in the App_Start/WebApiConfig.cs class:

    config.MessageHandlers.Add(new AuthenticationTestHandler());
    
  6. Sla uw wijzigingen op.Save your changes.

Registreren voor meldingen met behulp van de WebAPI-back-endRegister for notifications by using the WebAPI backend

In deze sectie voegen we een nieuwe controller toe aan de WebAPI-back-end om aanvragen voor het registreren van een gebruiker en een apparaat voor meldingen af te handelen met behulp van de clientbibliotheek voor notification hubs.In this section, you add a new controller to the WebAPI backend to handle requests to register a user and a device for notifications by using the client library for notification hubs. De controller voegt een gebruikerstag toe voor de gebruiker die door AuthenticationTestHandler is geverifieerd en gekoppeld aan HttpContext.The controller adds a user tag for the user that was authenticated and attached to HttpContext by AuthenticationTestHandler. De tag heeft de indeling van de tekenreeks, "username:<actual username>".The tag has the string format, "username:<actual username>".

  1. Klik in Solution Explorer met de rechtermuisknop op het project AppBackend en selecteer vervolgens NuGet-pakketten beheren.In Solution Explorer, right-click the AppBackend project and then select Manage NuGet Packages.

  2. Selecteer in het linkerdeelvenster Online en typ Microsoft.Azure.NotificationHubs in het vak Zoeken.In the left pane, select Online and then, in the Search box, type Microsoft.Azure.NotificationHubs.

  3. Selecteer Microsoft Azure Notification Hubs in de lijst met resultaten en selecteer vervolgens Installeren.In the results list, select Microsoft Azure Notification Hubs, and then select Install. Voltooi de installatie en sluit vervolgens het venster Nuget Package Manager.Complete the installation, and then close the NuGet Package Manager window.

    Met deze actie wordt een verwijzing toegevoegd aan de Azure Notification Hubs-SDK met het Microsoft.Azure.Notification Hubs NuGet-pakket.This action adds a reference to the Azure Notification Hubs SDK by using the Microsoft.Azure.Notification Hubs NuGet package.

  4. Maak een nieuw klassebestand waarmee de verbinding met de notification hub die wordt gebruikt voor het verzenden van meldingen.Create a new class file that represents the connection with the notification hub that's used to send notifications. Klik in Solution Explorer met de rechtermuisknop op de map Modellen en selecteer achtereenvolgens Toevoegen en Klasse.In Solution Explorer, right-click the Models folder, select Add, and then select Class. Noem de nieuwe klasse Notifications.cs en selecteer vervolgens Toevoegen om de klasse te genereren.Name the new class Notifications.cs, and then select Add to generate the class.

    Het venster Nieuw Item toevoegen

  5. Voeg in Notifications.cs de volgende using-instructie toe aan het begin van het bestand:In Notifications.cs, add the following using statement at the top of the file:

    using Microsoft.Azure.NotificationHubs;
    
  6. Vervang de Notifications-klassedefinitie door de volgende code en vervang de twee tijdelijke aanduidingen door de verbindingsreeks (met volledige toegang) voor uw notification hub en de naam van de hub (beschikbaar in Azure Portal):Replace the Notifications class definition with the following code, and replace the two placeholders with the connection string (with full access) for your notification hub and the hub name (available at Azure portal):

    public class Notifications
    {
        public static Notifications Instance = new Notifications();
    
        public NotificationHubClient Hub { get; set; }
    
        private Notifications() {
            Hub = NotificationHubClient.CreateClientFromConnectionString("<your hub's DefaultFullSharedAccessSignature>",
                                                                            "<hub name>");
        }
    }
    

    Belangrijk

    Voer de naam en het DefaultFullSharedAccessSignature van uw hub in voordat u verder gaat.Enter the name and the DefaultFullSharedAccessSignature of your hub before proceeding further.

  7. Maak vervolgens een nieuwe controller met de naam RegisterController.Next, create a new controller named RegisterController. Klik in Solution Explorer met de rechtermuisknop op de map Controllers en selecteer achtereenvolgens Toevoegen en Controller.In Solution Explorer, right-click the Controllers folder, select Add, and then select Controller.

  8. Selecteer Web API 2 Controller - leeg en selecteer vervolgens Toevoegen.Select Web API 2 Controller - Empty, and then select Add.

    Het venster Scaffold toevoegen

  9. Typ in het vak Controllernaam RegisterController als naam voor de nieuwe klasse en selecteer vervolgens Toevoegen.In the Controller name box, type RegisterController to name the new class, and then select Add.

    Het venster Controller toevoegen

  10. Voeg in RegisterController.cs de volgende using-instructies toe:In RegisterController.cs, add the following using statements:

    using Microsoft.Azure.NotificationHubs;
    using Microsoft.Azure.NotificationHubs.Messaging;
    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  11. Voeg de volgende code in de RegisterController-klassedefinitie.Add the following code inside the RegisterController class definition. In deze code voegt u een gebruikerstag toe voor de gebruiker die is gekoppeld aan HttpContext.In this code, you add a user tag for the user that's attached to HttpContext. De gebruiker is geverifieerd en gekoppeld aan HttpContext door het berichtenfilter dat u hebt toegevoegd, AuthenticationTestHandler.The user was authenticated and attached to HttpContext by the message filter that you added, AuthenticationTestHandler. U kunt ook optionele controles toevoegen om te controleren of de gebruiker rechten heeft voor het registreren voor de aangevraagde tags.You can also add optional checks to verify that the user has rights to register for the requested tags.

    private NotificationHubClient hub;
    
    public RegisterController()
    {
        hub = Notifications.Instance.Hub;
    }
    
    public class DeviceRegistration
    {
        public string Platform { get; set; }
        public string Handle { get; set; }
        public string[] Tags { get; set; }
    }
    
    // POST api/register
    // This creates a registration id
    public async Task<string> Post(string handle = null)
    {
        string newRegistrationId = null;
    
        // make sure there are no existing registrations for this push handle (used for iOS and Android)
        if (handle != null)
        {
            var registrations = await hub.GetRegistrationsByChannelAsync(handle, 100);
    
            foreach (RegistrationDescription registration in registrations)
            {
                if (newRegistrationId == null)
                {
                    newRegistrationId = registration.RegistrationId;
                }
                else
                {
                    await hub.DeleteRegistrationAsync(registration);
                }
            }
        }
    
        if (newRegistrationId == null) 
            newRegistrationId = await hub.CreateRegistrationIdAsync();
    
        return newRegistrationId;
    }
    
    // PUT api/register/5
    // This creates or updates a registration (with provided channelURI) at the specified id
    public async Task<HttpResponseMessage> Put(string id, DeviceRegistration deviceUpdate)
    {
        RegistrationDescription registration = null;
        switch (deviceUpdate.Platform)
        {
            case "mpns":
                registration = new MpnsRegistrationDescription(deviceUpdate.Handle);
                break;
            case "wns":
                registration = new WindowsRegistrationDescription(deviceUpdate.Handle);
                break;
            case "apns":
                registration = new AppleRegistrationDescription(deviceUpdate.Handle);
                break;
            case "fcm":
                registration = new FcmRegistrationDescription(deviceUpdate.Handle);
                break;
            default:
                throw new HttpResponseException(HttpStatusCode.BadRequest);
        }
    
        registration.RegistrationId = id;
        var username = HttpContext.Current.User.Identity.Name;
    
        // add check if user is allowed to add these tags
        registration.Tags = new HashSet<string>(deviceUpdate.Tags);
        registration.Tags.Add("username:" + username);
    
        try
        {
            await hub.CreateOrUpdateRegistrationAsync(registration);
        }
        catch (MessagingException e)
        {
            ReturnGoneIfHubResponseIsGone(e);
        }
    
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    
    // DELETE api/register/5
    public async Task<HttpResponseMessage> Delete(string id)
    {
        await hub.DeleteRegistrationAsync(id);
        return Request.CreateResponse(HttpStatusCode.OK);
    }
    
    private static void ReturnGoneIfHubResponseIsGone(MessagingException e)
    {
        var webex = e.InnerException as WebException;
        if (webex.Status == WebExceptionStatus.ProtocolError)
        {
            var response = (HttpWebResponse)webex.Response;
            if (response.StatusCode == HttpStatusCode.Gone)
                throw new HttpRequestException(HttpStatusCode.Gone.ToString());
        }
    }
    
  12. Sla uw wijzigingen op.Save your changes.

Meldingen verzenden vanuit de WebAPI-back-endSend notifications from the WebAPI backend

In deze sectie voegt u een nieuwe domeincontroller toe die clientapparaten een manier biedt om een melding te verzenden.In this section, you add a new controller that exposes a way for client devices to send a notification. De melding is gebaseerd op de gebruikersnaamtag die gebruikmaakt van de Azure Notification Hubs .NET-bibliotheek in de ASP.NET WebAPI-back-end.The notification is based on the username tag that uses Azure Notification Hubs .NET Library in the ASP.NET WebAPI backend.

  1. Maak nog een nieuwe controller met de naam NotificationsController op dezelfde manier als u RegisterController in de vorige sectie hebt gemaakt.Create another new controller named NotificationsController the same way you created RegisterController in the previous section.

  2. Voeg in NotificationsController.cs de volgende using-instructies toe:In NotificationsController.cs, add the following using statements:

    using AppBackend.Models;
    using System.Threading.Tasks;
    using System.Web;
    
  3. Voeg de volgende methode toe aan de klasse NotificationsController:Add the following method to the NotificationsController class:

    Met deze code wordt een meldingstype verzonden die is gebaseerd op de pns-parameter (Platform Notification Service, PNS).This code sends a notification type that's based on the Platform Notification Service (PNS) pns parameter. De waarde van to_tag wordt gebruikt om de tag gebruikersnaam in te stellen in het bericht.The value of to_tag is used to set the username tag on the message. Deze tag moet overeenkomen met een gebruikersnaamtag van een actieve notification hub-registratie.This tag must match a username tag of an active notification hub registration. Het meldingsbericht wordt opgehaald uit de hoofdtekst van de POST-aanvraag en geformatteerd voor de doel-PNS.The notification message is pulled from the body of the POST request and formatted for the target PNS.

    Afhankelijk van de PNS die uw ondersteunde apparaten gebruiken om meldingen te ontvangen, worden de meldingen met verschillende indelingen ondersteund.Depending on the PNS that your supported devices use to receive notifications, the notifications are supported by a variety of formats. Bijvoorbeeld op Windows-apparaten kunt u een pop-upmelding met WNS gebruiken die niet rechtstreeks wordt ondersteund door een andere PNS.For example, on Windows devices, you might use a toast notification with WNS that isn't directly supported by another PNS. In een dergelijk geval moet uw back-end de melding in een ondersteunde melding indelen voor de PNS van apparaten die u wilt ondersteunen.In such an instance, your backend needs to format the notification into a supported notification for the PNS of devices you plan to support. Gebruik vervolgens de juiste API voor verzending in de NotificationHubClient-klasse.Then use the appropriate send API on the NotificationHubClient class.

    public async Task<HttpResponseMessage> Post(string pns, [FromBody]string message, string to_tag)
    {
        var user = HttpContext.Current.User.Identity.Name;
        string[] userTag = new string[2];
        userTag[0] = "username:" + to_tag;
        userTag[1] = "from:" + user;
    
        Microsoft.Azure.NotificationHubs.NotificationOutcome outcome = null;
        HttpStatusCode ret = HttpStatusCode.InternalServerError;
    
        switch (pns.ToLower())
        {
            case "wns":
                // Windows 8.1 / Windows Phone 8.1
                var toast = @"<toast><visual><binding template=""ToastText01""><text id=""1"">" + 
                            "From " + user + ": " + message + "</text></binding></visual></toast>";
                outcome = await Notifications.Instance.Hub.SendWindowsNativeNotificationAsync(toast, userTag);
                break;
            case "apns":
                // iOS
                var alert = "{\"aps\":{\"alert\":\"" + "From " + user + ": " + message + "\"}}";
                outcome = await Notifications.Instance.Hub.SendAppleNativeNotificationAsync(alert, userTag);
                break;
            case "fcm":
                // Android
                var notif = "{ \"data\" : {\"message\":\"" + "From " + user + ": " + message + "\"}}";
                outcome = await Notifications.Instance.Hub.SendFcmNativeNotificationAsync(notif, userTag);
                break;
        }
    
        if (outcome != null)
        {
            if (!((outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Abandoned) ||
                (outcome.State == Microsoft.Azure.NotificationHubs.NotificationOutcomeState.Unknown)))
            {
                ret = HttpStatusCode.OK;
            }
        }
    
        return Request.CreateResponse(ret);
    }
    
  4. Selecteer de toets F5 om de toepassing uit te voeren en om de juistheid van uw werk tot nu toe te controleren.To run the application and ensure the accuracy of your work so far, select the F5 key. De app opent een webbrowser en deze wordt weergegeven met de startpagina van ASP.NET.The app opens a web browser, and it is displayed on the ASP.NET home page.

De nieuwe WebAPI-back-end publicerenPublish the new WebAPI backend

U gaat de app nu implementeren op een Azure-website zodat deze toegankelijk is vanaf alle apparaten.Next, you deploy the app to an Azure website to make it accessible from all devices.

  1. Klik met de rechtermuisknop op het project AppBackend en selecteer Publiceren.Right-click the AppBackend project, and then select Publish.

  2. Selecteer Microsoft Azure App Service als publicatiedoel en selecteer vervolgens **Publiceren.Select Microsoft Azure App Service as your publish target, and then select **Publish. Het venster App Service maken wordt geopend.The Create App Service window opens. Hier kunt u alle benodigde Azure-resources maken die nodig zijn om de ASP.NET-web-app in Azure uit te voeren.Here you can create all the necessary Azure resources to run the ASP.NET web app in Azure.

    De tegel Microsoft Azure App Service

  3. Selecteer uw Azure-account in het venster App Service maken.In the Create App Service window, select your Azure account. Selecteer Type wijzigen > Web App.Select Change Type > Web App. Houd de standaard Web App-naam en selecteer het Abonnement, de Resourcegroep en het App Service-plan.Keep the default Web App Name, and then select the Subscription, Resource Group, and App Service Plan.

  4. Selecteer Maken.Select Create.

  5. Noteer de Site-URL-eigenschap in de sectie Samenvatting.Make a note of the Site URL property in the Summary section. Deze URL is het eindpunt van uw back-end verderop in de zelfstudie.This URL is your back-end endpoint later in the tutorial.

  6. Selecteer Publiceren.Select Publish.

Nadat u de wizard hebt voltooid, wordt de ASP.NET-web-app naar Azure gepubliceerd. Daarna wordt de app geopend in de standaardbrowser.After you've completed the wizard, it publishes the ASP.NET web app to Azure and then opens the app in the default browser. Uw toepassing is zichtbaar in Azure App Services.Your application is viewable in Azure App Services.

De URL maakt gebruik van de web-appnaam die u eerder hebt opgegeven, met de notatie http://<app_naam>.azurewebsites.net.The URL uses the web app name that you specified earlier, with the format http://<app_name>.azurewebsites.net.

Het Android-project makenCreate the Android Project

De volgende stap is het bijwerken van de Android-toepassing die u hebt gemaakt in de Zelfstudie: Pushmeldingen naar Android-apparaten met Azure Notification Hubs en Google Cloud Messaging.The next step is to update the Android application created in the Tutorial: Push notifications to Android devices by using Azure Notification Hubs and Google Cloud Messaging.

  1. Open het bestand res/layout/activity_main.xml en vervang de volgende inhoudsdefinities:Open your res/layout/activity_main.xml file, replace the following content definitions:

    Hiermee worden nieuwe EditText-besturingselementen toegevoegd voor aanmelding als een gebruiker.It adds new EditText controls for logging in as a user. Er wordt ook een veld toegevoegd voor een gebruikersnaam-tag die deel gaat uitmaken van meldingen die u verzendt:Also a field is added for a username tag that will be part of notifications you send:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
    <EditText
        android:id="@+id/usernameText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="@string/usernameHint"
        android:layout_above="@+id/passwordText"
        android:layout_alignParentEnd="true" />
    <EditText
        android:id="@+id/passwordText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="@string/passwordHint"
        android:inputType="textPassword"
        android:layout_above="@+id/buttonLogin"
        android:layout_alignParentEnd="true" />
    <Button
        android:id="@+id/buttonLogin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/loginButton"
        android:onClick="login"
        android:layout_above="@+id/toggleButtonGCM"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="24dp" />
    <ToggleButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textOn="WNS on"
        android:textOff="WNS off"
        android:id="@+id/toggleButtonWNS"
        android:layout_toLeftOf="@id/toggleButtonGCM"
        android:layout_centerVertical="true" />
    <ToggleButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textOn="GCM on"
        android:textOff="GCM off"
        android:id="@+id/toggleButtonGCM"
        android:checked="true"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" />
    <ToggleButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textOn="APNS on"
        android:textOff="APNS off"
        android:id="@+id/toggleButtonAPNS"
        android:layout_toRightOf="@id/toggleButtonGCM"
        android:layout_centerVertical="true" />
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editTextNotificationMessageTag"
        android:layout_below="@id/toggleButtonGCM"
        android:layout_centerHorizontal="true"
        android:hint="@string/notification_message_tag_hint" />
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/editTextNotificationMessage"
        android:layout_below="@+id/editTextNotificationMessageTag"
        android:layout_centerHorizontal="true"
        android:hint="@string/notification_message_hint" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/send_button"
        android:id="@+id/sendbutton"
        android:onClick="sendNotificationButtonOnClick"
        android:layout_below="@+id/editTextNotificationMessage"
        android:layout_centerHorizontal="true" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:id="@+id/text_hello"
    />  
    </RelativeLayout>
    
  2. Open het bestand res/values/strings.xml en vervang de definitie send_button door de volgende regels die de tekenreeks voor de send_button aanpassen. Voeg vervolgens tekenreeksen toe voor de andere besturingselementen:Open your res/values/strings.xml file and replace the send_button definition with the following lines that redefine the string for the send_button and add strings for the other controls:

    <string name="usernameHint">Username</string>
    <string name="passwordHint">Password</string>
    <string name="loginButton">1. Sign in</string>
    <string name="send_button">2. Send Notification</string>
    <string name="notification_message_hint">Notification message</string>
    <string name="notification_message_tag_hint">Recipient username</string>
    

    De grafische indeling van main_activity.xml ziet er nu uit als in de volgende afbeelding:Your main_activity.xml graphical layout should now look like the following image:

  3. Maak in hetzelfde pakket als de klasse MainActivity een nieuwe klasse met de naam RegisterClient.Create a new class named RegisterClient in the same package as your MainActivity class. Gebruik de onderstaande code voor het nieuwe klassebestand.Use the code below for the new class file.

    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.util.Set;
    
    import org.apache.http.HttpResponse;
    import org.apache.http.HttpStatus;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.client.methods.HttpPut;
    import org.apache.http.client.methods.HttpUriRequest;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    import android.content.Context;
    import android.content.SharedPreferences;
    import android.util.Log;
    
    public class RegisterClient {
        private static final String PREFS_NAME = "ANHSettings";
        private static final String REGID_SETTING_NAME = "ANHRegistrationId";
        private String Backend_Endpoint;
        SharedPreferences settings;
        protected HttpClient httpClient;
        private String authorizationHeader;
    
        public RegisterClient(Context context, String backendEndpoint) {
            super();
            this.settings = context.getSharedPreferences(PREFS_NAME, 0);
            httpClient =  new DefaultHttpClient();
            Backend_Endpoint = backendEndpoint + "/api/register";
        }
    
        public String getAuthorizationHeader() {
            return authorizationHeader;
        }
    
        public void setAuthorizationHeader(String authorizationHeader) {
            this.authorizationHeader = authorizationHeader;
        }
    
        public void register(String handle, Set<String> tags) throws ClientProtocolException, IOException, JSONException {
            String registrationId = retrieveRegistrationIdOrRequestNewOne(handle);
    
            JSONObject deviceInfo = new JSONObject();
            deviceInfo.put("Platform", "gcm");
            deviceInfo.put("Handle", handle);
            deviceInfo.put("Tags", new JSONArray(tags));
    
            int statusCode = upsertRegistration(registrationId, deviceInfo);
    
            if (statusCode == HttpStatus.SC_OK) {
                return;
            } else if (statusCode == HttpStatus.SC_GONE){
                settings.edit().remove(REGID_SETTING_NAME).commit();
                registrationId = retrieveRegistrationIdOrRequestNewOne(handle);
                statusCode = upsertRegistration(registrationId, deviceInfo);
                if (statusCode != HttpStatus.SC_OK) {
                    Log.e("RegisterClient", "Error upserting registration: " + statusCode);
                    throw new RuntimeException("Error upserting registration");
                }
            } else {
                Log.e("RegisterClient", "Error upserting registration: " + statusCode);
                throw new RuntimeException("Error upserting registration");
            }
        }
    
        private int upsertRegistration(String registrationId, JSONObject deviceInfo)
                throws UnsupportedEncodingException, IOException,
                ClientProtocolException {
            HttpPut request = new HttpPut(Backend_Endpoint+"/"+registrationId);
            request.setEntity(new StringEntity(deviceInfo.toString()));
            request.addHeader("Authorization", "Basic "+authorizationHeader);
            request.addHeader("Content-Type", "application/json");
            HttpResponse response = httpClient.execute(request);
            int statusCode = response.getStatusLine().getStatusCode();
            return statusCode;
        }
    
        private String retrieveRegistrationIdOrRequestNewOne(String handle) throws ClientProtocolException, IOException {
            if (settings.contains(REGID_SETTING_NAME))
                return settings.getString(REGID_SETTING_NAME, null);
    
            HttpUriRequest request = new HttpPost(Backend_Endpoint+"?handle="+handle);
            request.addHeader("Authorization", "Basic "+authorizationHeader);
            HttpResponse response = httpClient.execute(request);
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                Log.e("RegisterClient", "Error creating registrationId: " + response.getStatusLine().getStatusCode());
                throw new RuntimeException("Error creating Notification Hubs registrationId");
            }
            String registrationId = EntityUtils.toString(response.getEntity());
            registrationId = registrationId.substring(1, registrationId.length()-1);
    
            settings.edit().putString(REGID_SETTING_NAME, registrationId).commit();
    
            return registrationId;
        }
    }
    

    Dit onderdeel implementeert de REST-aanroepen die nodig zijn om contact op te nemen met de app-back-end, om registratie voor pushmeldingen mogelijk te maken.This component implements the REST calls required to contact the app backend, in order to register for push notifications. Daarnaast wordt de registrationIds die is gemaakt door de meldingshub, lokaal opgeslagen. Zie Registering from your App Backend (Registreren vanuit uw app-back-end) voor meer informatie.It also locally stores the registrationIds created by the Notification Hub as detailed in Registering from your app backend. Het maakt gebruik van een verificatietoken die zijn opgeslagen in de lokale opslag wanneer u klikt op de aanmelden knop.It uses an authorization token stored in local storage when you click the Sign in button.

  4. Verwijder in uw klasse het private-veld voor NotificationHub of maak er een commentaar van. Voeg vervolgens een veld toe voor de klasse RegisterClient en een tekenreeks voor het eindpunt van uw ASP.NET-back-end.In your class, remove or comment out your private field for NotificationHub, and add a field for the RegisterClient class and a string for your ASP.NET backend's endpoint. Zorg ervoor dat u <Enter Your Backend Endpoint> vervangt door het eindpunt van de back-end dat u eerder hebt vastgesteld.Be sure to replace <Enter Your Backend Endpoint> with your actual backend endpoint obtained previously. Bijvoorbeeld http://mybackend.azurewebsites.net.For example, http://mybackend.azurewebsites.net.

    //private NotificationHub hub;
    private RegisterClient registerClient;
    private static final String BACKEND_ENDPOINT = "<Enter Your Backend Endpoint>";
    
  5. Ga in de klasse MainActivity naar de methode onCreate en verwijder de initialisatie van het veld hub en de aanroep van de methode registerWithNotificationHubs of maak er een commentaar van.In your MainActivity class, in the onCreate method, remove, or comment out the initialization of the hub field and the call to the registerWithNotificationHubs method. Voeg vervolgens code toe voor het initialiseren van een exemplaar van de klasse RegisterClient.Then add code to initialize an instance of the RegisterClient class. De methode moet de volgende regels bevatten:The method should contain the following lines:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        mainActivity = this;
        NotificationsManager.handleNotifications(this, NotificationSettings.SenderId, MyHandler.class);
        gcm = GoogleCloudMessaging.getInstance(this);
    
        //hub = new NotificationHub(HubName, HubListenConnectionString, this);
        //registerWithNotificationHubs();
    
        registerClient = new RegisterClient(this, BACKEND_ENDPOINT);
    
        setContentView(R.layout.activity_main);
    }
    
  6. Ga naar de klasse MainActivity en verwijder de hele methode registerWithNotificationHubs of maak er een commentaar van.In your MainActivity class, delete or comment out the entire registerWithNotificationHubs method. Deze methode wordt niet gebruikt in deze zelfstudie.It will not be used in this tutorial.

  7. Voeg de volgende instructies voor import toe aan uw MainActivity.java-bestand.Add the following import statements to your MainActivity.java file.

    import android.util.Base64;
    import android.view.View;
    import android.widget.EditText;
    
    import android.widget.Button;
    import android.widget.ToggleButton;
    import java.io.UnsupportedEncodingException;
    import android.content.Context;
    import java.util.HashSet;
    import android.widget.Toast;
    import org.apache.http.client.ClientProtocolException;
    import java.io.IOException;
    import org.apache.http.HttpStatus;
    
    import android.os.AsyncTask;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    
    import android.app.AlertDialog;
    import android.content.DialogInterface;
    
  8. Vervang de code van de onStart-methode door de volgende code:Replace code on the onStart method with the following code:

    super.onStart();
    Button sendPush = (Button) findViewById(R.id.sendbutton);
    sendPush.setEnabled(false);
    
  9. Vervolgens voegt u de volgende methoden voor het afhandelen van de aanmelden knop klikt u op gebeurtenissen en het verzenden van pushmeldingen.Then, add the following methods to handle the Sign in button click event and sending push notifications.

    public void login(View view) throws UnsupportedEncodingException {
        this.registerClient.setAuthorizationHeader(getAuthorizationHeader());
    
        final Context context = this;
        new AsyncTask<Object, Object, Object>() {
            @Override
            protected Object doInBackground(Object... params) {
                try {
                    String regid = gcm.register(NotificationSettings.SenderId);
                    registerClient.register(regid, new HashSet<String>());
                } catch (Exception e) {
                    DialogNotify("MainActivity - Failed to register", e.getMessage());
                    return e;
                }
                return null;
            }
    
            protected void onPostExecute(Object result) {
                Button sendPush = (Button) findViewById(R.id.sendbutton);
                sendPush.setEnabled(true);
                Toast.makeText(context, "Logged in and registered.",
                        Toast.LENGTH_LONG).show();
            }
        }.execute(null, null, null);
    }
    
    private String getAuthorizationHeader() throws UnsupportedEncodingException {
        EditText username = (EditText) findViewById(R.id.usernameText);
        EditText password = (EditText) findViewById(R.id.passwordText);
        String basicAuthHeader = username.getText().toString()+":"+password.getText().toString();
        basicAuthHeader = Base64.encodeToString(basicAuthHeader.getBytes("UTF-8"), Base64.NO_WRAP);
        return basicAuthHeader;
    }
    
    /**
        * This method calls the ASP.NET WebAPI backend to send the notification message
        * to the platform notification service based on the pns parameter.
        *
        * @param pns     The platform notification service to send the notification message to. Must
        *                be one of the following ("wns", "gcm", "apns").
        * @param userTag The tag for the user who will receive the notification message. This string
        *                must not contain spaces or special characters.
        * @param message The notification message string. This string must include the double quotes
        *                to be used as JSON content.
        */
    public void sendPush(final String pns, final String userTag, final String message)
            throws ClientProtocolException, IOException {
        new AsyncTask<Object, Object, Object>() {
            @Override
            protected Object doInBackground(Object... params) {
                try {
    
                    String uri = BACKEND_ENDPOINT + "/api/notifications";
                    uri += "?pns=" + pns;
                    uri += "&to_tag=" + userTag;
    
                    HttpPost request = new HttpPost(uri);
                    request.addHeader("Authorization", "Basic "+ getAuthorizationHeader());
                    request.setEntity(new StringEntity(message));
                    request.addHeader("Content-Type", "application/json");
    
                    HttpResponse response = new DefaultHttpClient().execute(request);
    
                    if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                        DialogNotify("MainActivity - Error sending " + pns + " notification",
                            response.getStatusLine().toString());
                        throw new RuntimeException("Error sending notification");
                    }
                } catch (Exception e) {
                    DialogNotify("MainActivity - Failed to send " + pns + " notification ", e.getMessage());
                    return e;
                }
    
                return null;
            }
        }.execute(null, null, null);
    }
    

    De login -handler voor de Meld u aan knop genereert een basisverificatie token met behulp van de ingevoerde gebruikersnaam en wachtwoord (vertegenwoordigt een token maakt gebruik van uw verificatieschema) en vervolgens hierbij RegisterClient om aan te roepen de back-end voor registratie.The login handler for the Sign in button generates a basic authentication token using on the input username and password (it represents any token your authentication scheme uses), then it uses RegisterClient to call the backend for registration.

    De methode sendPush roept de back-end aan om een beveiligde melding te activeren naar de gebruiker, op basis van de gebruikerstag.The sendPush method calls the backend to trigger a secure notification to the user based on the user tag. De Platform Notification Service die door sendPush wordt benaderd, is afhankelijk van de pns-tekenreeks die wordt doorgegeven.The platform notification service that sendPush targets depends on the pns string passed in.

  10. Voeg de volgende methode DialogNotify toe aan de klasse MainActivity.Add the following DialogNotify method to the MainActivity class.

    protected void DialogNotify(String title, String message)
    {
        AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
        alertDialog.setTitle(title);
        alertDialog.setMessage(message);
        alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
        alertDialog.show();
    }
    
  11. Werk in uw klasse MainActivity de methode sendNotificationButtonOnClick als volgt bij voor het aanroepen van de methode sendPush met de door de gebruiker geselecteerd Platform Notification Services.In your MainActivity class, update the sendNotificationButtonOnClick method to call the sendPush method with the user's selected platform notification services as follows.

    /**
    * Send Notification button click handler. This method sends the push notification
    * message to each platform selected.
    *
    * @param v The view
    */
    public void sendNotificationButtonOnClick(View v)
            throws ClientProtocolException, IOException {
    
        String nhMessageTag = ((EditText) findViewById(R.id.editTextNotificationMessageTag))
                .getText().toString();
        String nhMessage = ((EditText) findViewById(R.id.editTextNotificationMessage))
                .getText().toString();
    
        // JSON String
        nhMessage = "\"" + nhMessage + "\"";
    
        if (((ToggleButton)findViewById(R.id.toggleButtonWNS)).isChecked())
        {
            sendPush("wns", nhMessageTag, nhMessage);
        }
        if (((ToggleButton)findViewById(R.id.toggleButtonGCM)).isChecked())
        {
            sendPush("gcm", nhMessageTag, nhMessage);
        }
        if (((ToggleButton)findViewById(R.id.toggleButtonAPNS)).isChecked())
        {
            sendPush("apns", nhMessageTag, nhMessage);
        }
    }
    
  12. Voeg in het bestand build.gradle de volgende regel toe aan de sectie android na de sectie buildTypes.In the build.gradle file, add the following line to the android section after the buildTypes section.

    useLibrary 'org.apache.http.legacy'
    
  13. Maak het project.Build the project.

De app testenTest the app

  1. Voer de toepassing uit op een apparaat of in een emulator met Android Studio.Run the application on a device or an emulator using Android Studio.

  2. Voer in de Android-app een gebruikersnaam en wachtwoord in.In the Android app, enter a username and password. Deze moeten beide dezelfde tekenreekswaarde zijn en ze mogen geen spaties of speciale tekens bevatten.They must both be the same string value and they must not contain spaces or special characters.

  3. Klik in de Android-app op aanmelden.In the Android app, click Sign in. Wacht tot u het pop-upbericht Logged in and registered ziet.Wait for a toast message that states Logged in and registered. De knop Send Notification kan nu worden gekozen.It enables the Send Notification button.

  4. Klik op de wisselknoppen om alle platforms in te schakelen waarop u de app hebt uitgevoerd en een gebruiker hebt geregistreerd.Click the toggle buttons to enable all platforms where you ran the app and registered a user.

  5. Voer de naam van de gebruiker in die de melding moet ontvangen.Enter the user's name that receives the notification message. Die gebruiker moet zijn geregistreerd voor meldingen op de doelapparaten.That user must be registered for notifications on the target devices.

  6. Voer een bericht in dat de gebruiker als een pushmelding moet ontvangen.Enter a message for the user to receive as a push notification message.

  7. Klik op Send Notification.Click Send Notification. Elk apparaat dat een registratie heeft met de overeenkomende gebruikersnaam-tag ontvangt de pushmelding.Each device that has a registration with the matching username tag receives the push notification.

Volgende stappenNext steps

In deze zelfstudie hebt u geleerd hoe u pushmeldingen kunt verzenden naar specifieke gebruikers door een tag te koppelen aan hun registraties.In this tutorial, you learned how to push notifications to specific users that have tags associated with their registrations. Als u wilt weten hoe u locatiegebaseerde pushmeldingen kunt verzenden, gaat u verder met de volgende zelfstudie:To learn how to push location-based notifications, advance to the following tutorial: