You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用启动时获取未运行期间远程通知问题求助

解决Android启动时收集未运行期间远程通知的问题

我之前也碰到过类似的困扰,用getActiveNotifications拿不到FCM远程通知的实际内容,主要有几个核心原因和可行的解决思路,给你详细说下:

1. 为什么当前代码看不到通知内容?

你打印的notification.toString()里contentView=null,是因为FCM的远程通知内容并不直接通过Notification对象的toString方法暴露,而是存在它的extras(Bundle) 里。另外,getActiveNotifications只能获取当前显示在状态栏的通知——如果用户已经手动清除了通知,这个方法就拿不到任何数据了,这是很大的局限性。

2. 先试试读取Notification的Extras获取内容

修改你的代码,直接读取Notification的extras,FCM的通知标题、内容通常存在标准的key里,比如Notification.EXTRA_TITLE和Notification.EXTRA_TEXT:

NotificationManager notificationManager = (NotificationManager) cordova.getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
StatusBarNotification[] notifications = notificationManager.getActiveNotifications();
for (StatusBarNotification sbn : notifications) {
    Notification notification = sbn.getNotification();
    Bundle extras = notification.extras;
    
    // 获取标准通知内容
    String title = extras.getString(Notification.EXTRA_TITLE);
    String content = extras.getString(Notification.EXTRA_TEXT);
    // 如果是带多行内容的通知,用EXTRA_BIG_TEXT
    String bigContent = extras.getString(Notification.EXTRA_BIG_TEXT);
    
    // 打印看看
    Log.d("Tag", "通知标题:" + title + ",内容:" + content + ",长内容:" + bigContent);
    // 也可以打印所有extras,排查有没有自定义数据
    Log.d("Tag", "所有Extras:" + extras.toString());
}

3. 更可靠的方案:在消息接收时缓存(推荐)

依赖读取状态栏通知的方式太不稳定(用户随时可能清除),更靠谱的做法是在FCM消息到达时就把内容缓存到本地(比如SharedPreferences、Room数据库),不管应用是否运行:

步骤1:创建自定义FirebaseMessagingService

继承FirebaseMessagingService,重写onMessageReceived方法,在这里捕获所有FCM消息并保存:

public class MyFCMService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        
        // 处理FCM通知消息(系统会自动显示通知的那种)
        if (remoteMessage.getNotification() != null) {
            String title = remoteMessage.getNotification().getTitle();
            String body = remoteMessage.getNotification().getBody();
            // 保存到本地
            saveNotification(title, body, remoteMessage.getData());
        }
        
        // 处理FCM数据消息(不会自动显示通知,完全由开发者处理)
        if (!remoteMessage.getData().isEmpty()) {
            Map<String, String> data = remoteMessage.getData();
            saveDataMessage(data);
        }
    }
    
    // 保存通知到SharedPreferences(示例,也可以用Room存更复杂的结构)
    private void saveNotification(String title, String body, Map<String, String> data) {
        SharedPreferences sp = getSharedPreferences("AppNotifications", MODE_PRIVATE);
        Set<String> savedNotifications = sp.getStringSet("notifications", new HashSet<>());
        String notificationStr = String.format("[%s] 标题:%s,内容:%s,附加数据:%s",
                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()),
                title, body, data.toString());
        savedNotifications.add(notificationStr);
        sp.edit().putStringSet("notifications", savedNotifications).apply();
    }
    
    private void saveDataMessage(Map<String, String> data) {
        // 类似上面的保存逻辑,根据你的需求处理
    }
}

步骤2:在AndroidManifest中注册服务

<service
    android:name=".MyFCMService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

步骤3:启动时读取缓存的通知

当应用启动时,直接从本地缓存读取所有保存的通知即可,不用依赖状态栏:

SharedPreferences sp = cordova.getActivity().getSharedPreferences("AppNotifications", Context.MODE_PRIVATE);
Set<String> savedNotifications = sp.getStringSet("notifications", new HashSet<>());
for (String note : savedNotifications) {
    Log.d("Tag", "缓存的通知:" + note);
}

4. 额外注意事项

  • Android 13+权限:需要动态申请POST_NOTIFICATIONS权限,否则无法接收和显示FCM通知。
  • 应用被彻底杀死的情况:如果用户在任务管理器彻底划掉应用,FCM的通知消息会由系统直接显示,不会触发onMessageReceived。这种情况下,你还是可以结合getActiveNotifications读取当前状态栏的通知,再和本地缓存合并,但还是无法避免用户清除通知的问题。

内容的提问来源于stack exchange,提问作者rahul.mahajan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 17:22:38