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

Jetpack Compose(无Fragment)结合导航图处理FCM通知后台跳转

后台状态下FCM通知点击跳转处理(Jetpack Compose无Fragment场景)

在Jetpack Compose无Fragment的项目里,处理后台FCM通知点击跳转,核心是利用FCM的消息字段配置和Activity的Intent数据传递,分两种场景实现:

一、利用FCM默认通知的内置跳转逻辑

当应用处于后台时,FCM的通知消息(包含notification字段)会由系统托盘直接展示,要实现点击跳转指定页面,需在发送FCM消息时同时携带data字段,将订单ID这类关键数据放入其中。

示例FCM消息结构:

{
  "to": "设备令牌",
  "notification": {
    "title": "订单状态更新",
    "body": "您的订单12345已发货"
  },
  "data": {
    "order_id": "12345",
    "screen": "order_detail"
  }
}

在主Activity中处理Intent数据:

主Activity是Compose导航的入口,需在Activity中读取Intent携带的data字段,触发Compose导航跳转:

class MainActivity : ComponentActivity() {
    private val navController by lazy { rememberNavController() }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        handleNotificationData(intent)
        setContent {
            YourAppTheme {
                NavHost(navController = navController, startDestination = "home") {
                    composable("home") { HomeScreen(navController) }
                    composable("order_detail/{orderId}") { backStackEntry ->
                        val orderId = backStackEntry.arguments?.getString("orderId") ?: ""
                        OrderDetailScreen(orderId)
                    }
                }
            }
        }
    }

    // 单Task模式下,后台点击通知会触发此方法
    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        intent?.let { handleNotificationData(it) }
    }

    private fun handleNotificationData(intent: Intent) {
        val orderId = intent.getStringExtra("order_id")
        val targetScreen = intent.getStringExtra("screen")
        if (targetScreen == "order_detail" && orderId != null) {
            // 避免重复跳转
            if (navController.currentDestination?.route != "order_detail/$orderId") {
                navController.navigate("order_detail/$orderId")
            }
        }
    }
}

注意:给主Activity设置singleTop或singleTask启动模式,避免重复创建实例,确保onNewIntent能接收到通知的Intent。

二、自定义本地通知实现完全控制

如果需要更灵活的通知样式或跳转逻辑,可忽略FCM默认通知,在FirebaseMessagingService中自行构建本地通知,用PendingIntent指定跳转,和本地通知逻辑完全一致:

1. 自定义FirebaseMessagingService:

class MyFirebaseMessagingService : FirebaseMessagingService() {
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
        // 提取消息数据
        val orderId = remoteMessage.data["order_id"] ?: ""
        val title = remoteMessage.notification?.title ?: "订单通知"
        val body = remoteMessage.notification?.body ?: ""

        // 创建跳转Intent
        val intent = Intent(this, MainActivity::class.java).apply {
            putExtra("order_id", orderId)
            putExtra("screen", "order_detail")
            flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
        }
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        // 构建并发送通知
        val notification = NotificationCompat.Builder(this, "order_channel")
            .setContentTitle(title)
            .setContentText(body)
            .setSmallIcon(R.drawable.ic_notification)
            .setContentIntent(pendingIntent)
            .setAutoCancel(true)
            .build()

        NotificationManagerCompat.from(this).notify(1, notification)
    }
}

2. 配置Service清单:

在AndroidManifest.xml中注册自定义Service:

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

这种方式无论应用处于前台还是后台,都能完全控制通知的展示和跳转逻辑,和本地通知实现逻辑一致。

内容的提问来源于stack exchange,提问作者vanste25

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 02:33:06