Android 深层链接不遵循路径前缀

Posted

技术标签:

【中文标题】Android 深层链接不遵循路径前缀【英文标题】:Android deep links not following path prefix 【发布时间】:2016-03-20 11:59:15 【问题描述】:

我能找到的最接近的是这个问题here。但它并没有完全涵盖我遇到的问题。

我的应用设置中有深层链接以使用 /app 作为路径前缀。我遇到的问题是http://example.com/upgrade 之类的链接也试图在我的应用程序中打开,即使它在 URL 中的任何位置都没有 /app。我知道您不能排除前缀指定的网址,但路径前缀的全部意义不在于仅包含这些网址吗?

基本上我希望像这样的链接到深层链接:

http://example.com/app/home
http://example.com/app/specials

但不是这样的链接:

http://exaple.com/
http://example.com/login

这是我的清单中的内容:

<data android:scheme="http"
    android:host="example.com"
    android:pathPrefix="/app"/>

编辑 1

也找到了this link,但我没有任何空前缀,只有斜杠“/”的前缀

编辑 2

触发它的 url 是 http://example.com/upgrade.php?app=1&amp;method=1&amp;uid=1,我不确定 app 在 ?也会触发它,所以我将前缀更改为 /application 但这也不起作用,它仍然会触发它们。

编辑 3

这是清单中的其他深层链接数据标签:

个人资料活动

<data android:scheme="myapp"
    android:host="profile"
    android:pathPrefix="/"/>

登录/注册活动

<data android:scheme="myapp"
     android:host="login"
     android:pathPrefix="/signup"/>

主要活动

<data android:scheme="myapp"
     android:host="main"
     android:pathPrefix="/"/>

<data android:scheme="http"
     android:host="test.example.com"
     android:pathPrefix="/app"/>

<data android:scheme="http"
     android:host="live.example.com"
     android:pathPrefix="/app"/>

编辑 4

这变得越来越令人困惑,如果我从活动中删除带有 myapp 作为方案的数据标签(或者如果我从前缀为“/”的所有内容中删除 pathPrefix)它不再触发深层链接网址,即使其中包含 /app。

【问题讨论】:

这是您清单中唯一的 &lt;data&gt; 标记吗? 该活动有 3 个,另外两个活动各有一个。 这是唯一一个使用 example.com 的,其他使用我的应用程序名称作为方案,其中一些使用“/”作为前缀,但所有使用 http 方案的都有“/app”的定义前缀 尝试使用“android:pathPattern="/app*" 刚刚尝试了 pathPattern="/application*" 并且它也不起作用,即使它根本不包含“应用程序”,链接仍然会触发它。我会将每个数据标签添加到问题中,以防缺少其他内容。 【参考方案1】:

我想通了,数据标签似乎有点相互渗透,因此方案“example”的数据上的“/”前缀也适用于其他数据标签中的所有方案。我只需要为我的自定义方案深层链接和 url 深层链接使用单独的 Intent 过滤器,如下所示:

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

        <!-- must start with http://test.example.com/app -->
        <!-- http://test.example.com/ won't work since prefix / is in a different intent-filter -->
        <data android:scheme="http"
            android:host="test.example.com"
            android:pathPrefix="/app"/>

        <!-- must start with http://live.example.com/app -->
        <data android:scheme="http"
            android:host="live.example.com"
            android:pathPrefix="/app"/>

    </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" />

        <!-- must start with example://main/ -->
        <!-- http://test.example.com/ won't work since http is in a different intent-filter -->
        <data android:scheme="example"
            android:host="main"
            android:pathPrefix="/"/>

    </intent-filter>
</activity>

【讨论】:

谢谢,正是我正在处理的问题。删除额外的 pathPrefix="/" 对我的 Cordova Ionic 项目有效【参考方案2】:

正如here 解释的那样,您的属性将被合并:

虽然可以在同一个过滤器中包含多个 &lt;data&gt; 元素,但当您打算声明唯一 URL(例如方案和主机的特定组合)时,创建单独的过滤器很重要,因为多个 &lt;data&gt;同一意图过滤器中的元素实际上被合并在一起,以说明它们组合属性的所有变体。

因此,将它们放入 &lt;intent-filter&gt; 的单独实例中可以解决您的问题。

【讨论】:

感谢 sn-p。【参考方案3】:

我自己运行了一些测试我认为您自己已经创建了这个问题,然后继续测试来自您的应用程序的任何更多深层链接,请转到

设置 -> 您的应用名称 -> 默认启动并选择清除默认设置

然后导航回您的应用清单并将意图过滤器添加到每个 url 的 Activity:

在您的示例中,您要求

http://example.com/app/home
http://example.com/app/specials

我假设你有一个 Activity 可以为上面给出的 URI 启动其中的每一个。

对于清单中的 HomeActivity,请执行以下操作:

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

        <!-- http://example.com/app/home -->
        <data android:scheme="http"
            android:host="example.com"
            android:pathPrefix="/app/home"/>

        <!-- https://example.com/app/home -->
        <data android:scheme="https"
            android:host="example.com"
            android:pathPrefix="/app/home"/>

        <!-- custom url scheme example://app/home -->
        <data android:scheme="example"
            android:host="app"
            android:pathPrefix="/home"/>
    </intent-filter>
</activity>

从您的终端使用adb shell am start -W -a android.intent.action.VIEW -d http://example.com/app/homeadb shell am start -W -a android.intent.action.VIEW -d example.com/app/home 进行测试

然后为您的 SpecialsActivity

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

        <!-- http://example.com/app/specials -->
        <data android:scheme="http"
            android:host="example.com"
            android:pathPrefix="/app/specials"/>

        <!-- https://example.com/app/specials -->
        <data android:scheme="https"
            android:host="example.com"
            android:pathPrefix="/app/specials"/>

        <!-- custom url scheme example://app/specials -->
        <data android:scheme="example"
            android:host="app"
            android:pathPrefix="/specials"/>
    </intent-filter>
</activity>

从您的终端使用adb shell am start -W -a android.intent.action.VIEW -d http://example.com/app/specialsadb shell am start -W -a android.intent.action.VIEW -d example.com/app/specials 进行测试

这就是它的工作原理,如果您将应用设置为处理 http://example.com/ 网址并选择默认选择,那么它将尝试使用您的应用打开 http://example.com/anything

因此,简而言之,当您指定 pathPrefix 时,请确保包含您真正想要拦截的内容,并且如果您测试不应打开您的应用程序的链接,则默认情况下不要选择您的应用程序,只需调整您的 pathPrefix 以便它不会由您的应用触发。

例如上面的网址不会打开

http://example.com/app

因为我们还没有定义&lt;data /&gt; 标签来处理这个问题。

更新 并在使用 \ 或 * 时直接从文档中添加:

因为'\' 在从 XML 读取字符串时用作转义字符(在将其解析为模式之前),因此您需要双重转义:例如,文字 '*' 将被写为'\\*' 和文字 '\' 将写为 '\\\\'。这与在 Java 代码中构造字符串时需要编写的内容基本相同。

祝你好运,编码愉快!

【讨论】:

这可能会起作用,除了我还有一些现有的使用没有前缀的自定义方案的深层链接,比如 example://main/ 它只是转到主页,然后一些在像example://main/settings 这样的主要活动听起来我将不得不摆脱第一个活动,只在所有内容上加上前缀。但这需要我改变我的深层链接,一旦它们出现,说起来容易做起来难。

以上是关于Android 深层链接不遵循路径前缀的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 上下载应用后,Firebase 深层链接不跟踪链接(延迟深层链接)

如何使用 Branch 支持现有的深层链接路由

使用意图不打开应用程序的 Android 深层链接

OAuth 回调 URI 的 Android 深层链接不起作用

Parcelables 不支持默认值。 Android 导航深层链接参数

Android 深层链接 - 不显示意图选择器弹出窗口,强制打开应用