导航组件:使用uri通过buildType进行Deeplink

时间:2019-09-08 11:26:26

标签: android androidx deeplink

有什么方法可以读取依赖于buildType ${deepLinkHost}的常量?

debug -> deepLinkUri = http://link.debug/
staging -> deepLinkUri = http://link.staging/
release ->  deepLinkUri=  http://link/
<?xml version="1.0" encoding="utf-8"?>
<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/navigation_home"
    app:startDestination="@id/fragment_home">

    <fragment
        android:id="@+id/fragment_home"
        android:name="..."
        tools:layout="@layout/fragment_home">
        <argument
            android:name="token"
            android:defaultValue="@null"
            app:argType="string"
            app:nullable="true" />
        <deepLink app:uri="${deepLinkUri}/?code={token}" />
</fragment>

这以前是通过build.gradle上的manifestPlaceholders.deepLinkHost和AndroidManifest中的活动进行Deeplinks管理的,但是一旦google使用1个Activity到N个片段,我们如何使用导航组件进行管理?

3 个答案:

答案 0 :(得分:2)

貌似目前尚不支持,但是有一个非常简单的解决方法。 通常,注册深层链接需要两个步骤:

  1. deepLink添加到导航图。由于我们不能将任何替换或@string资源指定为uri,因此我们仅将主机名定义为变量: <deepLink app:uri="http://{deepLinkHost}/?code={token}" />。此链接将匹配任何主机,并通过deepLinkHost作为参数。
  2. AndroidManifest.xml中注册一个意图过滤器,因此我们的活动实际上在深层链接上做出反应。对于最新的android studio,推荐的方法是将<nav-graph android:value="@navigation/nav_graph" />添加到清单中,以便它自动生成必要的intent-filter。但是,它将注册我们的活动以接受与任何主机的链接,这可能不是我们想要的。因此,让我们不用the standard approach去做。基本上,这里我们手动定义了意图过滤器,而不是从导航图自动生成它。因此,我们可以像平常一样使用清单替换。

示例

build.gradle

buildTypes {

        debug {
            manifestPlaceholders.deepLinkUri = "http://link.debug"
        }

        staging {
           manifestPlaceholders.deepLinkUri = "http://link.staging"
        }

        release {
           manifestPlaceholders.deepLinkUri = "http://link"
        }
    }

AndroidManifest.xml

 <activity
     android:name=".HomeActivity">
     <intent-filter>
       <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
     </intent-filter>
     <intent-filter>
        <action android:name="android.intent.action.VIEW" />
         <category android:name="android.intent.category.DEFAULT" />
         <category android:name="android.intent.category.BROWSABLE" />

         <data
            android:host="${deepLinkUri}"
            android:scheme="https" />
    </intent-filter>   
 </activity>

navigation_main.xml

<?xml version="1.0" encoding="utf-8"?>
<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/navigation_home"
    app:startDestination="@id/fragment_home">

    <fragment
        android:id="@+id/fragment_home"
        android:name="..."
        tools:layout="@layout/fragment_home">
        <argument
            android:name="deepLinkUri"
            android:defaultValue="@null"
            app:argType="string"
            app:nullable="true" />
        <argument
            android:name="token"
            android:defaultValue="@null"
            app:argType="string"
            app:nullable="true" />
        <deepLink app:uri="{deepLinkUri}/identification?code={token}" />
</fragment>

    <fragment
        android:id="@+id/fragment_marketing"
        android:name="..."
        tools:layout="@layout/fragment_marketing">
        <argument
            android:name="deepLinkUri"
            android:defaultValue="@null"
            app:argType="string"
            app:nullable="true" />
        <argument
            android:name="id"
            app:argType="integer"
            app:nullable="true" />
        <deepLink app:uri="{deepLinkUri}/banner?id={id}" />
</fragment>

答案 1 :(得分:0)

只需简单地添加 -

<deepLink app:uri=".*/{my_token}" />

为我工作!!!这也让我惊讶的是它不需要任何额外的代码。

编辑 1:但是上面的代码也用我的应用程序打开其他应用程序的其他 URL。如果您真的希望人们使用您的应用程序打开他们的 URL,这是 GOOD应用程序。但如果你不喜欢那样,那么你可以尝试下面的修复。 我修复了它,只需为我的 URL 的两个变体添加两个深层链接,例如 -

<deepLink
    app:uri="http://www.stage.com/{token}" />

<deepLink
    app:uri="http://www.production.com/{token}" />

答案 2 :(得分:0)

仍然没有有效的解决方案。

请为这两个问题加注星号以便更快地解决(我认为不会,这会有所帮助,但也许...):

https://issuetracker.google.com/issues/36994900

https://issuetracker.google.com/issues/110237825