Android应用完全关闭时如何正常接收服务端推送的通知?
Android应用完全关闭后无法接收Node.js服务端推送通知的解决方案
核心原因
Android 6.0之后系统逐步收紧了后台进程权限,应用被用户完全关闭后,所有自定义的后台服务、长连接都会被系统强制回收,除非走系统级别的推送通道,否则无法触达。
解决方案
1. 优先使用系统级推送通道(最优方案,适配成本低、送达率最高)
- 海外应用场景:直接接入FCM(Firebase云消息服务)
FCM依赖Google Play服务,属于系统级保活进程,应用被杀后也能正常接收通知。Node.js服务端可以直接使用官方提供的firebase-adminnpm包调用推送接口,示例代码如下:const admin = require('firebase-admin'); // 初始化firebase admin,需要提前在Firebase控制台下载服务账号密钥 admin.initializeApp({ credential: admin.credential.cert(require('./service-account-key.json')), }); // 发送通知类消息 const pushMsg = { notification: { title: "通知标题", body: "通知具体内容" }, token: "目标Android设备的FCM注册令牌" }; admin.messaging().send(pushMsg) .then(res => console.log("推送成功", res)) .catch(err => console.error("推送失败", err)); - 国内应用场景:必须接入各手机厂商的系统推送通道
国内安卓设备默认没有Google服务,需要分别接入小米、华为、OPPO、vivo、荣耀等厂商的官方推送服务,这些通道都是厂商系统内置进程保活,应用被杀后也能正常展示通知。Node.js服务端只需对接对应厂商的服务端推送API即可,也可以选择集成第三方推送聚合服务降低适配成本。
2. 客户端侧必要配置校验
- Android 8.0及以上版本必须提前创建通知渠道,否则就算收到推送也无法正常展示,Kotlin实现示例如下:
// 应用启动时初始化通知渠道 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channelId = "your_notify_channel_id" val channelName = "消息通知" val importance = NotificationManager.IMPORTANCE_HIGH val channel = NotificationChannel(channelId, channelName, importance).apply { description = "用于接收应用推送的通知渠道" } val notifyManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notifyManager.createNotificationChannel(channel) } // 收到推送后展示通知的逻辑 val notification = NotificationCompat.Builder(context, "your_notify_channel_id") .setSmallIcon(R.drawable.ic_app_notify) .setContentTitle(notifyTitle) .setContentText(notifyContent) .setPriority(NotificationCompat.PRIORITY_HIGH) .setAutoCancel(true) .build() NotificationManagerCompat.from(context).notify(Random.nextInt(), notification) - 注意区分通知消息和透传消息:走系统通道时,通知类型的消息会由系统直接展示,不需要应用启动;透传消息需要应用存活时才能收到回调自行处理,应用关闭场景下不要依赖透传消息展示通知。
3. 自定义长连接方案(不推荐,适配成本极高、送达率无保障)
如果业务场景必须使用自有Node.js服务端和客户端的长连接推送,需做额外保活配置,但Android 12及以上版本对保活限制极严,仅可作为辅助方案:
- 申请前台服务权限,启动常驻前台通知保活长连接服务
- 引导用户手动将应用加入系统电池优化白名单,避免被系统后台查杀
- 配置广播接收器,监听系统开机、应用更新、网络切换等系统广播,尝试拉起长连接服务
内容的提问来源于stack exchange,提问作者Peace TheeCoder
相关产品推荐
相关产品推荐

