点击WorkManager发送的通知时,使用导航组件启动特定片段



我每天都会根据使用BroadcastReceiver启动的Worker的条件向用户发送通知。从Worker,我只有用于发送通知的context

NotificationCompat.Builder(context, CHANNEL_ID).apply {
setContentTitle(...)
setContentText(...)
setContentIntent(pendingIntent(context)) 
}.build()

如何使用导航组件创建用于启动特定片段的PendingIntent

我试过这个:

fun pendingIntent(context: Context): PendingIntent {
val navController = NavController(context.applicationContext)
navController.setGraph(R.navigation.your_navigation)
return navController.createDeepLink()
.setDestination(R.id.yourFragment)
.createPendingIntent()
}

但我有以下例外:

Caused by: java.lang.RuntimeException: Exception inflating package.name:navigation/your_navigation line 7
at androidx.navigation.NavInflater.inflate(NavInflater.java:90)
at androidx.navigation.NavController.setGraph(NavController.java:425)
at androidx.navigation.NavController.setGraph(NavController.java:407)
at 
......
at package.name.Worker.doWork(Worker.kt:15)
at androidx.work.Worker$1.run(Worker.java:85)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
at java.lang.Thread.run(Thread.java:761) 
Caused by: java.lang.IllegalStateException: Could not find Navigator with name "fragment". You must call NavController.addNavigator() for each navigation type.
at androidx.navigation.NavigatorProvider.getNavigator(NavigatorProvider.java:98)
at androidx.navigation.NavInflater.inflate(NavInflater.java:100)
at androidx.navigation.NavInflater.inflate(NavInflater.java:132)
at androidx.navigation.NavInflater.inflate(NavInflater.java:81)
at androidx.navigation.NavController.setGraph(NavController.java:425) 
at androidx.navigation.NavController.setGraph(NavController.java:407) 
at package.name.NotificationKt.pendingIntent(Notification.kt:57) 
at package.name.buildNotificationFor(Notification.kt:50) 
at package.name.showNotificationFor(Notification.kt:22) 
at package.name.doWork(Worker.kt:15) 
at androidx.work.Worker$1.run(Worker.java:85) 

根据创建显式深度链接文档,您应该使用NavDeepLinkBuilder类:

fun pendingIntent(context: Context): PendingIntent {
return NavDeepLinkBuilder(context)
.setGraph(R.navigation.your_navigation)
.setDestination(R.id.android)
.createPendingIntent()
}

这个答案更适合@Alexa289在这里提出的问题,但因为这个问题是关闭的,因为这是一个类似的问题,@ianhanniballeke提供的答案就足够了。我不得不把答案写在这里。@ianhanniballake给出的答案是光辉的,但它只适用于处理扩展FirebaseMessagingService()的类的onMessageReceived()时的特定条件。当活动在前台时,服务提供基于活动的上下文,因此代码工作正常,但当活动不在前台时时,类提供基于服务的上下文,从而从NavDeepLinkBuilder创建的pendingIntent工作不同。下面是我针对非前景案例的解决方案。首先,通过的常用方式创建pendingIntent

fun pendingIntent(context: Context): PendingIntent {
return NavDeepLinkBuilder(context)
.setGraph(R.navigation.your_navigation)
.setDestination(R.id.android)
.createPendingIntent()
}

然后你需要通过安卓清单中的意图过滤器来捕捉挂起的意图,比如这个

<intent-filter>
<action android:name="*TheClassNameOfFragmentYourDestinationPointsTo*" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

然后,从主页片段中,您可以获取启动类似的活动的意图

val intent = (activity as? AppCompatActivity)?.intent

根据意图,您可以提取捆绑包中的额外内容,然后导航到您希望喜欢此的片段

findNavController().navigate(R.id.android)

最新更新