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
- Sottoscrizione di Azure. Se non si ha una sottoscrizione di Azure, creare un account Azure gratuito prima di iniziare.
- Android Studio.
Creazione di un progetto che supporta Google Cloud Messaging
Passare a Google Cloud Consoleed eseguire l'accesso con le credenziali dell'account Google.
Selezionare Crea progetto sulla barra degli strumenti.
In Project name (Nome del progetto) immettere un nome per il progetto e fare clic su Create (Crea).
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>
Prendere nota del numero di progetto in Project number nel riquadro Project info (Informazioni sul progetto) del dashboard.
Nel dashboard, nel riquadro APIs (API) selezionare Go to APIs overview (Vai a panoramica API).
Nella pagina API selezionare Enable APIs and Services (Abilita API e servizi).
Cercare e selezionare Google Cloud Messaging.
Per abilitare Google Cloud Messaging per il progetto, selezionare Enable (Abilita).
Selezionare Create credentials (Crea credenziali) sulla barra degli strumenti.
Nella pagina Add credentials to your project (Aggiungi credenziali al progetto) selezionare il collegamento API key (Chiave API).
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.
Copiare la chiave API negli Appunti e salvarla altrove.
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
Accedere al portale di Azure.
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.
Nella pagina Hub di notifica selezionare Crea sulla barra degli strumenti.
Nella scheda Informazioni di base della pagina Hub di notifica seguire questa procedura:
In Sottoscrizione selezionare il nome della sottoscrizione di Azure da usare e quindi selezionare un gruppo di risorse esistente oppure crearne uno nuovo.
Immettere un nome univoco per il nuovo spazio dei nomi in Dettagli spazio dei nomi.
Uno spazio dei nomi contiene uno o più hub di notifica, quindi digitare un nome per l'hub in Dettagli hub di notifica. In alternativa, selezionare uno spazio dei nomi esistente dall'elenco a discesa.
Selezionare un valore nell'elenco a discesa Posizione. Questo valore specifica la posizione in cui creare l'hub.
Selezionare Crea.
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.
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.
Configurare l'impostazione di GCM per l'hub di notifica
Selezionare Google (GCM) in IMPOSTAZIONI NOTIFICHE.
Immettere la Chiave API ricevuta dalla console di Google Cloud.
Sulla barra degli strumenti selezionare Salva.
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
In Android Studio avviare un nuovo progetto Android Studio.
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.
Scegliere Empty Activity (Attività vuota) per l'attività principale, fare clic su Avanti, quindi su Fine.
Aggiungere Google Play Services al progetto
In Android Studio selezionare Strumenti nel menu e quindi SDK Manager.
Selezionare la versione di destinazione di Android SDK che viene usata nel progetto. Quindi selezionare Mostra i dettagli del pacchetto.
Selezionare API Google, se non è già installato.
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.
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).
Selezionare OK per chiudere la finestra di dialogo Settings for New Projects (Impostazioni per nuovi progetti).
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'
Selezionare l'icona Sincronizza ora nella barra degli strumenti
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
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'
Aggiungere l'archivio seguente dopo la sezione dependencies .
repositories { maven { url "https://dl.bintray.com/microsoftazuremobile/SDK" } }
Aggiornamento del file AndroidManifest.xml del progetto
Per supportare GCM, implementare un servizio listener ID istanza nel codice usato per ottenere i token di registrazione usando l'API ID istanza di 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 fileAndroidManifest.xml
.<service android:name="<your package>.MyInstanceIDService" android:exported="false"> <intent-filter> <action android:name="com.google.android.gms.iid.InstanceID"/> </intent-filter> </service>
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
denominatoRegistrationIntentService
. 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 fileAndroidManifest.xml
.<service android:name="<your package>.RegistrationIntentService" android:exported="false"> </service>
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 fileAndroidManifest.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>
Aggiungere le autorizzazioni GCM necessarie seguenti sotto il
<application>
tag. Sostituire<your package>
con il nome del pacchetto visualizzato all'inizio del fileAndroidManifest.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
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
.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>"; }
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); } };
Aggiungere al progetto un'altra nuova classe denominata
RegistrationIntentService
. Questa classe implementaIntentService
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); } } }
Nella classe
MainActivity
aggiungere le istruzioniimport
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;
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";
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; }
Nella classe
MainActivity
aggiungere il codice seguente che cercherà Google Play Services prima di chiamareIntentService
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); } }
Nel metodo
OnCreate
della classeMainActivity
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(); }
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); } }); }
Il
ToastNotify
metodo usa il controllo "Hello World"TextView
per segnalare in modo permanente lo stato e le notifiche nell'app. Nel layout di activity_main.xml aggiungere l'ID seguente per il controllo.android:id="@+id/text_hello"
Aggiungere una sottoclasse per il ricevitore definita nel file AndroidManifest.xml. Aggiungere al progetto un'altra nuova classe denominata
MyHandler
.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;
Aggiungere il codice seguente per la classe
MyHandler
, impostandola come sottoclasse dicom.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 metodosendNotification()
. Il metodosendNotification()
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()); } }
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
Eseguire l'app e notare l'ID registrazione segnalato per una registrazione riuscita.
Immettere un messaggio di notifica da inviare a tutti i dispositivi Android registrati con l'hub.
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.
Testare l'invio delle notifiche push dal portale di Azure
È possibile testare la ricezione di notifiche push nell'app inviandole tramite il Azure portal.
Nella sezione Risoluzione dei problemi, selezionare Invio di prova.
Per Platforms (Piattaforme) selezionare Android.
Selezionare Invia per inviare la notifica di prova.
Verificare di visualizzare il messaggio di notifica sul dispositivo Android.
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:
- App per dispositivi mobili di Azure: per un esempio di come inviare notifiche dal back-end di un'app per dispositivi mobili integrata con Hub di notifica, vedere Aggiungere notifiche push all'app iOS.
- ASP.NET: usare Hub di notifica per inviare notifiche push agli utenti.
- SDK per Java di Hub di notifica di Azure: vedere Come usare Hub di notifica da Java per l'invio di notifiche da Java. È stato testato in Eclipse per lo sviluppo per Android.
- PHP: Come usare Hub di notifica da PHP.
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 Google native, si verifica 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 causare 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.
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 controlliButton
eEditText
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" />
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 controlliButton
eEditText
. 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>
Nel file
NotificationSetting.java
aggiungere l'impostazione seguente alla classeNotificationSettings
.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>";
Nel file
MainActivity.java
aggiungere le istruzioniimport
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;
Nel file
MainActivity.java
aggiungere i membri seguenti all'inizio della classeMainActivity
.private String HubEndpoint = null; private String HubSasKeyName = null; private String HubSasKeyValue = null;
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 classeMainActivity
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); } } }
In
MainActivity.java
aggiungere il metodo seguente alla classeMainActivity
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; }
In
MainActivity.java
aggiungere il metodo seguente alla classeMainActivity
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: