Kurz: Odesílání oznámení konkrétním zařízením pomocí Notification Hubs a Google Firebase Cloud Messaging

Přehled

V tomto kurzu se naučíte používat službu Azure Notification Hubs k vysílání důležitých oznámení do aplikací pro Android. Po dokončení kurzu si budete moct zaregistrovat kategorie důležitých oznámení, které vás zajímají, abyste dostávali nabízená oznámení, která se týkají jenom těchto kategorií. Tento scénář se běžně používá v řadě aplikací, které posílají oznámení skupinám uživatelům, kteří o ně projevili zájem. Může jít třeba o čtečku RSS, aplikaci pro hudební fanoušky atd.

Scénáře vysílání povolíte tak, že při registraci v centru oznámení přidáte jednu nebo více značek. Pokud se oznámení posílají značce, přijdou všem zařízením, která si značku zaregistrovala. Značky jsou jednoduše řetězce, které se nemusejí vytvářet předem. Další informace o značkách najdete v článku Směrování a výrazy značek ve službě Notification Hubs.

V tomto kurzu provedete následující akce:

  • Přidáte do mobilní aplikace výběr kategorií.
  • Registrováno pro oznámení se značkami.
  • Odešlete označená oznámení.
  • Otestování aplikace

Požadavky

Tento kurz vychází z aplikace, kterou jste vytvořili v kurzu: Nabízená oznámení do zařízení s Androidem pomocí služby Azure Notification Hubs a Firebase Cloud Messaging. Před zahájením tohoto kurzu dokončete kurz: Nabízená oznámení do zařízení s Androidem pomocí služby Azure Notification Hubs a Firebase Cloud Messaging.

Přidání výběru kategorií do aplikace

První krok spočívá v přidání prvků uživatelského rozhraní do stávající třídy MainActivity, aby si uživatel mohl vybrat kategorie, které si zaregistruje. Kategorie, které uživatel vybere, jsou uložené v zařízení. Při spuštění aplikace se v centru oznámení provede registrace zařízení s vybranými kategoriemi ve formě značek.

  1. res/layout/activity_main.xml fileOtevřete a nahraďte obsah následujícím kódem:

    <LinearLayout 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="com.example.breakingnews.MainActivity"
        android:orientation="vertical">
    
            <CheckBox
                android:id="@+id/worldBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_world" />
            <CheckBox
                android:id="@+id/politicsBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_politics" />
            <CheckBox
                android:id="@+id/businessBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_business" />
            <CheckBox
                android:id="@+id/technologyBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_technology" />
            <CheckBox
                android:id="@+id/scienceBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_science" />
            <CheckBox
                android:id="@+id/sportsBox"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/label_sports" />
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:onClick="subscribe"
                android:text="@string/button_subscribe" />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Hello World!"
                android:id="@+id/text_hello"
            />
    </LinearLayout>
    
  2. res/values/strings.xml Otevřete soubor a přidejte následující řádky:

    <string name="button_subscribe">Subscribe</string>
    <string name="label_world">World</string>
    <string name="label_politics">Politics</string>
    <string name="label_business">Business</string>
    <string name="label_technology">Technology</string>
    <string name="label_science">Science</string>
    <string name="label_sports">Sports</string>
    

    Grafické main_activity.xml rozložení by mělo vypadat jako na následujícím obrázku:

    Screenshot of an emulator displaying what the main activity X M L graphical layout will look like.

  3. Vytvořte třídu Notifications ve stejném balíčku jako třída MainActivity .

    import java.util.HashSet;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    
    import android.content.Context;
    import android.content.SharedPreferences;
    import android.os.AsyncTask;
    import android.util.Log;
    import android.widget.Toast;
    
    import com.google.android.gms.tasks.OnSuccessListener;
    import com.google.firebase.iid.FirebaseInstanceId;
    import com.google.firebase.iid.InstanceIdResult;
    import com.microsoft.windowsazure.messaging.NotificationHub;
    
    public class Notifications {
        private static final String PREFS_NAME = "BreakingNewsCategories";
        private FirebaseInstanceId fcm;
        private NotificationHub hub;
        private Context context;
        private String senderId;
        public static String FCM_token = "";
        private static final String TAG = "Notifications";
    
        public Notifications(Context context, String hubName, String listenConnectionString) {
            this.context = context;
            this.senderId = senderId;
    
            fcm = FirebaseInstanceId.getInstance();
            hub = new NotificationHub(hubName, listenConnectionString, context);
        }
    
        public void storeCategoriesAndSubscribe(Set<String> categories)
        {
            SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
            settings.edit().putStringSet("categories", categories).commit();
            subscribeToCategories(categories);
        }
    
        public Set<String> retrieveCategories() {
            SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
            return settings.getStringSet("categories", new HashSet<String>());
        }
    
        public void subscribeToCategories(final Set<String> categories) {
            new AsyncTask<Object, Object, Object>() {
                @Override
                protected Object doInBackground(Object... params) {
                    try {
                        FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
                            @Override
                            public void onSuccess(InstanceIdResult instanceIdResult) {
                                FCM_token = instanceIdResult.getToken();
                                Log.d(TAG, "FCM Registration Token: " + FCM_token);
                            }
                        });
    
                        TimeUnit.SECONDS.sleep(1);
    
                        String templateBodyFCM = "{\"data\":{\"message\":\"$(messageParam)\"}}";
    
                        hub.registerTemplate(FCM_token,"simpleFCMTemplate", templateBodyFCM,
                                categories.toArray(new String[categories.size()]));
                    } catch (Exception e) {
                        Log.e("MainActivity", "Failed to register - " + e.getMessage());
                        return e;
                    }
                    return null;
                }
    
                protected void onPostExecute(Object result) {
                    String message = "Subscribed for categories: "
                            + categories.toString();
                    Toast.makeText(context, message,
                            Toast.LENGTH_LONG).show();
                }
            }.execute(null, null, null);
        }
    
    }
    

    Tato třída uloží kategorie novinek, které bude zařízení dostávat, do místního úložiště. Obsahuje také metody registrace kategorií.

  4. Do předmětu MainActivity přidejte pole pro Notifications:

    private Notifications notifications;
    
  5. Pak aktualizujte metodu onCreate , jak je znázorněno v následujícím kódu. Zaregistrujete se ve službě Notification Hubs v metodě subscribeToCategories třídy Notification .

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        mainActivity = this;
    
        FirebaseService.createChannelAndHandleNotifications(getApplicationContext());
        notifications = new Notifications(this, NotificationSettings.HubName, NotificationSettings.HubListenConnectionString);
        notifications.subscribeToCategories(notifications.retrieveCategories());
    }
    

    Potvrďte správné nastavení názvu centra a připojovacího řetězce ve třídě NotificationSettings.

    Poznámka

    Obecně platí, že přihlašovací údaje distribuované klientskou aplikací nejsou příliš bezpečné, a proto byste měli s klientskou aplikací distribuovat jenom přístupový klíč pro naslouchání. Přístup pro naslouchání umožňuje aplikaci registrovat oznámení, ale nedovolí měnit stávající registrace ani odesílat oznámení. Plný přístupový klíč se používá v zabezpečené back-endové službě k posílání oznámení a změně stávajících registrací.

  6. Pak přidejte následující importy:

    import android.widget.CheckBox;
    import java.util.HashSet;
    import java.util.Set;
    import android.view.View;
    
  7. Přidejte následující metodu subscribe, která zpracuje událost kliknutí na tlačítko Přihlášení k odběru:

    public void subscribe(View sender) {
        final Set<String> categories = new HashSet<String>();
    
        CheckBox world = (CheckBox) findViewById(R.id.worldBox);
        if (world.isChecked())
            categories.add("world");
        CheckBox politics = (CheckBox) findViewById(R.id.politicsBox);
        if (politics.isChecked())
            categories.add("politics");
        CheckBox business = (CheckBox) findViewById(R.id.businessBox);
        if (business.isChecked())
            categories.add("business");
        CheckBox technology = (CheckBox) findViewById(R.id.technologyBox);
        if (technology.isChecked())
            categories.add("technology");
        CheckBox science = (CheckBox) findViewById(R.id.scienceBox);
        if (science.isChecked())
            categories.add("science");
        CheckBox sports = (CheckBox) findViewById(R.id.sportsBox);
        if (sports.isChecked())
            categories.add("sports");
    
        notifications.storeCategoriesAndSubscribe(categories);
    }
    

    Tato metoda vytvoří seznam kategorií a pomocí Notifications třídy uloží seznam do místního úložiště a zaregistruje odpovídající značky v centru oznámení. Při změně kategorií se vytvoří registrace s novými kategoriemi.

Aplikace teď dokáže do místního úložiště v zařízení uložit sadu kategorií a zaregistrovat ji v centru oznámení pokaždé, když uživatel změní vybrané kategorie.

Registrace oznámení

Tento postup provede při spuštění registraci v centru oznámení. Použije k tomu kategorie uložené v místním úložišti.

  1. Ověřte, že na konci onCreate metody ve MainActivity třídě je následující kód:

    notifications.subscribeToCategories(notifications.retrieveCategories());
    

    Tento kód zajistí, aby aplikace při každém spuštění načetla kategorie z místního úložiště a vyžadovala registraci těchto kategorií.

  2. Potom aktualizujte metodu onStart() třídy MainActivity:

    @Override
    protected void onStart() {
    
        super.onStart();
        isVisible = true;
    
        Set<String> categories = notifications.retrieveCategories();
    
        CheckBox world = (CheckBox) findViewById(R.id.worldBox);
        world.setChecked(categories.contains("world"));
        CheckBox politics = (CheckBox) findViewById(R.id.politicsBox);
        politics.setChecked(categories.contains("politics"));
        CheckBox business = (CheckBox) findViewById(R.id.businessBox);
        business.setChecked(categories.contains("business"));
        CheckBox technology = (CheckBox) findViewById(R.id.technologyBox);
        technology.setChecked(categories.contains("technology"));
        CheckBox science = (CheckBox) findViewById(R.id.scienceBox);
        science.setChecked(categories.contains("science"));
        CheckBox sports = (CheckBox) findViewById(R.id.sportsBox);
        sports.setChecked(categories.contains("sports"));
    }
    

    Tento kód aktualizuje třídu MainActivity na základě stavu dříve uložených kategorií.

Hotová aplikace teď do místního úložiště v zařízení uloží sadu kategorií. Tato sada se použije k registraci v centru oznámení pokaždé, když uživatel změní vybrané kategorie. V dalším kroku definujte back-end, který aplikaci posílá oznámení týkající se kategorií.

Posílání označených oznámení

V této části odešlete nejnovější zprávy jako šablonové oznámení se značkami z konzolové aplikace .NET.

  1. Ve Visual Studiu vytvořte novou konzolovou aplikaci Visual C#:

    1. V nabídce vyberte FileNew>>Project.
    2. V části Vytvořit nový projekt vyberte konzolovou aplikaci (.NET Framework) pro C# v seznamu šablon a vyberte Další.
    3. Zadejte název aplikace.
    4. V případě řešení zvolte Přidat do řešení a vyberte Vytvořit a vytvořte projekt.
  2. Vyberte Nástroje>NuGet Správce balíčků>Správce balíčků Konzola a potom v okně konzoly spusťte následující příkaz:

    Install-Package Microsoft.Azure.NotificationHubs
    

    Tato akce přidá odkaz na sadu Azure Notification Hubs SDK pomocí balíčku Microsoft.Azure.NotificationHubs .

  3. Otevřete soubor Program.cs a přidejte následující using příkaz:

    using Microsoft.Azure.NotificationHubs;
    
  4. Do třídy Program přidejte následující metodu, nebo ji nahraďte, pokud už existuje:

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

    Tento kód odešle šablonové oznámení pro každou z šesti značek v poli řetězců. Použití značek zajišťuje, že zařízení budou přijímat oznámení jenom pro registrované kategorie.

  5. V předchozím kódu nahraďte zástupné symboly <hub name> a <connection string with full access> názvem vašeho centra oznámení a připojovacím řetězcem pro DefaultFullSharedAccessSignature z řídicího panelu vašeho centra oznámení.

  6. Main() Do metody přidejte následující řádky:

     SendTemplateNotificationAsync();
     Console.ReadLine();
    
  7. Sestavte konzolovou aplikaci.

Otestování aplikace

  1. V Android Studiu spusťte aplikaci buď na zařízení s Androidem, nebo v emulátoru. Uživatelské rozhraní aplikace nabízí sadu přepínačů, kterými můžete vybrat odebírané kategorie.

  2. Zapněte jeden nebo více přepínačů kategorií a klikněte na Přihlásit k odběru. Aplikace převede vybrané kategorie na značky a u vybraných značek požádá centrum oznámení o registraci nových zařízení. Zaregistrované kategorie se vrátí a zobrazí se v informační zprávě.

    Subscribe for categories

  3. Spusťte konzolovou aplikaci .NET, která zasílá oznámení o každé kategorii. Oznámení pro vybrané kategorie se zobrazí jako informační zprávy.

    Technology news notifications

Další kroky

V tomto kurzu jste odeslali nabízená oznámení určitým zařízením s Androidem, která si zaregistrovala kategorie. Pokud se chcete naučit zasílat nabízená oznámení určitým uživatelům, pokračujte následujícím kurzem: