General update - integrated dozo mode finding , power saving mode finding in native android side for sending loss less FCM notification to the device

#native#android

Answer

Overview

Doze Mode and Power Saving Mode are Android OS features that restrict background processing to save battery. When active, they can silently drop FCM (Firebase Cloud Messaging) notifications or delay them significantly — causing lossy notifications.


What is Doze Mode?

Introduced in Android 6.0 (API 23). When the device is idle, unplugged, and the screen is off for a long time, Android enters Doze mode and:

  • Defers all network access
  • Suspends background sync
  • Delays alarms and jobs
  • FCM low-priority messages are blocked

What is Power Saving Mode?

A user-toggleable mode that aggressively restricts background activity:

  • CPU speed throttled
  • Background processes killed
  • Network access for background apps limited
  • App-specific battery optimization can block FCM entirely

Detecting Doze Mode (Native Android)

kotlin
// Kotlin — detect if device is in Doze mode
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager

val isInDozeMode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    powerManager.isDeviceIdleMode
} else {
    false
}

// Detect if your app is battery optimized (excluded from doze whitelist)
val isIgnoringBatteryOptimizations =
    powerManager.isIgnoringBatteryOptimizations(packageName)

Log.d("PowerMode", "Doze: $isInDozeMode, BatteryOptimized: $!isIgnoringBatteryOptimizations")

Detecting Power Saving Mode (Native Android)

kotlin
val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager

val isPowerSaveMode = powerManager.isPowerSaveMode

Log.d("PowerMode", "Power Save Mode: $isPowerSaveMode")

Sending Lossless FCM Notifications

To ensure FCM notifications are delivered even in Doze/Power Saving mode, use high-priority FCM messages:

FCM Payload (High Priority)

json
{
  "message": {
    "token": "device_fcm_token",
    "android": {
      "priority": "HIGH"
    },
    "apns": {
      "headers": {
        "apns-priority": "10"
      }
    },
    "notification": {
      "title": "Urgent Alert",
      "body": "You have a new message"
    }
  }
}

text
priority: HIGH
causes Android to temporarily exit Doze mode and deliver the message immediately.


Request Battery Optimization Exemption

kotlin
// Request user to whitelist your app from battery optimization
val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
    data = Uri.parse("package:$packageName")
}
startActivity(intent)

Flutter Side (via flutter_local_notifications)

dart
// Ensure notifications show even in Doze
await flutterLocalNotificationsPlugin.show(
  0,
  'Urgent Alert',
  'Message received',
  NotificationDetails(
    android: AndroidNotificationDetails(
      'urgent_channel',
      'Urgent Notifications',
      importance: Importance.max,  // ← High importance bypasses Doze
      priority: Priority.high,
    ),
  ),
);

Best Practice: Always use

text
priority: HIGH
in your FCM server payload for time-sensitive notifications. Request battery optimization exemption for apps that rely on real-time alerts (like messaging or alarm apps).