Руководство. Отправка push-уведомлений на устройства Android с помощью пакета SDK Firebase версии 0.6
В этом руководстве показано, как использовать Центры уведомлений Azure и Firebase Cloud Messaging (FCM) SDK версии 0.6 для отправки push-уведомлений в приложение на платформе Android. Следуя инструкциям этого руководства, вы создадите пустое приложение Android, которое получает push-уведомления с помощью Firebase Cloud Messaging.
Внимание
Google перестанет поддерживать устаревший ПРОТОКОЛ HTTP FCM 20 июня 2024 года. Дополнительные сведения см. в статье "Центры уведомлений Azure" и миграция Google Firebase Cloud Messaging.
Полный код для этого руководства можно скачать на сайте GitHub.
При работе с этим руководством вы выполните следующие задачи:
- Создание проекта Android Studio.
- Создание проекта Firebase с поддержкой Firebase Cloud Messaging.
- Создайте концентратор.
- Подключение своего приложения к концентратору.
- Тестирование приложения.
Необходимые компоненты
Для работы с этим учебником необходима активная учетная запись Azure. Если ее нет, можно создать бесплатную пробную учетную запись всего за несколько минут. Дополнительные сведения см. на странице бесплатной пробной версии Azure.
Вам также понадобятся следующее.
- Последняя версия Android Studio.
- Android версии 2.3 или более поздней.
- Репозиторий Google версии 27 или более поздней.
- Службы Google Play версии 9.0.2 или более поздней.
Завершение изучения этого учебника является необходимым условием для работы со всеми другими учебниками, посвященными Центрам уведомлений для приложений Android.
Создание проекта Android Studio
- Запустите Android Studio.
- В меню выберите File (Файл), New (Создать), а затем — New Project (Создать проект).
- На странице Choose your project (Выбор проекта) выберите Empty Activity (Пустое действие) и щелкните Далее.
- На странице "Настройка проекта" выполните следующие действия:
Введите имя приложения.
Укажите расположение для сохранения файлов проекта.
Выберите Готово.
Создание проекта Firebase с поддержкой FCM
Войдите в консоль Firebase. Создайте проект Firebase, если его еще нет.
После создания проекта выберите Add Firebase to your Android app (Добавить Firebase в приложение Android).
Выполните следующие действия на странице Add Firebase to your Android app (Добавление Firebase в приложение Android):
Для параметра Android package name (Имя пакета Android) скопируйте свое значение applicationId в файл приложения build.gradle. В нашем примере это значение выглядит следующим образом:
com.fabrikam.fcmtutorial1app
.Выберите Регистрация приложения.
Выберите Download google-services.json (Загрузить google-services.json), сохраните файл в папку приложения проекта, а затем выберите Далее.
Внесите следующие изменения конфигурации в проект в Android Studio.
В файл build.gradle уровня проекта (<project>/build.gradle) добавьте в раздел dependencies следующий текст.
classpath 'com.google.gms:google-services:4.0.1'
В файле build.gradle уровня приложения (<project>/<app-module>/build.gradle) в раздел зависимостей добавьте следующий текст.
implementation 'com.google.firebase:firebase-core:16.0.8' implementation 'com.google.firebase:firebase-messaging:17.3.4'
Добавьте следующую строку в конец файла build.gradle уровня приложения после раздела с зависимостями.
apply plugin: 'com.google.gms.google-services'
На панели инструментов щелкните Синхронизировать сейчас.
Выберите Далее.
Выберите Пропустить этот шаг.
В консоли Firebase щелкните значок шестеренки возле имени проекта. Выберите пункт Project Settings (Параметры проекта).
Если вы еще не скачали файл google-services.json в папку app проекта Android Studio, это можно сделать на этой странице.
Переключитесь на вкладку Обмен сообщениями в облаке в верхней части.
Скопируйте и сохраните Ключ сервера для последующего использования. Это значение используется для настройки имени центра.
Если на вкладке firebase Cloud Messaging не отображается ключ сервера, выполните следующие действия.
- Щелкните меню с тремя точками заголовка "Api обмена сообщениями (устаревшая версия) 🚫 "Отключено"
- Перейдите по предлагаемой ссылке на "Управление API в Google Cloud Console".
- В облачной консоли Google нажмите кнопку, чтобы включить API googlecloudmessaging.
- Подождите несколько минут.
- Вернитесь на вкладку проекта консоли firebase Cloud Messaging и обновите страницу.
- Узнайте, что заголовок API cloud Messaging изменился на "Включено API обмена сообщениями в облаке (устаревшая версия) ✅ и теперь отображает ключ сервера.
Настройка концентратора
Войдите на портал Azure.
В меню слева выберите Все службы.
Введите центры уведомлений в текстовом поле " Службы фильтрации". Щелкните значок звездочки рядом с именем службы, чтобы добавить ее в раздел Избранное в меню слева. Выберите Центры уведомлений.
На странице Центры уведомлений выберите Добавить на панели инструментов.
На вкладке Основные сведения на странице Центр уведомлений выполните следующие действия:
В поле Подписка выберите имя подписки Azure, которую вы хотите использовать, а затем выберите существующую группу ресурсов или создайте новую.
Введите уникальное имя нового пространства имен в разделе Сведения о пространстве имен.
Пространство имен содержит один или несколько концентраторов уведомлений, поэтому укажите имя концентратора в разделе Сведения о Центре уведомлений.
Выберите значение в раскрывающемся списке Расположение. Это значение определяет расположение, в котором создается центр.
Просмотрите параметр Зоны доступности. Если вы выбрали регион с зонами доступности, установите флажок по умолчанию. Зоны доступности является платной функцией, поэтому дополнительная плата добавляется на ваш уровень.
Выберите вариант аварийного восстановления: Нет, парный регион восстановления или гибкий регион восстановления. При выборе парного региона восстановления отображается регион отработки отказа. Если выбрать гибкий регион восстановления, используйте раскрывающийся список регионов восстановления.
Нажмите кнопку создания.
После завершения развертывания выберите "Перейти к ресурсу".
Настройка параметров Firebase Cloud Messaging для центра
На панели слева в разделе Параметры, выберите Google (GCM/FCM).
Введите ключ сервера для проекта FCM, сохраненного ранее.
На панели инструментов нажмите кнопку Сохранить.
Портал Azure отображает предупреждения о том, что концентратор был успешно обновлен. Кнопка Сохранить отключена.
Теперь ваша служба настроена для работы с Firebase Cloud Messaging. У вас также есть строки подключения, которые необходимы для отправки уведомлений на устройство и регистрации приложения для получения уведомлений.
Подключение приложения к центру уведомлений
Добавление служб Google Play в проект
В Android Studio в меню выберите Средства, а затем — Диспетчер пакетов SDK.
Выберите целевую версию пакета SDK для Android, который используется в проекте. Затем выберите Show Package Details (Показать сведения о пакете).
Выберите Google APIs (API-интерфейсы Google), если они еще не установлены.
Перейдите на вкладку "Средства SDK". Если вы еще не установили службы Google Play, выберите Службы Google Play, как показано на следующем рисунке. Затем выберите Применить для установки. Запишите путь к пакету SDK. Он вам потребуется в дальнейшем.
Если вы видите диалоговое окно Подтвердить изменение, выберите ОК. Установщик компонентов устанавливает запрошенные компоненты. После установки компонентов выберите Готово.
Выберите ОК, чтобы закрыть диалоговое окно Settings for New Projects (Параметры для новых проектов).
Откройте файл AndroidManifest.xml, а затем добавьте следующий тег для тега приложения.
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
Затем добавьте библиотеки Центров уведомлений Azure.
В файле Build.Gradle для приложений добавьте следующие строки в раздел dependencies.
implementation 'com.microsoft.azure:notification-hubs-android-sdk:0.6@aar'
После раздела dependencies добавьте следующий репозиторий.
repositories { maven { url "https://dl.bintray.com/microsoftazuremobile/SDK" } }
Добавление поддержки Google Firebase
В файле Build.Gradle для приложения добавьте следующие строки в раздел dependencies, если они еще не существуют.
implementation 'com.google.firebase:firebase-core:16.0.8' implementation 'com.google.firebase:firebase-messaging:17.3.4' implementation 'com.google.firebase:firebase-iid:21.1.0'
Добавьте следующий подключаемый модуль в конце файла, если он еще не выбран.
apply plugin: 'com.google.gms.google-services'
На панели инструментов щелкните Синхронизировать сейчас.
Обновите файл AndroidManifest.xml
После получения маркера регистрации в FCM используйте его для регистрации в Центрах уведомлений Azure. Регистрация в фоновом режиме выполняется с помощью службы
IntentService
с именемRegistrationIntentService
. Эта служба также обновит ваш маркер регистрации FCM. Также создается класс с именемFirebaseService
в качестве подклассаFirebaseMessagingService
и переопределяется методonMessageReceived
для получения и обработки уведомлений.Добавьте приведенное ниже определение службы внутри тега
<application>
в файле AndroidManifest.xml.<service android:name=".RegistrationIntentService" android:exported="false"> </service> <service android:name=".FirebaseService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
Добавьте следующие разрешения, связанные с FCM, под тегом
</application>
.<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.GET_ACCOUNTS"/> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
Добавить код
В представлении проекта разверните узел app>src>main>java. Щелкните правой кнопкой мыши папку своего пакета в разделе java, выберите New (Создать), а затем выберите класс Java. Укажите NotificationSettings для имени, а затем нажмите кнопку ОК.
Обязательно обновите эти два заполнителя в следующем коде для класса
NotificationSettings
:HubListenConnectionString — укажите для Центра строку подключения DefaultListenAccessSignature. Чтобы скопировать эту строку подключения, щелкните пункт Политики доступа в своем центре на портале Azure.
HubName: используйте имя концентратора, который отображается на центральной странице в портал Azure.
NotificationSettings
:public class NotificationSettings { public static String HubName = "<Your HubName>"; public static String HubListenConnectionString = "<Enter your DefaultListenSharedAccessSignature connection string>"; }
Внимание
Прежде чем продолжить, введите имя и DefaultListenSharedAccessSignature вашего концентратора.
Добавьте еще один новый класс в проект
RegistrationIntentService
. Этот класс реализует интерфейсIntentService
. Он также выполняет обновление маркера FCM и регистрацию в центре уведомлений.Используйте для этого класса следующий код:
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.tasks.OnSuccessListener; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.InstanceIdResult; import com.microsoft.windowsazure.messaging.NotificationHub; import java.util.concurrent.TimeUnit; public class RegistrationIntentService extends IntentService { private static final String TAG = "RegIntentService"; String FCM_token = null; private NotificationHub hub; public RegistrationIntentService() { super(TAG); } @Override protected void onHandleIntent(Intent intent) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); String resultString = null; String regID = null; String storedToken = null; 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); // 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.d(TAG, "Attempting a new registration with NH using FCM token : " + FCM_token); regID = hub.register(FCM_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 = "New NH Registration Successfully - RegId : " + regID; Log.d(TAG, resultString); sharedPreferences.edit().putString("registrationID", regID ).apply(); sharedPreferences.edit().putString("FCMtoken", FCM_token ).apply(); } // Check to see if the token has been compromised and needs refreshing. else if (!(storedToken = sharedPreferences.getString("FCMtoken", "")).equals(FCM_token)) { NotificationHub hub = new NotificationHub(NotificationSettings.HubName, NotificationSettings.HubListenConnectionString, this); Log.d(TAG, "NH Registration refreshing with token : " + FCM_token); regID = hub.register(FCM_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 = "New NH Registration Successfully - RegId : " + regID; Log.d(TAG, resultString); sharedPreferences.edit().putString("registrationID", regID ).apply(); sharedPreferences.edit().putString("FCMtoken", FCM_token ).apply(); } else { resultString = "Previously Registered Successfully - RegId : " + regID; } } catch (Exception e) { Log.e(TAG, resultString="Failed to complete registration", e); // If an exception happens while fetching the new token or updating 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); } } }
В классе
MainActivity
добавьте следующие операторыimport
выше объявления класса.import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; import android.content.Intent; import android.util.Log; import android.widget.TextView; import android.widget.Toast;
Добавьте следующие элементы в верхней части класса. Используйте эти поля для проверки доступности служб Google Play в соответствии с рекомендациями Google.
public static MainActivity mainActivity; public static Boolean isVisible = false; private static final String TAG = "MainActivity"; private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
В классе
MainActivity
добавьте следующий метод проверки доступности сервисов Google Play./** * Check the device to make sure it has the Google Play Services APK. If * it doesn't, display a dialog box that enables 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; }
В классе
MainActivity
добавьте следующий код, который проверяет сервисы Google Play, прежде чем вызыватьIntentService
. Таким образом вы получите маркер регистрации в FCM и выполните регистрацию в своем центре.public void registerWithNotificationHubs() { if (checkPlayServices()) { // Start IntentService to register this application with FCM. Intent intent = new Intent(this, RegistrationIntentService.class); startService(intent); } }
В методе
OnCreate
классаMainActivity
добавьте следующий код, чтобы начать регистрацию при создании действия.@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mainActivity = this; registerWithNotificationHubs(); FirebaseService.createChannelAndHandleNotifications(getApplicationContext()); }
Добавьте эти дополнительные методы в класс
MainActivity
, чтобы проверять состояние приложения и отображать в нем полученные данные.@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); } }); }
Метод
ToastNotify
использует элемент управленияTextView
Hello World, чтобы постоянно передавать в приложение сведения о состоянии и уведомления. В файле макета res>layout>activity_main.xml добавьте следующий идентификатор для этого элемента управления.android:id="@+id/text_hello"
Затем добавьте подкласс для получателя, определенного в AndroidManifest.xml. Добавьте еще один новый класс в проект
FirebaseService
.Добавьте в начало файла
FirebaseService.java
следующие операторы импорта:import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; import android.util.Log; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.media.RingtoneManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; import androidx.core.app.NotificationCompat;
Добавьте в класс
FirebaseService
следующий код, чтобы сделать его подклассом классаFirebaseMessagingService
.Этот код переопределяет метод
onMessageReceived
и сообщает о полученных уведомлениях. Кроме того, он отправляет push-уведомление в диспетчер уведомлений Android с помощью методаsendNotification()
. Вызовите методsendNotification()
, если получено уведомление, а приложение не запущено.public class FirebaseService extends FirebaseMessagingService { private String TAG = "FirebaseService"; public static final String NOTIFICATION_CHANNEL_ID = "nh-demo-channel-id"; public static final String NOTIFICATION_CHANNEL_NAME = "Notification Hubs Demo Channel"; public static final String NOTIFICATION_CHANNEL_DESCRIPTION = "Notification Hubs Demo Channel"; public static final int NOTIFICATION_ID = 1; private NotificationManager mNotificationManager; NotificationCompat.Builder builder; static Context ctx; @Override public void onMessageReceived(RemoteMessage remoteMessage) { // ... // TODO(developer): Handle FCM messages here. // Not getting messages here? See why this may be: https://goo.gl/39bRNJ Log.d(TAG, "From: " + remoteMessage.getFrom()); String nhMessage; // Check if message contains a notification payload. if (remoteMessage.getNotification() != null) { Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody()); nhMessage = remoteMessage.getNotification().getBody(); } else { nhMessage = remoteMessage.getData().values().iterator().next(); } // Also if you intend on generating your own notifications as a result of a received FCM // message, here is where that should be initiated. See sendNotification method below. if (MainActivity.isVisible) { MainActivity.mainActivity.ToastNotify(nhMessage); } sendNotification(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 notificationBuilder = new NotificationCompat.Builder( ctx, NOTIFICATION_CHANNEL_ID) .setContentText(msg) .setPriority(NotificationCompat.PRIORITY_HIGH) .setSmallIcon(android.R.drawable.ic_popup_reminder) .setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL); notificationBuilder.setContentIntent(contentIntent); mNotificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); } public static void createChannelAndHandleNotifications(Context context) { ctx = context; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel( NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH); channel.setDescription(NOTIFICATION_CHANNEL_DESCRIPTION); channel.setShowBadge(true); NotificationManager notificationManager = context.getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } } }
В Android Studio в строке меню выберите Build>Rebuild Project (Сборка > Пересобрать проект) чтобы убедиться, что в вашем коде нет ошибок. Если появляется сообщение об ошибке о значке
ic_launcher
, удалите следующую инструкцию из файла AndroidManifest.xml.android:icon="@mipmap/ic_launcher"
Убедитесь, что у вас есть виртуальное устройство для запуска приложения. Если его нет, добавьте его следующим образом:
Запустите приложение на выбранном устройстве и убедитесь, что оно успешно зарегистрировано в концентраторе.
Примечание.
Во время первоначального запуска регистрация может завершиться неудачно, пока не будет вызван метод
onTokenRefresh()
службы ИД экземпляра. Чтобы заново начать регистрацию в центре уведомлений, обновите страницу.
Проверка отправки уведомления из центра уведомлений
Push-уведомления с портала Azure можно отправить, выполнив следующие действия.
На портале Azure на странице "Цента уведомлений" для своего центра выберите Тестовая отправка в разделе Устранение неполадок.
В качестве платформы выберите Android.
Выберите Отправить. Вы пока не увидите уведомление на устройстве Android, потому что на нем еще не запущено мобильное приложение. После запуска мобильного приложения нажмите еще раз кнопку Send (Отправить), чтобы просмотреть уведомление.
Результат операции можно увидеть в списке внизу.
Вы увидите сообщение уведомления на своем устройстве.
Push-уведомления обычно отправляются во внутренней службе, например мобильных приложениях или службе ASP.NET, с помощью совместимой библиотеки. Если для серверной части библиотека недоступна, для отправки уведомлений также можно напрямую использовать REST API.
Ниже приведен список других учебников, касающихся отправки уведомлений:
- Мобильные приложения Azure. Пример отправки уведомлений из серверной части мобильных приложений, интегрированных с Центрами уведомлений, см. в статье "Добавление push-уведомлений" в приложение iOS.
- ASP.NET: Использование центров уведомлений для отправки push-уведомлений пользователям.
- Пакет SDK для Центров уведомлений Azure для Java: сведения об отправке уведомлений Java см. в статье Использование концентраторов уведомлений из Java. Было протестировано в Eclipse для разработки для Android.
- PHP: Использование Центров уведомлений из PHP.
Запуск мобильного приложения в эмуляторе
Перед проверкой отправки push-уведомлений в эмуляторе, убедитесь, что образ эмулятора поддерживает уровень API Google, выбранный для приложения. Если образ не поддерживает собственные API-интерфейсы Google, создается исключение SERVICE_NOT_AVAILABLE.
Кроме того, добавьте учетную запись Google в запущенный эмулятор. Для этого щелкните Settings (Параметры)>Accounts (Учетные записи). В противном случае попытки регистрации в FCM могут привести к исключению AUTHENTICATION_FAILED.
Следующие шаги
В этом руководстве вы использовали Firebase Cloud Messaging, для отправки уведомлений на все устройства Android, зарегистрированных в службе. Чтобы узнать, как отправлять push-уведомления на конкретные устройства, перейдите к следующему руководству: