Как создать приложение для Android с push-уведомлениями: пошаговое руководство

Как создать приложение для Android с push-уведомлениями: пошаговое руководство

Зачем и в каких случаях нужны push-уведомления в Android-приложении

Push-уведомления — один из самых эффективных инструментов мобильного вовлечения. В интернет-магазине они информируют о скидке на интересующий товар. В игровом приложении — напоминают про бонус за ежедневный вход. В сервисе доставки — сообщают о приближении курьера. Это упрощённая, но мощная форма обратной связи с пользователем в реальном времени. Уведомления удерживают аудиторию, возвращают пользователей, которые начали уходить, и позволяют мгновенно отреагировать на событие любого типа. Но чрезмерная частота мешает: если push превращается в спам, его отключают или удаляют приложение. Оптимальный подход — отправлять ценные, ожидаемые сообщения, опираясь на контекст.

Какие технологии отвечают за push-уведомления на Android: основные подходы

Базовым стандартом доставки push-уведомлений на Android является Firebase Cloud Messaging (FCM) от Google. Это облачное решение, облегчающее отправку уведомлений как вручную через консоль, так и программно с сервера. FCM требует минимальной конфигурации и глубоко интегрирован в Android API и экосистему Google Play Services.

  • Firebase Cloud Messaging (FCM) — основной выбор для большинства. Бесплатен, стабилен, масштабируем. Используется в 70% Android-приложений с пушами.
  • OneSignal — кроссплатформенный сервис с удобным интерфейсом, идеален для разработки MVP и когда важна аналитика. Ограничения появляются на крупных масштабах.
  • Pusher — больше подходит для real-time взаимодействий, а не нативных push-уведомлений, но может быть полезен в гибридных решениях.
  • Собственный сервер — при необходимости глубокой кастомизации, соблюдения строгих правил хранения данных или специфических триггеров отправки уведомлений.

Если у вас нет собственного сервера и достаточно предустановленного функционала — начинайте с FCM. Он работает “из коробки” и не требует дополнительных библиотек, если работать через консоль Firebase.

Нужен ли сервер:

  1. FCM без сервера: достаточно Firebase Console. Подходит для тестов, маркетинговых уведомлений, MVP.
  2. FCM с сервером: позволяет автоматизировать отправку, использовать триггеры, сегментацию, A/B тесты. Необходим в продакшн-приложениях.

Использование сторонних библиотек может дать быструю настройку, но часто снижает безопасность, ограничивает гибкость и увеличивает зависимость от внешней платформы. Лучше избегать таких решений на серьёзных проектах, особенно если можно реализовать нативно через FCM.

Подготовка среды для создания Android-приложения

Перед добавлением уведомлений нужно развернуть рабочую среду и создать проект. Начните с установки последней стабильной версии Android Studio (на момент написания — Arctic Fox и выше). Вместе с ней установите:

  • Java Development Kit (JDK) — включён в Android Studio.
  • Android SDK — установится при первом запуске, выберите API Level 21 и выше (для поддержки push-уведомлений).

Создайте новый проект в Android Studio:

  1. Выберите шаблон Empty Activity.
  2. Укажите имя пакета (например, com.example.pushdemo).
  3. Выберите минимальный SDK: API 21 (Android 5.0) — поддерживает push и покрывает 95% устройств.

В качестве языка разработки используйте Kotlin — он компактнее, безопаснее, полностью поддерживается Google и считается приоритетным языком для Android. Java приемлема, если уже есть опыт, но для новых проектов предпочтительнее Kotlin.

В build.gradle (Project) и build.gradle (Module) добавьте зависимости для Firebase:

  • classpath 'com.google.gms:google-services:4.3.15' в раздел dependencies проекта
  • apply plugin: 'com.google.gms.google-services' в build.gradle (Module), чтобы активировать Google Services

Подключение выполнено, среда готова — переходим к интеграции Firebase.

Настройка Firebase для отправки push-уведомлений

Firebase связывает облачные сервисы Google с вашим приложением, позволяя отправлять сообщения на устройства. Ниже — последовательность действий для подключения FCM и отправки первого уведомления.

1. Создайте проект в Firebase Console:

  1. Перейдите на console.firebase.google.com.
  2. Нажмите «Добавить проект», укажите имя (например, PushDemo), при необходимости подключите Google Analytics.

2. Добавьте Android-приложение в Firebase-проект:

  1. Выберите иконку Android.
  2. Укажите Package Name — точно такой же, как в Android Studio (com.example.pushdemo).
  3. Добавьте SHA-1: чтобы получить его, используйте команду ./gradlew signingReport в терминале. SHA-1 находится в блоке debug.
  4. После этого скачайте google-services.json — ключевой файл для интеграции с Firebase.

3. Поместите google-services.json в проект:

  • Вставьте файл в папку app/.
  • Убедитесь, что файл корректно синхронизирован (Android Studio может предложить Sync Now — нажмите).

4. Добавьте зависимости в build.gradle (Module: app):

implementation 'com.google.firebase:firebase-messaging:23.0.0'

Эта библиотека отвечает за получение пушей. Вы также можете видеть зависимость firebase-bom — она управляет версиями компонентов Firebase. Для стабильности удобно использовать её:

implementation platform('com.google.firebase:firebase-bom:32.1.1')
implementation 'com.google.firebase:firebase-messaging'

5. Получение токена устройства

Каждое Android-устройство получает уникальный токен Firebase, по которому можно отправить уведомление. Получить токен можно в FirebaseMessaging.getInstance().token:

FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
    if (task.isSuccessful) {
        val token = task.result
        Log.d("FCM", "Token: $token") // Сохраните или отправьте на сервер
    }
}

Нужные разрешения для интернета уже включены по умолчанию. Но убедитесь, что в AndroidManifest.xml присутствует:

<uses-permission android:name="android.permission.INTERNET" />

6. Отправка первого уведомления через Firebase Console

  1. В Firebase Console перейдите в раздел Cloud Messaging.
  2. Нажмите «Отправить сообщение».
  3. Укажите текст, заголовок, выберите целевое приложение.
  4. Можно указать токен устройства, чтобы отправить прямо на ваш девайс.

7. Что должно произойти в приложении

  • Если приложение в фоне — уведомление отобразится в статус-баре автоматически.
  • Если приложение активно — уведомление не появится автоматически. Надо обрабатывать вручную (об этом далее).

Таким образом, базовая настройка завершена — можно отправлять уведомления и видеть результат во встроенной нотификации. Следующий этап — кастомизация, обработка разного поведения и работа с действиями.

Обработка push-уведомлений внутри приложения: что нужно реализовать вручную

По умолчанию push-уведомления в Android приложениях отображаются автоматически, если приложение находится в фоне. Но для полного контроля — кастомного текста, поведения, переходов и аналитики — необходимо вручную обрабатывать входящие сообщения через FirebaseMessagingService.

Реализация FirebaseMessagingService

Создайте новый класс, унаследованный от FirebaseMessagingService. Именно он перехватывает входящие push-сообщения.

class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        // Обработка сообщения
    }

    override fun onNewToken(token: String) {
        Log.d("FCM", "New token: $token")
        // Отправьте токен на сервер, если используете бекенд
    }
}

Не забудьте регистрировать сервис в манифесте:

<service
    android:name=".MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

Отображение уведомлений вручную

Если приложение активно, push не отобразится автоматически. Используйте NotificationCompat для создания уведомления, которое будет показываться пользователю самостоятельно:

private fun showNotification(title: String?, message: String?) {
    val channelId = "push_channel"
    val notificationManager =
        getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val channel = NotificationChannel(
            channelId,
            "Уведомления приложения",
            NotificationManager.IMPORTANCE_HIGH
        )
        notificationManager.createNotificationChannel(channel)
    }

    val notification = NotificationCompat.Builder(this, channelId)
        .setContentTitle(title ?: "Новое сообщение")
        .setContentText(message ?: "")
        .setSmallIcon(R.drawable.ic_notification)
        .setAutoCancel(true)
        .build()

    notificationManager.notify(0, notification)
}

Вызовите showNotification() внутри onMessageReceived, если remoteMessage.notification не отображается автоматом.

Что внутри RemoteMessage?

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    val title = remoteMessage.notification?.title
    val body = remoteMessage.notification?.body
    showNotification(title, body)
}

Обработка включенного и фонового состояния

  • Фоновое состояние: FCM отображает system tray нотификацию автоматически (если данные пришли в notification payload).
  • Приложение активно — foreground: onMessageReceived() вызывается, но notification не показывается. Нужно вручную вызвать отображение через NotificationManager.

Push с only data payload:

Если отправить сообщение только с data (без notification-части), оно всегда будет обрабатываться через onMessageReceived(), в любом состоянии.

Навигация по нажатию на уведомление (routing)

Чтобы при тапе по push пользователь открывал нужный экран приложения, создают PendingIntent с целевым экраном:

val intent = Intent(this, TargetActivity::class.java).apply {
    addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
    putExtra("extra_key", "значение")
}
val pendingIntent = PendingIntent.getActivity(
    this, 0, intent,
    PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE
)

val notification = NotificationCompat.Builder(this, channelId)
    .setContentTitle(title)
    .setContentText(message)
    .setContentIntent(pendingIntent)
    .build()

Данные можно передавать как через intent.putExtra(), так и парсить внутри активности через intent.getStringExtra("key").

Практическая минимальная логика

override fun onMessageReceived(remoteMessage: RemoteMessage) {
    val data = remoteMessage.data
    val title = data["title"]
    val message = data["message"]

    showNotification(title, message)
}

Такой подход контролирует отображение уведомлений, позволяет динамически менять их внешний вид, поведение, и легко масштабируется под будущее расширение функционала.

Советы по UX и частоте отправки push-уведомлений

Push-уведомления — мощный инструмент, но неправильное использование легко превращает его в причину удаления приложения. Главное правило UX при работе с push — отправляйте только то, что действительно имеет ценность для пользователя в конкретный момент.

  • Избегайте частого спама. Если уведомления приходят несколько раз в день без конкретной пользы — пользователь отключит их или удалит приложение. Нормальное значение — 1–2 релевантных уведомления в сутки, не более.
  • Настройки уведомлений внутри приложения. Обязательно дайте пользователю возможность отключать типы push (например, промо-уведомления, новости, системные).
  • Учитывайте режим работы приложения. Нет смысла показывать push, если пользователь и так сейчас на нужном экране. Например, при заказе через приложение — не нужно дублировать push “ваш заказ оформлен”, если пользователь видит экран подтверждения.
  • Сегментация — обязательна. Не всем нужен один и тот же push. Разделите аудиторию по интересам, действиям, истории использования (например, только тем, кто добавил в корзину), и отправляйте адресные уведомления.

Примеры плохих push:

  • «Акция! Только сегодня!». Без уточнений — не релевантно.
  • «Вернитесь в игру!» — что именно ждет?

Примеры хороших push:

  • «Товар в вашей корзине подешевел на 15%. Осталось 3 часа».
  • «Вы не завершили тренировку: продолжить сейчас?»

Чем более персонализированы уведомления, тем выше количество открытий (CTR). Правильно подобранный момент и уместное сообщение могут повысить вовлеченность до 6–8 раз, по сравнению с массовыми пушами.

Организация отправки push-уведомлений с сервера

Чтобы управлять доставкой push-уведомлений в продакшн-приложении, необходимо научиться отправлять их программно — через ваш собственный бекенд или сервер. Это даёт полный контроль: можно назначать расписание, использовать события в базе, сегментировать по действиям и вести аналитику.

1. Сохранение токенов пользователей

Каждое устройство, установившее приложение, получает уникальный токен FCM. Он может меняться при переустановке или очистке данных, поэтому его нужно обновлять при каждом изменении. Рекомендуется отправлять токен на сервер после его получения или обновления:

override fun onNewToken(token: String) {
    sendTokenToServer(token) // Примерная функция отправки
}

На сервере эти токены нужно:

  • Привязывать к аккаунтам пользователя (если доступна авторизация).
  • Обновлять при каждом новом сеансе или запуске приложения.
  • Хранить с метаданными: тип устройства, язык, версия приложения.

2. Отправка push-сообщения вручную через HTTP-запрос

Firebase предоставляет API endpoint:

https://fcm.googleapis.com/fcm/send

Отправка происходит POST-запросом с заголовком Authorization: key=ВАШ_КЛЮЧ_СЕРВЕРА (его можно найти в Firebase Console: «Настройки проекта» → «Общие» → «Серверный ключ»)

Пример JSON-запроса для отправки уведомления на конкретный токен:

{
  "to": "fcm_token_устройства",
  "notification": {
    "title": "🔥 Распродажа началась!",
    "body": "Только 12 часов — скидки до 50%!"
  },
  "data": {
    "screen": "offers",
    "promo_id": "abc123"
  }
}

Этот JSON можно отправить через curl:

curl -X POST -H "Authorization: key=ВАШ_КЛЮЧ" -H "Content-Type: application/json" -d @message.json https://fcm.googleapis.com/fcm/send

3. Безопасность и авторизация

  • Никогда не включайте серверный ключ в клиентское приложение — он должен храниться только на вашем сервере.
  • Ограничьте ключ по IP в Firebase (доступные опции внутри настроек проекта) для ограничения доступа.
  • Используйте HTTPS для всех вызовов API.

4. Дополнительные возможности FCM API

  • Отложенные уведомления (scheduled): не поддерживаются напрямую в FCM, но можно реализовать через cron на сервере или использовать Firebase Functions.
  • Приоритет уведомлений:high — уведомление немедленно доставляется даже в режиме Doze.
  • normal — экономит заряд, может быть отложено.
  • Multilang: храните язык пользователя и формируйте сообщение соответствующим языком на стороне сервера.

5. Когда использовать сторонние сервисы отправки

Для более сложных случаев (регулярное расписание, аналитика открытий, A/B-тесты, автоматические триггеры) удобно использовать сервисы, такие как:

  • Firebase Cloud Functions — отправка уведомлений по событиям БД или аутентификации.
  • OneSignal или Notix — для маркетинговых кампаний, с визуальной статистикой CTR.
  • Segment, Amplitude, Leanplum — совместно с FCM для комплексной аналитики.

Главный плюс отправки с сервера — автоматизация, масштабирование и состояние полной гибкости, особенно если push-сообщения должны реагировать на триггеры: заказ оформлен, клиент кликнул по павербанку и т.д.

Отладка push-уведомлений и типичные ошибки

Правильная интеграция — это 80% успеха, но даже при точной настройке push может не пройти. Ниже типичное поведение и способы устранять сбои.

1. Push не приходит — что проверить:

  • Актуален ли токен? Он может меняться, особенно после переустановки.
  • Приложение зарегистрировано в Firebase? Проверьте google-services.json.
  • Серверный ключ — корректный и не просрочен?
  • Устройство подключено к интернету? VPN, всплывающие DNS-фильтры могут блокировать трафик.
  • Разрешён ли порт 5228–5230? Через них Firebase доставляет сообщения.

2. Проблемы в Gradle или зависимостях

  • Неправильные версии библиотек Firebase могут вызвать конфликты, особенно если используется com.google.firebase:firebase-bom.
  • Убедитесь, что во всех модулях одинаковые версии firebase-компонентов.

3. Отладка через Logcat

  • Фильтруйте по тегу FirebaseMessaging — вы увидите получение token’а, ошибки регистрации, входящие push-сообщения.
  • Добавьте лог в onMessageReceived: Log.d("Push", "Message received: $remoteMessage").

4. Проверка реакции на разные состояния

  • Фон: push должен автоматически появляться как notification.
  • Foreground: только вручную вызывается NotificationManager.
  • Приложение убито: обработка возможна, только если было data-сообщение. При этом нужно тестировать поведение на разных устройствах.

5. Push не приходит в режиме Doze

Android оптимизирует батарею, переходя в режим Doze (неактивное состояние), при котором обычные уведомления задерживаются. Решение:

  • Установить priority: high в JSON-запросе.
  • Использовать data-сообщения вместо notification-типов — они имеют более высокий приоритет доставки.
  • Добавить исключения из энергосбережения вручную (для тестов).

Push-уведомления — тонкий механизм, в котором ошибки чаще носят технический характер: неправильные зависимости, устаревшие токены, конфликты в манифесте. Тестируйте каждое состояние: активное окно, свернутое приложение, выключенный экран, и ведите логирование отправки и получения push на сервере и клиенте.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *