Jetpack导航带有查询参数的深层链接

时间:2018-06-16 10:48:50

标签: android regex url query-parameters android-architecture-navigation

看起来在新的Jetpack导航库中处理带有查询参数的深层链接似乎是不可能的。如果将以下内容放在navigation.xml中: <deepLink app:uri="scheme://host/path?query1={query_value}" />然后深层链接不会打开片段。

经过一番挖掘后,我发现当它将url从xml转换为Pattern正则表达式时,罪魁祸首可能在NavDeepLink中。看起来这个问题是一个没有被解开的问号。

我写了一个失败的测试:

@Test
fun test() {
    val navDeepLink = NavDeepLink("scheme://host/path?query1={query_value}")
    val deepLink = Uri.parse("scheme://host/path?query1=foo_bar")
    assertEquals(true, navDeepLink.matches(deepLink))
}

要让测试通过,我所要做的就是逃避?如下:

@Test
fun test() {
    val navDeepLink = NavDeepLink("scheme://host/path\\?query1={query_value}")
    val deepLink = Uri.parse("scheme://host/path?query1=foo_bar")
    assertEquals(true, navDeepLink.matches(deepLink))
}

我是否遗漏了一些非常基本的东西,将查询值传递给我的片段,或者目前这是不支持的功能?

2 个答案:

答案 0 :(得分:0)

package androidx.navigation

import android.net.Uri
import androidx.test.runner.AndroidJUnit4
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class NavTest {
    @Test
    fun test() {
        val navDeepLink = NavDeepLink("scheme://host/path\\?query1={query_value1}&query2={query_value2}")
        val deepLink = Uri.parse("scheme://host/path?query1=foo_bar&query2=baz")

        val bundle = navDeepLink.getMatchingArguments(deepLink)!!
        assertTrue(bundle.get("query_value1") == "foo_bar")
        assertTrue(bundle.get("query_value2") == "baz")
    }
}

最后看起来NavDeepLink将非转义视为“?” match-zero-or-one quantifier。你需要逃脱它。换句话说,我们泄露了未记录的实施细节。

这可能与这种情况无关,但是在逃避“&amp;”时存在一些类似的问题。用“\”when using add command.

此问题也被触及in the following channel.

答案 1 :(得分:0)

您需要将DeepLink导航添加到AndroidManifest.xml(用于处理片段的特殊活动),以便在单击链接时,您的应用可以接收DeepLink并将其传递给该导航,并且片段可以将其作为参数读取:

我将Kotlin代码放在​​这里:

在您的导航文件中,要处理带有争论的深层链接的片段必须是这样的:

<fragment
        android:id="@+id/menu"
        android:name="ir.hamplus.fragments.MainFragment"
        android:label="MainFragment">

    <action android:id="@+id/action_menu_to_frg_messenger_main" 
     app:destination="@id/frg_messenger_main"/>

    <deepLink app:uri="http://hamplus.ir/request/?key={key}&amp;id={id}" />

    <argument android:name="key" app:argType="string"/>
    <argument android:name="id" app:argType="string"/>

</fragment>

阅读片段/ Activity中的deeplink参数:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
  //Or in activity read the intent?.data
       arguments?.let {
            Log.i("TAG", "Argument=$arguments")

            var key = it.getString("key")
            Log.i("TAG", "key=$key")

            var id = it.getString("id")
            Log.i("TAG", "id=$id")

        }
}

还在相关的Activity中在AndroidManifest.xml上添加导航图:

 <activity
        android:name=".MainActivity"
        android:theme="@style/AppTheme.NoActionBar" >

    <nav-graph android:value="@navigation/main_navigation"/>

</activity>