You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在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的本地存储(比如AsyncStorageMMKV或者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

火山引擎 最新活动