控制/指定Android Jetpack导航Deeplink主机名

时间:2019-05-08 13:22:54

标签: android android-jetpack android-architecture-navigation

使用Jetpack导航库(在撰写本文时为Ver 2.1.0-alpha03),构造深度链接URI可以用${applicationId}替换应用程序包名称(它使用Context.getPackageName())。

<fragment
    android:id="@+id/screen1"
    android:name="com.example.com.Screen1Fragment"
    android:label="Screen1Fragment"
    tools:layout="@layout/fragment_screen1" >
    <deepLink android:id="@+id/screen1_link"
        app:uri="https://${applicationId}/screen1/" />
</fragment>

通过使用导航库,可以为您创建意图过滤器。

在Jetpack导航意图过滤器可以由资源设置之前。示例:

<intent-filter>
    <action android:name="com.tictrac.intent.action.VIEW"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data
        android:host="@string/app_intent_host"
        android:path="/settings"
        android:scheme="https"/>
</intent-filter>

我目前正在package name != deep-link host-name的白标应用程序上工作。

如果不以一系列方式重新定义所有导航图,是否可以指定深层链接主机名?

1 个答案:

答案 0 :(得分:1)

Jetpack导航库允许您创建或定义自己的图形以及目的地,但是使用导航的一个令人信服的理由是要处理深层链接,同时让导航库将导航建立到返回的目的地堆栈。

Jetpack使用Gradle任务将导航图中的深层链接URL转换为清单中的意图过滤器。还可以在运行时读取XML导航图,以创建带有相应的深层链接条目的导航图。

可以通过创建gradle任务来解决此问题,该任务将gradle prameter或默认值替换为令牌。

添加新的gradle文件navigation.gradle.kts

import java.io.BufferedReader

tasks.register("convertNavigation") {
    doLast{
        val appIntentHost: String by project

        val MAGIC_TEXT = "{@string/app_intent_host}"
        val DEFAULT_URL = "default.url.com"

        val generatedResDir = File(buildDir, "generated/local/main/res")
        val targetDir = File(  generatedResDir, "navigation")

        if (targetDir.exists()) {
            targetDir.delete()
        }
        targetDir.mkdirs()

        val tree = fileTree("src/main/nav/navigation")
        val host: String = if (project.hasProperty("appIntentHost") && !appIntentHost.isBlank())
            appIntentHost else DEFAULT_URL

        println ("Replacing $MAGIC_TEXT in nav files with [$host]")

        for (f in tree) {
            val target = File(targetDir, f.name)
            println ("Transforming ${f.name} to ${target.absolutePath}")
            val writer = target.writer()
            val allText = f.absoluteFile.inputStream().bufferedReader().use(BufferedReader::readText)

            writer.write(allText.replace(MAGIC_TEXT, host))
            writer.close()
        }
    }
}

将此添加到您要导航的应用/模块的build.gradle

apply from: "navigation.gradle.kts"

gradle.projectsEvaluated {
  // Modifies and copies asset nav graphs to generated
  preBuild.dependsOn convertNavigation
}

android{
  sourceSets {
    //Location of generate navigation XML
    main.assets.srcDirs += 'src/main/nav'
  }
}

将导航xml移至src/main/nav/navigation(例如MyApplication/app/src/main/nav/navigation),并使深层链接看起来像这样

        <deepLink android:id="@+id/verify_link"
            app:uri="https://{@string/app_intent_host}/verify/" />

这将生成正确的清单default.url.com作为URL,除非您使用-PappIntentHost=customer.url.com运行gradle脚本,否则将被替换。

希望这将由Google解决(我不知道gradle脚本的开源源在哪里),将来这将成为无效答案。 Google issue tracker