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
相关产品推荐
相关产品推荐

