深层链接意图不起作用

Posted

技术标签:

【中文标题】深层链接意图不起作用【英文标题】:Deep-linking intent does not work 【发布时间】:2014-09-08 15:12:51 【问题描述】:

我按照https://developer.android.com/training/app-indexing/deep-linking.html 上的说明进行操作,但是当我想通过adb 触发意图时:

adb shell am start
           -W -a android.intent.action.BROWSEABLE
           -d "http://example.com/gizmos" com.myapp.android

我才明白

Error: Activity not started, unable to resolve Intent act=android.intent.action.VIEW dat=example://gizmos flg=0x10000000 pkg=com.myapp.android

<activity
        android:name=".activities.DeepLinkActivity"
        android:label="@string/title_activity_deep_link">
        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />

        <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:scheme="http"
                android:host="example.com"
                android:pathPrefix="/gizmos" />
        </intent-filter>
    </activity>

我犯了什么明显的错误吗?

【问题讨论】:

@MikeM。不,它就在那里。 @RichardLeMesurier 感谢您指出问题,但答案与我的问题有什么关系? ;-) android.intent.action.BROWSABLE 不是BROWSEABLE 从对我有用的命令中删除我的应用程序包名称。 @david_adler 这对我们来说不是问题。我没有研究为什么该命令在使用和不使用包名称时会有所不同。 【参考方案1】:

编辑:

好的,首先确保 adb 可以访问您的包:

adb shell am start -n com.example.simon.test/.activities.MainActivity

然后要接受多个数据标签,您需要不同的意图过滤器(这就是它对我的工作方式,与我在网上看到的所有其他示例不同)。例如:

<intent-filter>
    ...
    <data android:scheme="http"
          android:host="example.com"/>
</intent-filter>
<intent-filter>
    ...
    <data android:scheme="http"
          android:host="example.com"
          android:pathPrefix="/gizmos"/>
</intent-filter>

注意,在上面的示例中,pathPrefix 以 正斜杠 开头!

我不确定为什么 Google 的文档如此具有误导性,或者可能是针对某些不同版本的 adb,但上述更改对我来说非常有效。这有帮助:Source


这就是我使 Chrome 浏览器路由特定链接到我的应用程序的方式:

<activity
    android:name=".activities.DeepLinkActivity"
    android:label="@string/app_name">
    <!-- Accept chrome links -->
    <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:scheme="http"
              android:host="example.com"
            android:pathPrefix="/"/>
    </intent-filter>
    <!-- Accept adb data flag -->
    <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:scheme="http"
              android:host="example.com"/>
    </intent-filter>
</activity>

注意第一个过滤器适用于 Google Chrome,而第二个过滤器适用于 ADB。

NOTE2 如果在浏览器的地址栏中输入链接,则不会显示应用选择菜单。它必须是某个页面中的&lt;a href="http://example.com"&gt;&lt;/a&gt; 链接。

在我看来,这里的一切都相当模糊,而且真的不是我期望的那样。但这就是它在我的设备上的工作方式。希望这对您也有帮助(并且有效)。

【讨论】:

完美,它仍然缺少您需要设置 android:export="true" (可能用于非启动活动?)的事实,例如,如果您的活动不在根目录中,则测试命令将是adb shell am start -n com.example.simon/.test.MainActivity 无论如何,我不确定这是否是一个概念问题,但是当我在浏览器应用程序中输入这个HTTP地址时,为什么MainActivity现在没有启动? 是的,所以我使用了三个类别:VIEWBROWSABLEDEFAULT。 API 方面,我正在使用 Android 4.2 和 Android 4.4(浏览器版本为 4.1.2)。我目前正在使用 Gmail 测试打开链接。 哇哦,明白了!由于复制粘贴,我将VIEW 的标签元素从&lt;action&gt; 更改为&lt;category&gt; 现在知道了!当然,如果不定义 &lt;action&gt; 标签,意图过滤器将无法工作。 展示我们需要不同的意图过滤器的好例子!此外,pathPrefix 中的斜线也很重要。干得好!【参考方案2】:

经过一些测试,这对我有用:

    <activity android:name=".activities.MainActivity">
        <intent-filter android:label="@string/app_name">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="http"
                  android:host="www.example.com"
                  android:pathPrefix=""
                />
            <data android:scheme="myschema"
                  android:host="example"
                  android:pathPrefix=""
                />
        </intent-filter>
    </activity>

当点击浏览器中的任何链接(例如“http://www.example.com”、“http://www.example.com/”或“http://www.example.com/whatever”)时,此功能有效。与“myschema://example/whatever”相同。

也适用于adb 使用此命令(使用任何这些 URL):

adb shell am start -W -a android.intent.action.VIEW -d "http://www.example.com" com.example

希望它可以帮助您入门。

当一切正常时,您可能需要为不同的活动配置不同的pathPrefix

【讨论】:

这很有用。谢谢... :) 您需要将 myschema://example 分离到另一个意图过滤器。根据developer.android.com/training/app-indexing/deep-linking.html - “注意:意图过滤器可能只包含URI模式的单个数据元素。创建单独的意图过滤器以捕获其他URI模式。” @Ferran Maylinch,感谢您的回答,我们可以使用 android:host="www.example.com" 中的任何网站吗? android:pathPrefix="" 路径前缀不能为空 使用adb 进行测试并不能给出真实的生产图片。例如。我想使用myschema://example/whatever 从电子邮件打开应用程序,但 GMAIL 应用程序无法将其识别为链接。试图将其作为链接发送(包装为链接的 href,使用 html 发送电子邮件),但 Google 将其转换为普通文本。因此,我可以启动应用程序并将其视为链接的唯一方法 - 仅使用 android:scheme="https"【参考方案3】:

在我的例子中,我在 MainActivity 中放置了深度链接意图过滤器,它也是主启动器。这导致了问题。

在我创建了另一个单独的活动并将意图过滤器放在那里之后,它解决了这个问题。希望这可以帮助面临同样问题的其他人。

【讨论】:

是的,这是一个很好的方法,我一直在寻找解决方案。【参考方案4】:

就我而言,我使用的是模拟器而不是实际的 USB 连接设备,因此我不得不将 -d 更改为 -e,如下所示:

adb shell am start -W -a android.intent.action.VIEW -e "http://www.example.com" com.example

注意深层链接前的 -e

【讨论】:

【参考方案5】:

首先,阅读此页面上@user3249477 的答案。

我只是想补充一点,而不是他写的,你可以使用 pathPattern 来压缩它:

<activity
    android:name=".activities.DeepLinkActivity"
    android:label="@string/app_name">
    <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:scheme="http"
              android:host="example.com"
            android:pathPattern=".*"/>
    </intent-filter>
</activity>

“.*”同时匹配空字符串和“/”,因此这两种情况都包括在内。如果您最终尝试处理多个方案和主机,这变得尤为重要,因此您不必向 http, https X "", "/" X "foo", "bar" 的 powerset 发送垃圾邮件等

【讨论】:

主机也可以使用“.*”数据吗?【参考方案6】:

确保您的网址采用这种格式(大写字母替换为您自己的):

android-app://COM.YOUR.APP.IDENTIFIER/SCHEME/HOST?somegetparams

adb 工具不需要这种格式。有了上面的内容,您现在可以将它放在 src 或 href 中,如下所示:

<iframe src="android-app://COM.YOUR.APP.IDENTIFIER/SCHEME/HOST?somegetparams"> </iframe> 
<a href="android-app://COM.YOUR.APP.IDENTIFIER/SCHEME/HOST?somegetparams">LINK</a>

【讨论】:

这对我有用,谢谢伙计.. 你救了我的一天 ;) 顺便说一句,它只在android.. ios怎么样..?【参考方案7】:

在我的情况下,我删除了它的 URL 中有一个端口 8075,它可以工作

【讨论】:

谢谢,它拯救了我的一天。【参考方案8】:

./adb shell am start -n 包名/.splash.SplashActivity -d "schemeName://content"

【讨论】:

【参考方案9】:

使用 adb shell am start -W -a android.intent.action.VIEW -d "http://example.com/gizmos" com.myapp.android

它会起作用的。

【讨论】:

【参考方案10】:

感谢 Simas 的回复,我想补充一些说明:

使用此命令测试您的活动后:

adb shell am start -n com.example.simon.test/.activities.MainActivity

在将意图过滤器添加到您的 AndroidManifest.xml 文件后,您需要测试您的深层链接(行如下):

... ...

所以这是您可以用来测试的 adb 命令:

adb shell am start -W -a android.intent.action.VIEW -d "http://example.com/gizmos" com.example.packageid

adb shell am start -W -a android.intent.action.VIEW -d "http://example.com" com.example.pakageid

【讨论】:

【参考方案11】:

如果您没有权限问题,可能与 API 级别有关

【讨论】:

【参考方案12】:

改用这个意图过滤器,

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

<!-- Accepts URIs that begin with "example://gizmos” -->
<data
   android:host="gizmos"
   android:scheme="example" />
</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" />

<!-- Accepts URIs that begin with "http://www.example.com/gizmos” -->
<data 
    android:host="www.example.com"
    android:pathPrefix="gizmos"
    android:scheme="http" />
</intent-filter>

【讨论】:

以上是关于深层链接意图不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Facebook延迟深层链接不起作用

为啥这个由 facebook 生成的深层链接(applink)不起作用?

Http 302 重定向到深层链接在 Android 中不起作用

如果应用程序通过深层链接打开,共享元素转换不起作用

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

Branch.io 深层链接在我的浏览器中不起作用