Android平台实现可靠即时推送通知的解决方案探讨
问题:FCM数据消息在设备深度睡眠时延迟,如何实现全设备即时接收?
现状说明
- 应用依赖Firebase Cloud Messaging(FCM)接收服务器通知,当前部分通知因设备深度睡眠出现严重延迟
- 使用Data Messages(非Notifications类型消息),发送时已设置优先级为
high - 开发了测试可靠推送的开源应用,夜间推送接收测试结果如下:

当前实现代码
FcmService 代码
class FcmService : FirebaseMessagingService() { override fun onNewToken(token: String) { super.onNewToken(token) Timber.tag(TAG).d("Firebase token:$token") } override fun onMessageReceived(message: RemoteMessage) { super.onMessageReceived(message) val data = message.data val reliableId = data["reliableId"] val time = reliableId!!.toLong().formatTime() Timber.tag(TAG).i("========= Received a push (id $reliableId, type ${data["type"]} time $time priority ${message.priority})") if (data.getBool("network", true)){ networkOperation() } }
AndroidManifest.xml 配置
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.INTERNET" /> <application android:name=".MyApplication" android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/Theme.ReliableFCM" tools:targetApi="31"> <service android:name=".FcmService" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <activity android:name=".MainActivity" android:exported="true" android:theme="@style/Theme.ReliableFCM"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
核心疑问
有没有办法让所有用户(无论Android版本、设备型号)都能在服务器发送通知的同时,即时接收到FCM数据消息?
解决方案
要最大化降低FCM数据消息的延迟,需针对Android系统及厂商后台限制做针对性处理,以下是关键措施:
1. 适配Android 8.0+后台限制
- 启用前台服务:Android 8.0+对后台服务有严格管控,在
onMessageReceived中启动前台服务,可避免消息处理进程被系统杀死,确保即时处理:
同时在Manifest中声明权限:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { startForegroundService(Intent(this, YourForegroundService::class.java)) } else { startService(Intent(this, YourForegroundService::class.java)) }<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
2. 绕过厂商省电策略
国内主流厂商(小米、华为、OPPO等)有自定义省电机制,会限制后台应用的网络和进程,需引导用户操作:
- 申请忽略电池优化权限:
代码中触发权限申请:<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) intent.data = Uri.parse("package:$packageName") startActivity(intent) } - 引导添加至厂商白名单:在应用设置页提供跳转入口,引导用户将应用加入厂商的“自启动白名单”“受保护应用”列表,比如小米的自启动管理、华为的应用启动管理。
3. 优化FCM消息配置
- 确认优先级生效:服务器发送消息时,确保
priority设为high,同时Android端需验证RemoteMessage.priority为HIGH(对应值10)。 - Android 12+使用即时消息类型:添加
message_type: instant字段,系统会优先调度这类消息,降低延迟。
4. 补充消息兜底机制
- 用WorkManager处理非紧急任务:如果部分任务允许短暂延迟,使用WorkManager替代后台线程,确保任务在系统允许的时机执行。
- 定期同步检查:用JobScheduler定期触发服务器同步,作为FCM推送的兜底,避免极端情况下消息丢失。
注意事项
不存在绝对的“全设备即时接收”方案,因不同厂商的限制逻辑差异较大,上述措施仅能最大化降低延迟概率。申请权限时需向用户说明原因,避免违反应用商店审核规则。
内容的提问来源于stack exchange,提问作者Solvek
相关产品推荐
相关产品推荐

