简体   繁体   English

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

[英]Launch a particular Fragment using Navigation component when tapped on Notification that is sent from WorkManager

I'm sending a daily notification to the user based on a condition from the Worker that is launched using BroadcastReceiver.我根据使用 BroadcastReceiver 启动的Worker的条件向用户发送每日通知。 From Worker I only have context for sending notification.Worker我只有发送通知的context

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

How do I create PendingIntent for launching a particular fragment using Navigation component?如何使用 Navigation 组件创建PendingIntent以启动特定片段?

I tried this:我试过这个:

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

But I get following exceptions:但我得到以下例外:

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) 

As per the Create an explicit deep link documentation , you should be using the NavDeepLinkBuilder class:根据创建显式深层链接文档,您应该使用NavDeepLinkBuilder class:

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

This answer is more suited for the question asked by @Alexa289 here but since the question was closed on the basis that this is a similar question and answer provided by @ianhanniballeke should suffice.这个答案更适合@Alexa289 在这里提出的问题,由于这个问题是基于@ianhanniballeke提供的类似问题和答案就足够了。 I am compelled to write the answer here.我不得不在这里写下答案。 The answer provided by @ianhanniballake is brillant but it only work for certain condition when dealing with onMessageReceived() of a class extending FirebaseMessagingService() . @ianhanniballake 提供的答案非常出色,但它仅在处理扩展FirebaseMessagingService()的 class 的onMessageReceived()时适用于某些条件。 When the activity is in foreground, the service provide activity based context hence the code works fine, but when the activity is not in foreground, the class provide service based context, hence the pendingIntent created from NavDeepLinkBuilder works differently.当活动在前台时,服务提供基于活动的上下文,因此代码工作正常,但当活动不在前台时,class 提供基于服务的上下文,因此从 NavDeepLinkBuilder 创建的 pendingIntent 工作方式不同。 So here goes my solution for the non-foreground cases.所以这是我对非前台情况的解决方案。 Firstly, create the pendingIntent through the usual way首先,通过通常的方式创建pendingIntent

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

then you need to catch the pending intent through intent filter in the android manifest like this那么您需要通过 android 清单中的意图过滤器来捕获待处理的意图,如下所示

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

Then from the home fragment, you can grab the intent that start the activity like this然后从主页片段中,您可以像这样获取启动活动的意图

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

From the intent you can extract the extras in the bundle then navigate to the fragment you wish to like this意图中,您可以提取捆绑包中的附加内容,然后导航到您希望喜欢的片段

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用导航架构组件启动带有结果的片段 - launch a fragment with result using navigation architecture components 如何从导航抽屉的片段中启动活动 - how to launch an activity from a fragment of a navigation drawer 在Oreo及更高版本中使用WorkManager时,我应该显示正在进行的通知吗? - Should I show ongoing notification when using WorkManager in Oreo and above? 无法使用导航组件导航到所需的片段 - Unable to navigate to desired fragment using navigation component 使用导航组件而不使用 ViewModel 时如何在后台堆栈中保留 Fragment 实例? - How to preserve Fragment instance in backstack when using Navigation Component without using ViewModels? 如何从导航组件中的子片段关闭父片段 - How to close a parent fragment from child fragment in navigation component 如何从导航组件中的子片段访问父片段的视图 - How to access a view of parent fragment from child fragment in navigation component 有没有一种方法可以防止在使用Android导航组件时在bottomNavigation中重新创建片段 - Is there a way to prevent re-create fragment in bottomNavigation when using android navigation component 使用导航切换到另一个片段时保存片段数据 - Save Fragment data when switch to another fragment using Navigation 如何在 Android 导航组件中从片段导航到活动? - How to navigate from fragment to Activity in Android navigation component?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM