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

