Navigation components : Deeplink using uri depending buildType

前端 未结 1 585
隐瞒了意图╮
隐瞒了意图╮ 2021-02-01 23:09

Any way to read a constant depending buildType ${deepLinkHost}?

debug -> deepLinkUri = http://link.debug/
staging -> deepLinkUri = http://link         


        
相关标签:
1条回答
  • 2021-02-01 23:47

    It looks like it's not currently supported out of the box, but there is a pretty simple workaround. Normally registering a deep link requires two steps:

    1. Add deepLink to the navigation graph. Since we can't specify any substitution or a @string resource as the uri, let's just define the host name as a variable: <deepLink app:uri="http://{deepLinkHost}/?code={token}" />. This link will match any host and pass deepLinkHost as a parameter.
    2. Register an intent-filter in the AndroidManifest.xml, so our activity actually reacts on the deep link. The recommended approach for the latest android studio is to add <nav-graph android:value="@navigation/nav_graph" /> to the manifest, so it generates necessary intent-filter automatically. It will, however, register our activity to accept links with any host, which is probably not what we want. So instead of doing this, let's go with the standard approach. Basically here we define the intent-filter manually instead of auto-generating it from navigation graph. So we can use manifest substitutions just as we would normally do.

    Example

    • debug -> http://link.debug/identification?code=123
    • staging -> http://link.staging/identification?code=123
    • release -> http://link/identification?code=123

    and

    • debug -> http://link.debug/banner?id=123
    • staging -> http://link.staging/banner?id=123
    • release -> http://link/banner?id=123

    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>
    

    22.05.2020 Update: Starting with the gradle plugin version 3.6 the deep link uri cannot contain parameters in scheme and host parts, it will result in Improper use of wildcards and/or placeholders in deeplink URI host error.

    Fortunately one can use a wildcard, so to make the approach work again just change the deepLink definition in your nav graph file:

    <deepLink app:uri="{deepLinkUri}/banner?id={id}" /> to <deepLink app:uri=".*/banner?id={id}" />

    0 讨论(0)
提交回复
热议问题