如何在Android上用react-native-push-notification获取所有通知(等效iOS的getDeliveredNotifications)
在Android上实现类似iOS的getDeliveredNotifications功能(基于react-native-push-notification)
嘿,刚好我对这个库的Android端实现挺熟悉的,给你一步步拆解怎么实现和iOS getDeliveredNotifications 相同的效果——也就是获取状态栏里所有已送达的推送通知:
方法一:自定义原生模块(最准确的方案)
遗憾的是这个库本身并没有直接提供对应Android的API,所以我们需要手写一点原生代码来封装Android系统的通知查询能力,步骤很清晰:
1. 创建Android原生模块文件
在你的RN项目的android/app/src/main/java/com/[你的项目包名]/路径下,新建一个名为NotificationHelperModule.java的文件,代码如下:
package com.yourappname; // 替换成你自己的项目包名 import android.app.Notification; import android.os.Build; import androidx.core.app.NotificationManagerCompat; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; import com.facebook.react.bridge.Promise; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; public class NotificationHelperModule extends ReactContextBaseJavaModule { private final ReactApplicationContext reactContext; public NotificationHelperModule(ReactApplicationContext reactContext) { super(reactContext); this.reactContext = reactContext; } @Override public String getName() { return "NotificationHelper"; // 这个名字是RN端调用时的模块名 } @ReactMethod public void getDeliveredNotifications(Promise promise) { try { NotificationManagerCompat notificationManager = NotificationManagerCompat.from(reactContext); ArrayList<Object> notificationList = new ArrayList<>(); // Android 6.0及以上才能调用getActiveNotifications if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { for (var sbn : notificationManager.getActiveNotifications()) { Notification notification = sbn.getNotification(); // 提取你需要的通知字段,比如标题、内容、自定义payload Map<String, Object> notificationData = new HashMap<>(); notificationData.put("title", notification.extras.getString(Notification.EXTRA_TITLE)); notificationData.put("body", notification.extras.getString(Notification.EXTRA_TEXT)); // 这里的"payload"是你推送时自定义的字段,根据实际情况调整 notificationData.put("payload", notification.extras.getString("payload")); notificationList.add(notificationData); } } promise.resolve(notificationList); } catch (Exception e) { promise.reject("FETCH_NOTIFICATIONS_ERROR", e.getMessage()); } } }
2. 注册这个原生模块
同样在上述路径下新建NotificationHelperPackage.java:
package com.yourappname; // 替换成你自己的项目包名 import com.facebook.react.ReactPackage; import com.facebook.react.bridge.NativeModule; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.uimanager.ViewManager; import java.util.ArrayList; import java.util.List; public class NotificationHelperPackage implements ReactPackage { @Override public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { List<NativeModule> modules = new ArrayList<>(); modules.add(new NotificationHelperModule(reactContext)); return modules; } @Override public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { return new ArrayList<>(); } }
3. 在MainApplication中添加Package
打开android/app/src/main/java/com/[你的项目包名]/MainApplication.java,找到getPackages()方法,把我们的Package加进去:
@Override protected List<ReactPackage> getPackages() { List<ReactPackage> packages = new PackageList(this).getPackages(); // 新增这一行 packages.add(new NotificationHelperPackage()); return packages; }
4. 在RN代码中调用
现在就可以在JS里像调用iOS的API一样使用了:
import { NativeModules } from 'react-native'; const { NotificationHelper } = NativeModules; // 获取已送达通知的异步函数 const getDeliveredNotifications = async () => { try { const notifications = await NotificationHelper.getDeliveredNotifications(); console.log('状态栏中的已送达通知:', notifications); // 这里可以和处理iOS返回的通知数组逻辑保持一致 } catch (error) { console.error('获取通知失败:', error); } };
方法二:本地存储替代方案(无需原生代码)
如果觉得写原生代码麻烦,还有个更简单的思路:在收到推送的时候(也就是onNotification回调触发时),把通知数据保存到RN的本地存储(比如AsyncStorage、MMKV或者Realm)。之后需要获取已送达通知时,直接从本地存储读取即可。
示例代码:
import PushNotification from 'react-native-push-notification'; import AsyncStorage from '@react-native-async-storage/async-storage'; // 初始化推送监听 PushNotification.configure({ onNotification: async (notification) => { // 收到通知时,保存到本地存储 try { const existingNotifications = await AsyncStorage.getItem('deliveredNotifications'); const notificationsArray = existingNotifications ? JSON.parse(existingNotifications) : []; // 避免重复添加,可以根据通知id做判断 const isDuplicate = notificationsArray.some(n => n.id === notification.id); if (!isDuplicate) { notificationsArray.push(notification); await AsyncStorage.setItem('deliveredNotifications', JSON.stringify(notificationsArray)); } } catch (error) { console.error('保存通知失败:', error); } }, // 其他配置项... }); // 获取已保存的通知 const fetchSavedNotifications = async () => { try { const notifications = await AsyncStorage.getItem('deliveredNotifications'); return notifications ? JSON.parse(notifications) : []; } catch (error) { console.error('读取通知失败:', error); return []; } };
注意点
- 原生模块方案只能获取Android 6.0(API 23)及以上系统的状态栏通知,低版本系统无法支持,这种情况建议用本地存储方案。
- 远程推送的payload不会被Android系统自动保存,所以如果用原生模块方案,需要确保推送时把自定义数据放到通知的
extras里,这样才能在原生代码中提取到。
内容的提问来源于stack exchange,提问作者kc2




