React Native应用关闭时onNotification方法未触发问题求助
解决react-native-push-notification应用关闭时onNotification不触发的问题
问题概述
使用react-native-push-notification时,应用在前台/后台状态下onNotification回调正常触发,但完全关闭应用后回调无法执行。尝试替换<category android:name="android.intent.category.DEFAULT" />为<category android:name="android.intent.category.INFO" />后问题仍未解决,原AndroidManifest.xml配置如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.appname"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/logo" android:roundIcon="@mipmap/logo_round" android:allowBackup="false" android:usesCleartextTraffic="false" android:theme="@style/AppTheme" android:networkSecurityConfig="@xml/network_security_config"> <activity android:name=".SplashActivity" android:theme="@style/SplashTheme" android:label="@string/app_name" android:screenOrientation="portrait" android:exported="false"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:screenOrientation="portrait" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.INFO" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="appname" /> </intent-filter> </activity> <meta-data android:name="com.dieam.reactnativepushnotification.default_notification_channel_id" android:value="@string/default_notification_channel_id" /> <!-- Change the value to true to enable pop-up for in foreground on receiving remote notifications (for prevent duplicating while showing local notifications set this to false) --> <meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground" android:value="true"/> <!-- Change the resource name to your App's accent color - or any other color you want --> <meta-data android:name="com.dieam.reactnativepushnotification.notification_color" android:resource="@color/white"/> <!-- or @android:color/{name} to use a standard color --> <!-- Notification icon --> <meta-data android:name = "com.dieam.reactnativepushnotification.notification_icon" android:resource="@mipmap/ic_launcher" /> <meta-data android:name = "com.google.firebase.messaging.default_notification_icon" android:resource="@mipmap/ic_launcher" /> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" /> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" /> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver" android:exported="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.QUICKBOOT_POWERON" /> <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/> </intent-filter> </receiver> <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> </application> </manifest>
核心原因与修复方案
1. 推送Payload必须包含data字段
Android系统对推送消息的处理逻辑:
- 仅使用
notification字段:应用关闭时,系统直接展示通知,不会将消息传递给应用回调。 - 包含
data字段:无论应用状态如何,消息都会被RNPushNotificationListenerService接收,进而触发onNotification回调。
正确Payload示例:
{ "to": "YOUR_DEVICE_FCM_TOKEN", "data": { "title": "新通知", "message": "这是一条测试消息", "screen": "NotificationDetail", "id": "123" } }
2. 修改AndroidManifest.xml配置
调整监听服务属性,确保应用关闭后服务仍能运行并唤醒应用:
- 在
RNPushNotificationListenerService中添加android:stopWithTask="false",防止应用关闭时服务被终止:
<service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService" android:exported="false" android:stopWithTask="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
- 将MainActivity的主intent-filter改回
<category android:name="android.intent.category.DEFAULT" />,保证应用被唤醒时能正确启动:
<activity android:name=".MainActivity" ...> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
3. 确认通知渠道已创建
Android 8.0+要求必须创建通知渠道才能显示通知,应用初始化时调用以下代码创建默认渠道:
import PushNotification from 'react-native-push-notification'; PushNotification.createChannel( { channelId: 'default_notification_channel_id', // 与Manifest中的meta-data值一致 channelName: '默认通知渠道', channelDescription: '用于显示所有通知的渠道', importance: 4, vibrate: true, }, (created) => console.log(`渠道创建结果:${created}`) );
4. 测试注意事项
- 使用真实设备测试,部分模拟器对应用关闭后的推送支持不佳。
- 确保应用是完全关闭(从最近任务列表划掉),而非后台运行。
修改后的完整AndroidManifest.xml示例
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.appname"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/logo" android:roundIcon="@mipmap/logo_round" android:allowBackup="false" android:usesCleartextTraffic="false" android:theme="@style/AppTheme" android:networkSecurityConfig="@xml/network_security_config"> <activity android:name=".SplashActivity" android:theme="@style/SplashTheme" android:label="@string/app_name" android:screenOrientation="portrait" android:exported="false"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:screenOrientation="portrait" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="appname" /> </intent-filter> </activity> <meta-data android:name="com.dieam.reactnativepushnotification.default_notification_channel_id" android:value="@string/default_notification_channel_id" /> <meta-data android:name="com.dieam.reactnativepushnotification.notification_foreground" android:value="true"/> <meta-data android:name="com.dieam.reactnativepushnotification.notification_color" android:resource="@color/white"/> <meta-data android:name = "com.dieam.reactnativepushnotification.notification_icon" android:resource="@mipmap/ic_launcher" /> <meta-data android:name = "com.google.firebase.messaging.default_notification_icon" android:resource="@mipmap/ic_launcher" /> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationActions" /> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" /> <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver" android:exported="false"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <action android:name="android.intent.action.QUICKBOOT_POWERON" /> <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/> </intent-filter> </receiver> <service android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService" android:exported="false" android:stopWithTask="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> </application> </manifest>
内容的提问来源于stack exchange,提问作者Satinderpal Singh
相关产品推荐
相关产品推荐

