繁体   English   中英

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

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

我根据使用 BroadcastReceiver 启动的Worker的条件向用户发送每日通知。 Worker我只有发送通知的context

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

如何使用 Navigation 组件创建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 class:

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

这个答案更适合@Alexa289 在这里提出的问题,由于这个问题是基于@ianhanniballeke提供的类似问题和答案就足够了。 我不得不在这里写下答案。 @ianhanniballake 提供的答案非常出色,但它仅在处理扩展FirebaseMessagingService()的 class 的onMessageReceived()时适用于某些条件。 当活动在前台时,服务提供基于活动的上下文,因此代码工作正常,但当活动不在前台时,class 提供基于服务的上下文,因此从 NavDeepLinkBuilder 创建的 pendingIntent 工作方式不同。 所以这是我对非前台情况的解决方案。 首先,通过通常的方式创建pendingIntent

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

那么您需要通过 android 清单中的意图过滤器来捕获待处理的意图,如下所示

        <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)

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM