Esercitazione: Inviare notifiche push ai dispositivi Android usando Hub di notifica di Azure e Google Cloud Messaging (deprecato)

Avviso

A partire dal 10 aprile 2018, Google ha deprecato Google Cloud Messaging (GCM). Il server GCM e le API client sono deprecati e verranno rimossi entro il 29 maggio 2019. Per altre informazioni, vedere le domande frequenti su GCM ed FCM.

Panoramica

Questa esercitazione illustra come usare Hub di notifica di Azure per inviare notifiche push a un'applicazione per Android. In questa esercitazione verrà creata un'app Android vuota che riceve notifiche push usando il servizio Google Cloud Messaging (GCM).

Importante

Il servizio Google Cloud Messaging (GCM) è deprecato e presto verrà rimosso.

Importante

Questo argomento illustra le notifiche push con Google Cloud Messaging (GCM). Se si sta ancora usando Google Firebase Messaging (FCM), vedere Invio di notifiche push ad Android con Hub di notifica di Azure e Firebase Cloud Messaging.

Il codice completo per questa esercitazione può essere scaricato da GitHub qui.

In questa esercitazione vengono completate le azioni seguenti:

  • Creare un progetto che supporta Google Cloud Messaging
  • Creare un hub di notifica
  • Connettere l'app all'hub di notifica
  • Testare l'app

Prerequisiti

Creazione di un progetto che supporta Google Cloud Messaging

  1. Passare a Google Cloud Consoleed eseguire l'accesso con le credenziali dell'account Google.

  2. Selezionare Crea progetto sulla barra degli strumenti.

    Creare un nuovo progetto

  3. In Project name (Nome del progetto) immettere un nome per il progetto e fare clic su Create (Crea).

  4. Selezionare il pulsante Alerts (Avvisi) sulla barra degli strumenti e selezionare il progetto nell'elenco. Verrà visualizzato il dashboard del progetto. È anche possibile passare direttamente al dashboard tramite l'URL: https://console.developers.google.com/home/dashboard?project=<YOUR PROJECT NAME>

    Selezionare il progetto negli avvisi

  5. Prendere nota del numero di progetto in Project number nel riquadro Project info (Informazioni sul progetto) del dashboard.

    ID progetto

  6. Nel dashboard, nel riquadro APIs (API) selezionare Go to APIs overview (Vai a panoramica API).

    Collegamento alla panoramica delle API

  7. Nella pagina API selezionare Enable APIs and Services (Abilita API e servizi).

    Pulsante Enable APIs and Services (Abilita API e servizi)

  8. Cercare e selezionare Google Cloud Messaging.

    Cercare e selezionare Google Cloud Messaging

  9. Per abilitare Google Cloud Messaging per il progetto, selezionare Enable (Abilita).

    Abilitare Google Cloud Messaging

  10. Selezionare Create credentials (Crea credenziali) sulla barra degli strumenti.

    Pulsante Create credentials (Crea credenziali)

  11. Nella pagina Add credentials to your project (Aggiungi credenziali al progetto) selezionare il collegamento API key (Chiave API).

    Aggiungere le credenziali

  12. Nella pagina API key (Chiave API) selezionare Create/Save (Crea/Salva). Nell'esempio seguente è selezionata l'opzione IP addresses (Indirizzi IP) e si immette 0.0.0.0/0 per gli indirizzi IP consentiti. È consigliabile limitare la chiave API in modo appropriato.

    Chiave API - Pulsante Create (Crea)

  13. Copiare la chiave API negli Appunti e salvarla altrove.

    Copiare la chiave API

    Questo valore della chiave dell'API verrà usato successivamente per abilitare Azure per l'autenticazione con GCM e l'invio di notifiche push per conto dell'app. Per tornare al dashboard del progetto, usare l'URL: https://console.developers.google.com/home/dashboard?project=<YOUR PROJECT NAME>

Creare un hub di notifica

  1. Accedere al portale di Azure.

  2. Scegliere Tutti i servizi dal menu a sinistra e quindi selezionare Hub di notifica nella sezione Dispositivi mobili. Selezionare l'icona a forma di stella accanto al nome del servizio per aggiungere il servizio alla sezione PREFERITI nel menu a sinistra. Dopo aver aggiunto Hub di notifica a PREFERITI, selezionarlo nel menu a sinistra.

    Portale di Azure - Selezionare Hub di notifica

  3. Nella pagina Hub di notifica selezionare Crea sulla barra degli strumenti.

    Hub di notifica - Pulsante Aggiungi della barra degli strumenti

  4. Nella scheda Informazioni di base della pagina Hub di notifica seguire questa procedura:

    1. In Sottoscrizione selezionare il nome della sottoscrizione di Azure da usare, quindi selezionare un gruppo di risorse esistente o crearne uno nuovo.

    2. Immettere un nome univoco per il nuovo spazio dei nomi in Dettagli spazio dei nomi.

    3. Uno spazio dei nomi contiene uno o più hub di notifica, quindi digitare un nome per l'hub in Dettagli hub di notifica. In caso contrario, selezionare uno spazio dei nomi esistente nell'elenco a discesa.

    4. Selezionare un valore nell'elenco a discesa Posizione. Questo valore specifica la posizione in cui creare l'hub.

    5. Selezionare Create (Crea).

      Portale di Azure: impostare le proprietà dell'hub di notifica

  5. Selezionare Notifiche (icona a forma di campanello) e quindi selezionare Vai alla risorsa. È anche possibile aggiornare l'elenco nella pagina Hub di notifica e selezionare l'hub.

    Portale di Azure - Vai alla risorsa

  6. Selezionare Criteri di accesso dall'elenco. Prendere nota delle due stringhe di connessione disponibili. Sono necessarie in un secondo momento per gestire le notifiche push.

    Importante

    Non usare il criterio DefaultFullSharedAccessSignature nell'applicazione. Deve essere usato solo nel back-end.

    Portale di Azure: stringhe di connessione dell'hub di notifica

Configurare l'impostazione di GCM per l'hub di notifica

  1. Selezionare Google (GCM) in IMPOSTAZIONI NOTIFICHE.

  2. Immettere la Chiave API ricevuta dalla console di Google Cloud.

  3. Sulla barra degli strumenti selezionare Salva.

    Hub di notifica di Azure - Google (GCM)

A questo punto, l'hub di notifica è configurato per l'uso con GCM e sono disponibili le stringhe di connessione per registrare l'app per l'invio e la ricezione di notifiche push.

Connettere l'app all'hub di notifica

Creare un nuovo progetto Android

  1. In Android Studio avviare un nuovo progetto Android Studio.

    Android Studio: nuovo progetto

  2. Scegliere il fattore di forma Phone and Tablet (Telefono e tablet) e la versione Minimum SDK (SDK minimo) che si vuole supportare. Quindi fare clic su Next.

    Android Studio: flusso di lavoro di creazione del progetto

  3. Scegliere Empty Activity (Attività vuota) per l'attività principale, fare clic su Avanti, quindi su Fine.

Aggiungere Google Play Services al progetto

  1. In Android Studio selezionare Strumenti nel menu e quindi SDK Manager.

  2. Selezionare la versione di destinazione di Android SDK che viene usata nel progetto. Quindi selezionare Mostra i dettagli del pacchetto.

    Android SDK Manager: selezionare la versione di destinazione

  3. Selezionare API Google, se non è già installato.

    Android SDK Manager: selezione di Google APIs (API Google)

  4. Passare alla scheda SDK Tools. Se lo strumento Google Play Services non è già installato, fare clic su Google Play Services come illustrato nell'immagine di seguito. Selezionare Applica per installarlo. Prendere nota del percorso dell'SDK per l'uso in un passaggio successivo.

    Android SDK Manager: selezione di Google Play Services

  5. Se viene visualizzata la finestra di dialogo Confirm Change (Conferma modifica), selezionare OK. Il programma di installazione componenti installa i componenti richiesti. Al termine dell'installazione dei componenti, selezionare Finish (Fine).

  6. Selezionare OK per chiudere la finestra di dialogo Settings for New Projects (Impostazioni per nuovi progetti).

  7. Aprire il file build. gradle nella directory dell'app, quindi aggiungere la riga seguente sotto dependencies.

    implementation 'com.google.android.gms:play-services-gcm:16.0.0'
    
  8. Selezionare l'icona Sincronizza ora nella barra degli strumenti

    Sincronizzazione con Gradle

  9. Aprire il file AndroidManifest.xml e quindi aggiungere il tag seguente al tag dell'applicazione.

    <meta-data android:name="com.google.android.gms.version"
         android:value="@integer/google_play_services_version" />
    

Aggiunta di librerie dell'Hub di notifica di Azure

  1. Nel file Build.Gradle relativo all'app aggiungere le righe seguenti alla sezione delle dipendenze.

    implementation 'com.microsoft.azure:notification-hubs-android-sdk:0.6@aar'
    implementation 'com.microsoft.azure:azure-notifications-handler:1.0.1@aar'
    
  2. Aggiungere l'archivio seguente dopo la sezione dependencies .

    repositories {
        maven {
            url "https://dl.bintray.com/microsoftazuremobile/SDK"
        }
    }
    

Aggiornamento del file AndroidManifest.xml del progetto

  1. Per supportare GCM, implementare un servizio listener ID istanza nel codice usato per ottenere i token di registrazione usando l'API ID istanza google. In questa esercitazione, il nome della classe è MyInstanceIDService.

    Aggiungere la definizione del servizio seguente al file AndroidManifest.xml, all'interno del tag <application> . Sostituire il segnaposto <your package> con il nome effettivo del pacchetto visualizzato all'inizio del file AndroidManifest.xml.

    <service android:name="<your package>.MyInstanceIDService" android:exported="false">
        <intent-filter>
            <action android:name="com.google.android.gms.iid.InstanceID"/>
        </intent-filter>
    </service>
    
  2. Dopo che l'applicazione riceve il token di registrazione di GCM dall'API Instance ID, lo userà per la registrazione con Hub di notifica di Azure. La registrazione in background viene eseguita mediante un IntentService denominato RegistrationIntentService. Il servizio è responsabile dell'aggiornamento del token di registrazione di GCM.

    Aggiungere la definizione del servizio seguente al file AndroidManifest.xml, all'interno del tag <application> . Sostituire il segnaposto <your package> con il nome effettivo del pacchetto visualizzato all'inizio del file AndroidManifest.xml.

    <service
        android:name="<your package>.RegistrationIntentService"
        android:exported="false">
    </service>
    
  3. Definire un ricevitore per la ricezione di notifiche. Aggiungere la definizione del ricevitore seguente al file AndroidManifest.xml, nel tag <application> . Sostituire il segnaposto <your package> con il nome effettivo del pacchetto visualizzato all'inizio del file AndroidManifest.xml.

    <receiver android:name="com.microsoft.windowsazure.notifications.NotificationsBroadcastReceiver"
        android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="<your package name>" />
        </intent-filter>
    </receiver>
    
  4. Aggiungere le necessarie autorizzazioni GCM riportate di seguito sotto il tag <application>. Sostituire <your package> con il nome del pacchetto visualizzato all'inizio del file AndroidManifest.xml.

    Per altre informazioni su queste autorizzazioni, vedere Set up a GCM Client app for Android (Configurare un'app client di GCM per Android).

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    
    <permission android:name="<your package>.permission.C2D_MESSAGE" android:protectionLevel="signature" />
    <uses-permission android:name="<your package>.permission.C2D_MESSAGE"/>
    

Aggiunta di codice

  1. Nella visualizzazione del progetto espandere app > src > main > java. Fare clic con il pulsante destro del mouse sulla cartella del pacchetto in java, scegliere Nuovo, quindi selezionare Java Class (Classe Java). Aggiungere una nuova classe denominata NotificationSettings.

    Android Studio: nuova classe Java

    Aggiornare questi tre segnaposto nel codice seguente per la classe NotificationSettings:

    • SenderId: il numero di progetto ottenuto in precedenza in Google Cloud Console.

    • HubListenConnectionString: la stringa di connessione DefaultListenAccessSignature per l'hub. È possibile copiare la stringa di connessione facendo clic su Criteri di accesso nella pagina Impostazioni dell'hub nel Azure portal.

    • HubName: usare il nome dell'hub di notifica visualizzato nella pagina dell'hub del Azure portal.

      NotificationSettings :

      public class NotificationSettings {
         public static String SenderId = "<Your project number>";
         public static String HubName = "<Your HubName>";
         public static String HubListenConnectionString = "<Your default listen connection string>";
      }
      
  2. Aggiungere un'altra classe denominata MyInstanceIDService. Questa classe è l'implementazione del servizio listener ID istanza.

    Il codice di questa classe chiama IntentService per aggiornare il token di GCM in background.

    import android.content.Intent;
    import android.util.Log;
    import com.google.android.gms.iid.InstanceIDListenerService;
    
    public class MyInstanceIDService extends InstanceIDListenerService {
    
        private static final String TAG = "MyInstanceIDService";
    
        @Override
        public void onTokenRefresh() {
    
            Log.i(TAG, "Refreshing GCM Registration Token");
    
            Intent intent = new Intent(this, RegistrationIntentService.class);
            startService(intent);
        }
    };
    
  3. Aggiungere al progetto un'altra nuova classe denominata RegistrationIntentService. Questa classe implementa IntentService che gestisce l'aggiornamento del token di GCM e la registrazione nell'hub di notifica.

    Usare il codice seguente per la classe.

    import android.app.IntentService;
    import android.content.Intent;
    import android.content.SharedPreferences;
    import android.preference.PreferenceManager;
    import android.util.Log;
    
    import com.google.android.gms.gcm.GoogleCloudMessaging;
    import com.google.android.gms.iid.InstanceID;
    import com.microsoft.windowsazure.messaging.NotificationHub;
    
    public class RegistrationIntentService extends IntentService {
    
        private static final String TAG = "RegIntentService";
    
        private NotificationHub hub;
    
        public RegistrationIntentService() {
            super(TAG);
        }
    
        @Override
        protected void onHandleIntent(Intent intent) {
            SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
            String resultString = null;
            String regID = null;
    
            try {
                InstanceID instanceID = InstanceID.getInstance(this);
                String token = instanceID.getToken(NotificationSettings.SenderId,
                        GoogleCloudMessaging.INSTANCE_ID_SCOPE);
                Log.i(TAG, "Got GCM Registration Token: " + token);
    
                // Storing the registration id that indicates whether the generated token has been
                // sent to your server. If it is not stored, send the token to your server,
                // otherwise your server should have already received the token.
                if ((regID=sharedPreferences.getString("registrationID", null)) == null) {
                    NotificationHub hub = new NotificationHub(NotificationSettings.HubName,
                            NotificationSettings.HubListenConnectionString, this);
                    Log.i(TAG, "Attempting to register with NH using token : " + token);
    
                    regID = hub.register(token).getRegistrationId();
    
                    // If you want to use tags...
                    // Refer to : https://azure.microsoft.com/documentation/articles/notification-hubs-routing-tag-expressions/
                    // regID = hub.register(token, "tag1", "tag2").getRegistrationId();
    
                    resultString = "Registered Successfully - RegId : " + regID;
                    Log.i(TAG, resultString);
                    sharedPreferences.edit().putString("registrationID", regID ).apply();
                } else {
                    resultString = "Previously Registered Successfully - RegId : " + regID;
                }
            } catch (Exception e) {
                Log.e(TAG, resultString="Failed to complete token refresh", e);
                // If an exception happens while fetching the new token or updating the registration data
                // on a third-party server, this ensures that we'll attempt the update at a later time.
            }
    
            // Notify UI that registration has completed.
            if (MainActivity.isVisible) {
                MainActivity.mainActivity.ToastNotify(resultString);
            }
        }
    }
    
  4. Nella classe MainActivity aggiungere le istruzioni import seguenti all'inizio della classe.

    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.GoogleApiAvailability;
    import com.google.android.gms.gcm.*;
    import com.microsoft.windowsazure.notifications.NotificationsManager;
    import android.util.Log;
    import android.widget.TextView;
    import android.widget.Toast;
    import android.content.Intent;
    
  5. Aggiungere i seguenti membri privati nella parte superiore della classe. Questo codice verifica la disponibilità di Google Play Services come consigliato da Google.

    public static MainActivity mainActivity;
    public static Boolean isVisible = false;
    private GoogleCloudMessaging gcm;
    private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
    private static final String TAG = "MainActivity";
    
  6. Nella classe MainActivity aggiungere il metodo seguente alla disponibilità di Google Play Services.

    /**
        * Check the device to make sure it has the Google Play Services APK. If
        * it doesn't, display a dialog that allows users to download the APK from
        * the Google Play Store or enable it in the device's system settings.
        */
    private boolean checkPlayServices() {
        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
        int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (apiAvailability.isUserResolvableError(resultCode)) {
                apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
                        .show();
            } else {
                Log.i(TAG, "This device is not supported by Google Play Services.");
                ToastNotify("This device is not supported by Google Play Services.");
                finish();
            }
            return false;
        }
        return true;
    }
    
  7. Nella classe MainActivity aggiungere il codice seguente che cercherà Google Play Services prima di chiamare IntentService per ottenere il token di registrazione di GCM e registrarlo nell'hub di notifica.

    public void registerWithNotificationHubs()
    {
        Log.i(TAG, " Registering with Notification Hubs");
    
        if (checkPlayServices()) {
            // Start IntentService to register this application with GCM.
            Intent intent = new Intent(this, RegistrationIntentService.class);
            startService(intent);
        }
    }
    
  8. Nel metodo OnCreate della classe MainActivity aggiungere il codice seguente per avviare il processo di registrazione quando viene creata l'attività.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        mainActivity = this;
        NotificationsManager.handleNotifications(this, NotificationSettings.SenderId, MyHandler.class);
        registerWithNotificationHubs();
    }
    
  9. Aggiungere questi altri metodi a MainActivity per verificare lo stato dell'app e segnalare lo stato nell'app.

    @Override
    protected void onStart() {
        super.onStart();
        isVisible = true;
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        isVisible = false;
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        isVisible = true;
    }
    
    @Override
    protected void onStop() {
        super.onStop();
        isVisible = false;
    }
    
    public void ToastNotify(final String notificationMessage) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, notificationMessage, Toast.LENGTH_LONG).show();
                TextView helloText = (TextView) findViewById(R.id.text_hello);
                helloText.setText(notificationMessage);
            }
        });
    }
    
  10. Il metodo ToastNotify usa il controllo "Hello World" TextView per segnalare lo stato e le notifiche in modo persistente nell'app. Nel layout di activity_main.xml aggiungere l'ID seguente per il controllo.

    android:id="@+id/text_hello"
    
  11. Aggiungere una sottoclasse per il ricevitore definita nel file AndroidManifest.xml. Aggiungere al progetto un'altra nuova classe denominata MyHandler.

  12. Aggiungere le istruzioni import seguenti all'inizio di MyHandler.java:

    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    import android.support.v4.app.NotificationCompat;
    import com.microsoft.windowsazure.notifications.NotificationsHandler;
    import android.net.Uri;
    import android.media.RingtoneManager;
    
  13. Aggiungere il codice seguente per la classe MyHandler, impostandola come sottoclasse di com.microsoft.windowsazure.notifications.NotificationsHandler.

    Questo codice ignora il metodo OnReceive, quindi il gestore segnala le notifiche ricevute. Il gestore invia anche la notifica push al gestore delle notifiche di Android usando il metodo sendNotification() . Il metodo sendNotification() deve essere eseguito quando l'app non è in esecuzione e si riceve una notifica.

    public class MyHandler extends NotificationsHandler {
        public static final int NOTIFICATION_ID = 1;
        private NotificationManager mNotificationManager;
        NotificationCompat.Builder builder;
        Context ctx;
    
        @Override
        public void onReceive(Context context, Bundle bundle) {
            ctx = context;
            String nhMessage = bundle.getString("message");
            sendNotification(nhMessage);
            if (MainActivity.isVisible) {
                MainActivity.mainActivity.ToastNotify(nhMessage);
            }
        }
    
        private void sendNotification(String msg) {
    
            Intent intent = new Intent(ctx, MainActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    
            mNotificationManager = (NotificationManager)
                    ctx.getSystemService(Context.NOTIFICATION_SERVICE);
    
            PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0,
                    intent, PendingIntent.FLAG_ONE_SHOT);
    
            Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
            NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(ctx)
                            .setSmallIcon(R.mipmap.ic_launcher)
                            .setContentTitle("Notification Hub Demo")
                            .setStyle(new NotificationCompat.BigTextStyle()
                                    .bigText(msg))
                            .setSound(defaultSoundUri)
                            .setContentText(msg);
    
            mBuilder.setContentIntent(contentIntent);
            mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
        }
    }
    
  14. Sulla barra dei menu in Android Studio fare clic su Compila > Ricompila il progetto per assicurarsi che non ci siano errori nel codice.

Testare l'app

Eseguire l'applicazione per dispositivi mobili

  1. Eseguire l'app e notare l'ID registrazione segnalato per una registrazione riuscita.

    Test in Android: registrazione di canali

  2. Immettere un messaggio di notifica da inviare a tutti i dispositivi Android registrati con l'hub.

    Test in Android: invio di un messaggio

  3. Premere Send Notification. Su tutti i dispositivi che eseguono l'app verrà visualizzata un'istanza di AlertDialog con il messaggio di notifica push. I dispositivi che non eseguono l'app, ma che sono stati registrati in precedenza per le notifiche push, riceveranno una notifica in Android Notification Manager. Per visualizzare i messaggi di notifica, scorrere verso il basso dall'angolo superiore sinistro.

    Test in Android: notifiche

Testare l'invio delle notifiche push dal portale di Azure

È possibile testare la ricezione di notifiche push nell'app inviandole tramite il Azure portal.

  1. Nella sezione Risoluzione dei problemi, selezionare Invio di prova.

  2. Per Platforms (Piattaforme) selezionare Android.

  3. Selezionare Invia per inviare la notifica di prova.

  4. Verificare di visualizzare il messaggio di notifica sul dispositivo Android.

    Hub di notifica di Azure: test dell'invio

Le notifiche push vengono in genere inviate in un servizio back-end come App per dispositivi mobili o ASP.NET usando una libreria compatibile. Se non è disponibile una libreria per il back-end è anche possibile usare direttamente l'API REST per inviare messaggi di notifica.

Di seguito è riportato un elenco di altre esercitazioni, che è possibile esaminare per l'invio di notifiche:

Notifiche push nell'emulatore

Per testare le notifiche push all'interno dell'emulatore, assicurarsi che l'immagine dell'emulatore supporti il livello Google API scelto per l'app. Se l'immagine non supporta le API di Google in modalità nativa verrà generata l'eccezione SERVICE_NOT_AVAILABLE.

Verificare anche di avere aggiunto l'account Google all'emulatore in esecuzione in Impostazioni > Account. In caso contrario, i tentativi di registrazione con GCM potrebbero generare l'eccezione AUTHENTICATION_FAILED.

(Facoltativo) Inviare notifiche push direttamente dall'app

In genere, le notifiche vengono inviate tramite un server back-end. In alcuni casi può essere necessario inviare notifiche push direttamente dall'applicazione client. Questa sezione illustra come inviare notifiche dal client usando l' API REST dell'Hub di notifica di Azure.

  1. Nella visualizzazione del progetto in Android Studio espandere App > src > main > res > layout. Aprire il file di layout activity_main.xml e fare clic sulla scheda Text (Testo) per aggiornare il contenuto di testo del file. Aggiornarlo con il codice seguente che aggiunge i nuovi controlli Button e EditText per l'invio di messaggi di notifica push all'hub di notifica. Aggiungere questo codice alla fine, subito prima di </RelativeLayout>.

    <Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/send_button"
    android:id="@+id/sendbutton"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"
    android:onClick="sendNotificationButtonOnClick" />
    
    <EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/editTextNotificationMessage"
    android:layout_above="@+id/sendbutton"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="42dp"
    android:hint="@string/notification_message_hint" />
    
  2. Nella visualizzazione del progetto in Android Studio espandere App > src > main > res > values. Aprire il file strings.xml e aggiungere i valori di stringa a cui fanno riferimento i nuovi controlli Button e EditText. Aggiungere le righe seguenti alla fine del file, subito prima di </resources>.

    <string name="send_button">Send Notification</string>
    <string name="notification_message_hint">Enter notification message text</string>
    
  3. Nel file NotificationSetting.java aggiungere l'impostazione seguente alla classe NotificationSettings.

    Aggiornare HubFullAccess con la stringa di connessione DefaultFullSharedAccessSignature per l'hub. Questa stringa di connessione può essere copiata dal Azure portal facendo clic su Criteri di accesso nella pagina Impostazioni dell'hub di notifica.

    public static String HubFullAccess = "<Enter Your DefaultFullSharedAccess Connection string>";
    
  4. Nel file MainActivity.java aggiungere le istruzioni import seguenti all'inizio del file.

    import java.io.BufferedOutputStream;
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLEncoder;
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    import android.util.Base64;
    import android.view.View;
    import android.widget.EditText;
    
  5. Nel file MainActivity.java aggiungere i membri seguenti all'inizio della classe MainActivity.

    private String HubEndpoint = null;
    private String HubSasKeyName = null;
    private String HubSasKeyValue = null;
    
  6. Creare un token di firma di accesso condiviso (SaS) per autenticare una richiesta POST per l'invio di messaggi all'hub di notifica. Analizzare i dati della chiave dalla stringa di connessione e quindi creare il token di firma di accesso condiviso come indicato in Concetti comuni nelle informazioni di riferimento sull'API REST. Il codice seguente è un esempio di implementazione.

    In MainActivity.java aggiungere il metodo seguente alla classe MainActivity per analizzare la stringa di connessione.

    /**
        * Example code from https://msdn.microsoft.com/library/azure/dn495627.aspx
        * to parse the connection string so a SaS authentication token can be
        * constructed.
        *
        * @param connectionString This must be the DefaultFullSharedAccess connection
        *                         string for this example.
        */
    private void ParseConnectionString(String connectionString)
    {
        String[] parts = connectionString.split(";");
        if (parts.length != 3)
            throw new RuntimeException("Error parsing connection string: "
                    + connectionString);
    
        for (int i = 0; i < parts.length; i++) {
            if (parts[i].startsWith("Endpoint")) {
                this.HubEndpoint = "https" + parts[i].substring(11);
            } else if (parts[i].startsWith("SharedAccessKeyName")) {
                this.HubSasKeyName = parts[i].substring(20);
            } else if (parts[i].startsWith("SharedAccessKey")) {
                this.HubSasKeyValue = parts[i].substring(16);
            }
        }
    }
    
  7. In MainActivity.java aggiungere il metodo seguente alla classe MainActivity per creare un token di autenticazione di firma di accesso condiviso.

    /**
        * Example code from https://msdn.microsoft.com/library/azure/dn495627.aspx to
        * construct a SaS token from the access key to authenticate a request.
        *
        * @param uri The unencoded resource URI string for this operation. The resource
        *            URI is the full URI of the Service Bus resource to which access is
        *            claimed. For example,
        *            "http://<namespace>.servicebus.windows.net/<hubName>"
        */
    private String generateSasToken(String uri) {
    
        String targetUri;
        String token = null;
        try {
            targetUri = URLEncoder
                    .encode(uri.toString().toLowerCase(), "UTF-8")
                    .toLowerCase();
    
            long expiresOnDate = System.currentTimeMillis();
            int expiresInMins = 60; // 1 hour
            expiresOnDate += expiresInMins * 60 * 1000;
            long expires = expiresOnDate / 1000;
            String toSign = targetUri + "\n" + expires;
    
            // Get an hmac_sha1 key from the raw key bytes
            byte[] keyBytes = HubSasKeyValue.getBytes("UTF-8");
            SecretKeySpec signingKey = new SecretKeySpec(keyBytes, "HmacSHA256");
    
            // Get an hmac_sha1 Mac instance and initialize with the signing key
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(signingKey);
    
            // Compute the hmac on input data bytes
            byte[] rawHmac = mac.doFinal(toSign.getBytes("UTF-8"));
    
            // Using android.util.Base64 for Android Studio instead of
            // Apache commons codec
            String signature = URLEncoder.encode(
                    Base64.encodeToString(rawHmac, Base64.NO_WRAP).toString(), "UTF-8");
    
            // Construct authorization string
            token = "SharedAccessSignature sr=" + targetUri + "&sig="
                    + signature + "&se=" + expires + "&skn=" + HubSasKeyName;
        } catch (Exception e) {
            if (isVisible) {
                ToastNotify("Exception Generating SaS : " + e.getMessage().toString());
            }
        }
    
        return token;
    }
    
  8. In MainActivity.java aggiungere il metodo seguente alla classe MainActivity per gestire il clic del pulsante Invia notifica e inviare il messaggio di notifica push all'hub usando l'API REST predefinita.

    /**
        * Send Notification button click handler. This method parses the
        * DefaultFullSharedAccess connection string and generates a SaS token. The
        * token is added to the Authorization header on the POST request to the
        * notification hub. The text in the editTextNotificationMessage control
        * is added as the JSON body for the request to add a GCM message to the hub.
        *
        * @param v
        */
    public void sendNotificationButtonOnClick(View v) {
        EditText notificationText = (EditText) findViewById(R.id.editTextNotificationMessage);
        final String json = "{\"data\":{\"message\":\"" + notificationText.getText().toString() + "\"}}";
    
        new Thread()
        {
            public void run()
            {
                try
                {
                    // Based on reference documentation...
                    // https://msdn.microsoft.com/library/azure/dn223273.aspx
                    ParseConnectionString(NotificationSettings.HubFullAccess);
                    URL url = new URL(HubEndpoint + NotificationSettings.HubName +
                            "/messages/?api-version=2015-01");
    
                    HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
    
                    try {
                        // POST request
                        urlConnection.setDoOutput(true);
    
                        // Authenticate the POST request with the SaS token
                        urlConnection.setRequestProperty("Authorization",
                            generateSasToken(url.toString()));
    
                        // Notification format should be GCM
                        urlConnection.setRequestProperty("ServiceBusNotification-Format", "gcm");
    
                        // Include any tags
                        // Example below targets 3 specific tags
                        // Refer to : https://azure.microsoft.com/documentation/articles/notification-hubs-routing-tag-expressions/
                        // urlConnection.setRequestProperty("ServiceBusNotification-Tags",
                        //        "tag1 || tag2 || tag3");
    
                        // Send notification message
                        urlConnection.setFixedLengthStreamingMode(json.length());
                        OutputStream bodyStream = new BufferedOutputStream(urlConnection.getOutputStream());
                        bodyStream.write(json.getBytes());
                        bodyStream.close();
    
                        // Get response
                        urlConnection.connect();
                        int responseCode = urlConnection.getResponseCode();
                        if ((responseCode != 200) && (responseCode != 201)) {
                            BufferedReader br = new BufferedReader(new InputStreamReader((urlConnection.getErrorStream())));
                            String line;
                            StringBuilder builder = new StringBuilder("Send Notification returned " +
                                    responseCode + " : ")  ;
                            while ((line = br.readLine()) != null) {
                                builder.append(line);
                            }
    
                            ToastNotify(builder.toString());
                        }
                    } finally {
                        urlConnection.disconnect();
                    }
                }
                catch(Exception e)
                {
                    if (isVisible) {
                        ToastNotify("Exception Sending Notification : " + e.getMessage().toString());
                    }
                }
            }
        }.start();
    }
    

Passaggi successivi

In questa esercitazione, le notifiche sono state trasmesse a tutti i dispositivi Android registrati con il back-end. Per informazioni sulle procedure per eseguire il push di notifiche a dispositivi Android specifici, passare all'esercitazione seguente: