簡體   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