← Назад к вопросам

Как получить push-уведомления от сервера если приложение выгружено из памяти?

2.0 Middle🔥 242 комментариев
#Android компоненты#Жизненный цикл и навигация#Сетевое взаимодействие

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Механизмы получения Push-уведомлений в выгруженном приложении

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

Основные компоненты системы

  1. Google Play Services - поддерживает постоянное соединение с серверами Google
  2. FCM Transport Layer - канал для доставки сообщений
  3. System Broadcasts - механизм пробуждения устройства и приложения

Как работает процесс доставки

// Пример манифеста с приемником уведомлений
<manifest>
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    
    <application>
        <!-- Сервис для работы с FCM -->
        <service
            android:name=".MyFirebaseMessagingService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

        <!-- Приемник для пробуждения устройства -->
        <receiver
            android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver"
            android:exported="true"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

Типы сообщений FCM

Существует два основных типа сообщений:

  • Notification Messages - обрабатываются автоматически системой
  • Data Messages - требуют обработки в вашем приложении
// Notification Message (автоматическая обработка)
{
  "notification": {
    "title": "Новое сообщение",
    "body": "У вас новое уведомление",
    "icon": "ic_notification"
  },
  "to": "device_token"
}

// Data Message (требует обработки в приложении)
{
  "data": {
    "type": "new_message",
    "sender_id": "12345",
    "message": "Текст сообщения"
  },
  "to": "device_token"
}

Жизненный цикл доставки уведомления

  1. Сервер отправляет сообщение на FCM-серверы Google
  2. Google Play Services получает сообщение через постоянное соединение
  3. Система Android проверяет тип сообщения:
    • Для Notification Messages: показывает уведомление немедленно
    • Для Data Messages: запускает ваше приложение в фоне
  4. Приложение получает управление через FirebaseMessagingService
class MyFirebaseMessagingService : FirebaseMessagingService() {
    
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        // Обработка Data Messages
        remoteMessage.data?.let { data ->
            val type = data["type"]
            val message = data["message"]
            showNotification(type, message)
        }
        
        // Notification Messages обрабатываются автоматически,
        // но можно переопределить поведение
        remoteMessage.notification?.let { notification ->
            // Дополнительная обработка
        }
    }
    
    override fun onNewToken(token: String) {
        // Обновление токена на сервере
        sendTokenToServer(token)
    }
    
    private fun showNotification(type: String?, message: String?) {
        // Создание канала (для Android 8.0+)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                "messages",
                "Сообщения",
                NotificationManager.IMPORTANCE_HIGH
            )
            getSystemService(NotificationManager::class.java)
                .createNotificationChannel(channel)
        }
        
        // Построение уведомления
        val notification = NotificationCompat.Builder(this, "messages")
            .setContentTitle("Новое сообщение")
            .setContentText(message)
            .setSmallIcon(R.drawable.ic_notification)
            .setAutoCancel(true)
            .build()
        
        NotificationManagerCompat.from(this)
            .notify(Random.nextInt(), notification)
    }
}

Критические аспекты реализации

Приоритет сообщений:

  • high - немедленная доставка, пробуждение устройства
  • normal - доставка при следующем подключении

Фоновые ограничения:

  • Начиная с Android 8.0 (API 26) ограничены фоновые службы
  • Необходимо использовать JobScheduler или WorkManager для длительных задач

Оптимизация для разных версий Android:

  • Для Android 12+ требуется явное разрешение на точные уведомления
  • Adaptive icons для уведомлений
  • Правильная настройка каналов уведомлений

Альтернативные подходы

Для сценариев, где FCM недоступен (например, в Китае), используются:

  1. Собственные WebSocket-соединения с foreground service
  2. Системные AlarmManager для периодических опросов
  3. WorkManager с периодическими задачами

Рекомендации по надежности

  • Всегда реализуйте onNewToken() для обновления токена
  • Используйте data messages для критически важных уведомлений
  • Тестируйте сценарии с выгруженным приложением на реальных устройствах
  • Реализуйте механизм повторной отправки уведомлений при сбоях

Этот механизм обеспечивает надежную доставку push-уведомлений даже при полностью выгруженном приложении, используя системные возможности Android и инфраструктуру Google.

Как получить push-уведомления от сервера если приложение выгружено из памяти? | PrepBro