通过 NavDeepLinkBuilder 的 PendingIntent 发送参数

Rya*_*yan 8 android android-notifications android-activity android-bundle android-architecture-navigation

我在PendingIntent使用NavDeepLinkBuilder. 我可以Activity通过单击通知来启动目标,但是Activity'sIntent不包含我通过NavDeepLinkBuilder. 将Intent代替返回defaultValue在导航图中,我设定- “noJobId”。

通知创建

val notification =
    NotificationCompat.Builder(context, context.getString(R.string.notification_channel_id_new_job))
        ...
        .setContentIntent(
            NavDeepLinkBuilder(context)
                .setComponentName(NewJobDetailsActivity::class.java)
                .setGraph(R.navigation.main_graph)
                .setDestination(R.id.newJobDetailsActivity)
                .setArguments(
                    NewJobDetailsActivityArgs.Builder()
                        .setJobId(event.jobId)
                        .build()
                        .toBundle()
                )
                .createPendingIntent()
        )
        .build()

notificationManager.notify(notificationId, notification)
Run Code Online (Sandbox Code Playgroud)

context通知中使用的是FirebaseMessagingService

目的地Activity onCreate():

val jobId: String = NewJobDetailsActivityArgs.fromBundle(intent?.extras).jobId
Run Code Online (Sandbox Code Playgroud)

main_graph.xml导航图

<navigation
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_graph"
    app:startDestination="@id/jobsFragment">

    <fragment
        android:id="@+id/jobsFragment"
        android:name=".ui.jobs.JobsFragment"
        android:label="JobsFragment">

        <action
            android:id="@+id/action_jobsFragment_to_newJobDetailsActivity"
            app:destination="@id/newJobDetailsActivity" />

    </fragment>

    <fragment
        android:id="@+id/historyFragment"
        android:name=".ui.history.HistoryFragment"
        android:label="HistoryFragment" />

    <fragment
        android:id="@+id/profileFragment"
        android:name=".ui.profile.ProfileFragment"
        android:label="ProfileFragment" />

    <activity
        android:id="@+id/newJobDetailsActivity"
        android:name=".ui.job.NewJobDetailsActivity"
        android:label="activity_new_job_details"
        tools:layout="@layout/activity_new_job_details">

        <argument
            android:name="jobId"
            android:defaultValue="noJobId" // just for testing
            app:argType="string" />

    </activity>

</navigation>
Run Code Online (Sandbox Code Playgroud)

有没有其他人遇到过这个问题?我有一种感觉,这是导航组件的一个错误,但我还不能 100% 确定。很好奇我是否在这里遗漏了什么。

依赖项:android.arch.navigation:navigation-fragment-ktx:1.0.0-alpha06, android.arch.navigation:navigation-ui-ktx:1.0.0-alpha06

插件:androidx.navigation.safeargs

Rya*_*yan 7

我在谷歌的公共问题跟踪器上发布了这个问题,我收到了以下回复:

NavDeepLinkBuilder 将其参数传递给 NavController 以深度链接到特定目的地。活动目的地实际上是导航图的更多出口点,而不是可以/应该深层链接的东西。

来源:https : //issuetracker.google.com/issues/118964253

该帖的作者推荐使用TaskStackBuilder的,而不是NavDeepLinkBuilder创建时PendingIntent,其目的地是一个Activity。这是我最终的结果:

NotificationCompat.Builder(context, context.getString(R.string.notification_channel_id_new_job))
    ...
    .setContentIntent(
        TaskStackBuilder.create(context).run {
            addNextIntentWithParentStack(Intent(context, DestinationActivity::class.java).apply {
                putExtras(DestinationActivityArgs.Builder(jobId).build().toBundle())
            })
            getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
        }
    )
    .build()
Run Code Online (Sandbox Code Playgroud)

此解决方案使我能够成功地深层链接到目标,Activity同时仍然能够Activity通过生成的DestinationActivityArgs构建器引用导航图中定义的参数,并且可以从目标ActivityonCreate()方法访问参数。

当应用程序任务不在“最近应用程序”列表中,应用程序在前台显示其他ActivityFragment应用程序,或者应用程序在前台并且已经在目的地时,此解决方案也能正确处理这些情况ActivityaddNextIntentWithParentStack()正确处理了导航,所以点击来自目的地的向上按钮Activity导航回逻辑父Activity如在定义AndroidManifest

这个解决方案没有直接使用导航架构库来构建PendingIntent.

  • 我不明白为什么没有更多的人带着类似的问题来到这里。我发现问题相关,答案仍然适用于导航版本 2.1.0-rc01 中的通知 (2认同)