点击FCM通知后应用重启跳转至登录页问题咨询
问题根因
你遇到的问题是FCM消息机制的默认行为导致的:
- FCM控制台默认发送的是通知消息,应用处于后台时不会触发你重写的
onMessageReceived回调,通知由系统直接创建处理 - 系统处理通知点击事件时,默认启动Manifest中声明的
LAUNCHER节点对应的Activity(也就是你的LoginActivity),不会复用应用已有的后台任务栈,所以会直接回到登录页,而非恢复之前的DashboardActivity页面
解决方案
提供两种可选方案,可根据你的使用场景选择:
方案1:保留FCM控制台发通知的习惯,最小改动修复
不需要改现有Service逻辑,只需要两处配置即可:
- FCM控制台发送配置:发通知时找到「其他选项」-「点击操作」,选择「启动应用」,系统会自动复用应用已有的后台任务,不会重新创建LoginActivity
- LoginActivity增加防重逻辑:在
onCreate最前面加如下判断,避免通知点击重复启动登录页:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 已有运行任务栈时,直接结束当前新开的LoginActivity,恢复后台页面 if (!isTaskRoot && intent.action == Intent.ACTION_MAIN && intent.hasCategory(Intent.CATEGORY_LAUNCHER)) { finish() return } // 原有初始化逻辑 }
方案2:全场景自主控制通知逻辑,可控性更高
如果需要自定义点击跳转逻辑、不受FCM控制台限制,可以改用纯数据消息实现,前后台通知都由你自己的代码创建:
- 发送消息时切换为数据消息:FCM控制台发通知时不要填标题、内容字段,只在「自定义数据」里填你要传递的参数(比如key为title、body的字段),此时发送的就是纯数据消息,所有场景都会触发
onMessageReceived回调 - 修改Service代码,手动创建通知:
class FirebasePushNotificationsService : FirebaseMessagingService() { override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) // 前台场景弹Toast if (isAppForeground()) { Handler(Looper.getMainLooper()).post { Toast.makeText( baseContext, remoteMessage.data["body"] ?: "收到新通知", Toast.LENGTH_LONG ).show() } return } // 后台场景手动创建通知 showNotification(remoteMessage.data) } private fun showNotification(data: Map<String, String>) { val channelId = "fcm_notify_channel" // 安卓8.0及以上需创建通知渠道 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( channelId, "消息通知", NotificationManager.IMPORTANCE_DEFAULT ) getSystemService(NotificationManager::class.java).createNotificationChannel(channel) } // 点击通知的意图:和桌面图标启动逻辑一致,恢复现有后台任务 val intent = packageManager.getLaunchIntentForPackage(packageName)?.apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED } val pendingIntent = PendingIntent.getActivity( this, 0, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) // 构建通知 val notification = NotificationCompat.Builder(this, channelId) .setSmallIcon(R.mipmap.ic_launcher) // 替换为你自己的应用图标 .setContentTitle(data["title"] ?: "新通知") .setContentText(data["body"] ?: "") .setContentIntent(pendingIntent) .setAutoCancel(true) .build() // 显示通知 NotificationManagerCompat.from(this).notify(System.currentTimeMillis().toInt(), notification) } // 判断应用是否处于前台 private fun isAppForeground(): Boolean { val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager val appProcesses = activityManager.runningAppProcesses ?: return false for (process in appProcesses) { if (process.processName == packageName && process.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { return true } } return false } }
内容的提问来源于stack exchange,提问作者Ludiras
相关产品推荐
相关产品推荐

