Руководство. Отправка уведомлений на определенные устройства с помощью Центров уведомлений и Google Firebase Cloud Messaging
Обзор
Внимание
По состоянию на июнь 2024 года устаревшие API FCM больше не будут поддерживаться и будут прекращены. Чтобы избежать сбоев в службе push-уведомлений, необходимо как можно скорее перейти к протоколу FCM версии 1.
В этом руководстве показано, как использовать Центры уведомлений Azure для рассылки широковещательных уведомлений о последних новостях в приложение Android. По завершении вы сможете зарегистрироваться в интересующих вас категориях экстренных новостей и получать push-уведомления только для этих категорий. Этот сценарий часто используется во многих приложениях, которые отправляют уведомления определенным группам пользователей, подтвердившим интерес к этим уведомлениям. Типичные примеры: средства чтения RSS, приложения для любителей музыки и т. д.
Широковещательные сценарии реализуются путем включения одного или нескольких тегов при создании регистрации в концентраторе уведомлений. Если уведомления отправляются на тег, их получают все устройства, зарегистрированные для данного тега. Поскольку теги представляют собой обычные строки, их не нужно подготавливать заранее. Дополнительные сведения о тегах см. в статье Маршрутизация и выражения тегов.
Вот какие действия выполняются в этом руководстве:
- добавление возможности выбора категорий в мобильное приложение;
- регистрация для получения уведомлений с тегами;
- отправка уведомлений с тегами.
- Тестирование приложения
Необходимые компоненты
В этом руководстве описывается приложение, созданное в руководстве. Push-уведомления на устройства Android с помощью Центров уведомлений Azure и Firebase Cloud Messaging. Перед началом работы с этим руководством выполните инструкции по отправке push-уведомлений на устройства Android с помощью Центров уведомлений Azure и Firebase Cloud Messaging.
Добавление возможности выбора категорий в приложение
Прежде всего, необходимо добавить элементы пользовательского интерфейса для имеющегося основного действия, позволяющие пользователю выбирать категории для регистрации. Выбранные пользователем категории хранятся на устройстве. При запуске приложения в концентраторе уведомлений создается регистрация устройства с выбранными категориями, представленными в форме тегов.
Откройте файл
res/layout/activity_main.xml file
и замените его содержимое следующим кодом:<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>
Откройте файл
res/values/strings.xml
и добавьте следующие строки:<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>
Графическая структура файла
main_activity.xml
должна выглядеть следующим образом:Создайте класс
Notifications
в том же пакете, в котором существует класс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); } }
Этот класс использует локальное хранилище для хранения категорий новостей, которые данное устройство должно получать. Он также содержит методы для регистрации этих категорий.
В класс
MainActivity
добавьте поле дляNotifications
.private Notifications notifications;
Затем обновите метод
onCreate
, как показано в следующем коде. Регистрация в Центрах уведомлений осуществляется посредством метода subscribeToCategories класса Notifications.@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()); }
Убедитесь, что в классе NotificationSettings правильно указаны имя центра и строка подключения.
Примечание.
Так как учетные данные, которые распространяются с помощью клиентского приложения, обычно небезопасны, с помощью вашего клиентского приложения следует распространять только ключ для доступа к прослушиванию. Доступ к прослушиванию позволяет приложению регистрироваться для использования уведомлений, однако при этом нельзя изменять имеющиеся регистрации и отправлять уведомления. Для отправки уведомлений и изменения существующих регистраций используется ключ полного доступа в защищенной серверной службе.
Теперь добавьте следующие операторы import:
import android.widget.CheckBox; import java.util.HashSet; import java.util.Set; import android.view.View;
Добавьте этот метод
subscribe
для обработки нажатия кнопки "Подписаться":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); }
Этот метод создает список категорий и использует класс
Notifications
для хранения списка в локальном хранилище и регистрации соответствующих тегов в концентраторе уведомлений. При изменении категорий регистрация создается заново с новыми категориями.
Ваше приложение теперь может сохранять набор категорий в локальном хранилище на устройстве и регистрироваться в центре уведомлений всякий раз, когда пользователь изменяет выбранные категории.
Регистрация для использования уведомлений
Эти действия позволяют зарегистрироваться в концентраторе уведомлений при запуске с использованием категорий, сохраненных в локальном хранилище.
Убедитесь, что приведенный ниже код добавлен в конец метода
onCreate
в классеMainActivity
.notifications.subscribeToCategories(notifications.retrieveCategories());
Этот код гарантирует, что при каждом запуске приложения категории извлекаются из локального хранилища и для них запрашивается регистрация.
Затем обновите метод
onStart()
класса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")); }
Этот код обновляет основное действие в зависимости от состояния ранее сохраненных категорий.
Теперь приложение готово и может сохранять набор категорий в локальном хранилище устройств и использовать его для регистрации в концентраторе уведомлений всякий раз, когда пользователь изменяет выбранные категории. Теперь определите серверную часть, которая может отправлять в это приложение уведомления по категориям.
Отправка уведомлений с тегами
В этом разделе вы будете отправлять экстренные новости в виде шаблонных уведомлений с тегами из консольного приложения .NET.
Создайте в Visual Studio новое консольное приложение Visual C#.
- В меню выберите Файл>Создать>Проект.
- В окне Создание проекта выберите в списке шаблонов Консольное приложение (.NET Framework) для C# и нажмите кнопку Далее.
- Введите название приложения.
- Для параметра Решение, выберите Добавить к решению и Создать, чтобы создать проект.
Выберите Инструменты>Диспетчер пакетов NuGet>Консоль диспетчера пакетов, а затем в окне консоли выполните следующую команду:
Install-Package Microsoft.Azure.NotificationHubs
Это действие добавляет ссылку на пакет SDK для Центров уведомлений Azure с помощью пакета Microsoft.Azure.NotificationHubs.
Откройте файл Program.cs и добавьте следующий оператор
using
:using Microsoft.Azure.NotificationHubs;
В класс
Program
добавьте следующий метод или замените его, если он уже существует: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); } }
Этот код отправляет шаблонное уведомление по каждому из шести тегов в массиве строк. Использование тегов гарантирует, что устройства будут получать уведомления только зарегистрированных категорий.
В предыдущем коде замените заполнители
<hub name>
и<connection string with full access>
именем центра уведомлений и строкой подключения для DefaultFullSharedAccessSignature, полученными ранее на панели мониторинга центра уведомлений.Добавьте следующие строки в метод
Main()
:SendTemplateNotificationAsync(); Console.ReadLine();
Выполните сборку консольного приложения.
Тестирование приложения
Запустите приложение в Android Studio на устройстве Android или в эмуляторе. В пользовательском интерфейсе присутствует набор переключателей, позволяющий выбрать категории для подписки.
Включите переключатели одной или нескольких категорий, затем нажмите Подписаться. Приложение преобразует выбранные категории в теги и запрашивает у концентратора уведомлений новую регистрацию устройств для выбранных тегов. Зарегистрированные категории возвращаются и отображаются во всплывающем уведомлении.
Запустите консольное приложение .NET, которое отправляет уведомления по каждой категории. Уведомления для выбранных категорий отображаются в виде всплывающих уведомлений.
Следующие шаги
Из этого руководства вы узнали, как рассылать широковещательные уведомления на конкретные устройства Android, зарегистрированные для получения уведомлений по категориям. Сведения о том, как отправлять push-уведомления конкретным пользователям, вы найдете в следующем руководстве: