点击从 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()
如何创建 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.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.run(Worker.java:85)
根据 Create an explicit deep link documentation, you should be using the NavDeepLinkBuilder
class:
fun pendingIntent(context: Context): PendingIntent {
return NavDeepLinkBuilder(context)
.setGraph(R.navigation.your_navigation)
.setDestination(R.id.android)
.createPendingIntent()
}
这个答案更适合@Alexa289 here但是提出的问题,因为问题是closed 因为这是@ianhanniballeke 提供的类似问题和答案就足够了。我不得不在这里写下答案。 @ianhanniballake 提供的答案非常出色,但它仅在处理扩展 FirebaseMessagingService()
的 class 的 onMessageReceived()
时适用于特定条件。当 activity 处于前台时,服务提供基于 activity 的上下文,因此代码工作正常,但是当 activity 不在前台时,class 提供基于服务的上下文,因此从 NavDeepLinkBuilder 创建的 pendingIntent 的工作方式不同。所以这里是我针对非前景案例的解决方案。
首先,通过通常的方式创建pendingIntent
fun pendingIntent(context: Context): PendingIntent {
return NavDeepLinkBuilder(context)
.setGraph(R.navigation.your_navigation)
.setDestination(R.id.android)
.createPendingIntent()
}
然后您需要通过 android 清单中的 Intent 过滤器捕获未决 Intent
<intent-filter>
<action android:name="*TheClassNameOfFragmentYourDestinationPointsTo*" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
然后从主页片段中,您可以像这样获取启动 activity 的意图
val intent = (activity as? AppCompatActivity)?.intent
从 intent 您可以提取捆绑包中的额外内容,然后导航到您想要喜欢的片段
findNavController().navigate(R.id.android)
我根据使用 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.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.run(Worker.java:85)
根据 Create an explicit deep link documentation, you should be using the NavDeepLinkBuilder
class:
fun pendingIntent(context: Context): PendingIntent {
return NavDeepLinkBuilder(context)
.setGraph(R.navigation.your_navigation)
.setDestination(R.id.android)
.createPendingIntent()
}
这个答案更适合@Alexa289 here但是提出的问题,因为问题是closed 因为这是@ianhanniballeke 提供的类似问题和答案就足够了。我不得不在这里写下答案。 @ianhanniballake 提供的答案非常出色,但它仅在处理扩展 FirebaseMessagingService()
的 class 的 onMessageReceived()
时适用于特定条件。当 activity 处于前台时,服务提供基于 activity 的上下文,因此代码工作正常,但是当 activity 不在前台时,class 提供基于服务的上下文,因此从 NavDeepLinkBuilder 创建的 pendingIntent 的工作方式不同。所以这里是我针对非前景案例的解决方案。
首先,通过通常的方式创建pendingIntent
fun pendingIntent(context: Context): PendingIntent {
return NavDeepLinkBuilder(context)
.setGraph(R.navigation.your_navigation)
.setDestination(R.id.android)
.createPendingIntent()
}
然后您需要通过 android 清单中的 Intent 过滤器捕获未决 Intent
<intent-filter>
<action android:name="*TheClassNameOfFragmentYourDestinationPointsTo*" />
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
然后从主页片段中,您可以像这样获取启动 activity 的意图
val intent = (activity as? AppCompatActivity)?.intent
从 intent 您可以提取捆绑包中的额外内容,然后导航到您想要喜欢的片段
findNavController().navigate(R.id.android)