Android使用自定义URI进行深层链接

12

我在我的清单文件中定义了以下内容:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.app.package">
...
    <activity
        android:name="app.myActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait">
        <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="www.example.com"
                android:pathPrefix="/gizmos"
                android:scheme="http" />
            <!-- note that the leading "/" is required for pathPrefix-->
            <!-- Accepts URIs that begin with "example://gizmos”-->
            <data
                android:host="gizmos"
                android:scheme="example" />
        </intent-filter>
    </activity>
 ...

而且我已经将我的onCreate()定义为:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = getIntent();
    Uri data = intent.getData();
    if (data != null) {
        Log.d("URI",data.toString());            
    }
}

这符合Android文档:Android深度链接
问题是: 如何测试URI深度链接?根据文档,我可以运行以下命令:

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

但是会出现以下错误:

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

我还尝试过使用活动名称和引用、启动器活动以及将包留空的shell。唯一一个可以正常工作的是:

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

即使我成功了,也不能保证它在其他应用程序中能够工作。自定义URI(例如example://gizmos)在其他应用程序中,如Gmail和WhatsApp中无法点击 - 因此,在Android生态系统中进行测试也存在问题。 此堆栈溢出问题的答案不可接受,因为它没有回答问题,而只是鼓励使用http://版本,我希望example://方案能够正常工作。

请不要试图在一个帖子中塞入多个问题,即使您认为它们是相关的。 - Alex P.
3个回答

23

ADB正在发送intent,只是当您想要多个链接类型时,您的应用程序必须具有单独的意图过滤器:

    <activity
        android:name="app.myActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait">
        <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" />
            <data
                android:host="www.example.com"
                android:pathPrefix="/gizmos"
                android:scheme="http" />
            <!-- note that the leading "/" is required for pathPrefix-->                
        </intent-filter>
    </activity>

以下两个 ADB 命令都可正常工作:

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

但我在自定义 URI 添加更多元素时遇到问题(例如:example://gizmos?data1='hello'&data2='world',"&" 被截断了)。

显然这并不能解决这些链接在其他应用程序中无法点击的问题,例如 WhatsApp 和 Gmail...但在其他平台上可以点击。


4
谢谢!在 Android 的参考文档中,这一点非常不清楚! - swooby
3
有时我很惊讶一家公司为什么可以如此有名,但他们的文档却如此晦涩难懂或误导人。不过这份文档确实很有帮助。 - superuserdo
如何从浏览器打开example://gizmos?命令adb shell am start -W -a android.intent.action.VIEW -d "example://gizmos"可以正常工作。 - Shajeel Afzal
我认为这取决于浏览器 - 我知道例如(从历史经验,可能已经改变)WhatsApp只是不会转发深度链接 - 或者说,在广播时不会将它们传递。您可能想在这里寻找潜在的解决方案:https://dev59.com/9lsW5IYBdhLWcg3wSFfW - Quintin Balsdon

7
作为其他答案所提到的,安卓框架要求您为启用应用程序中的每个深度链接声明单独的意图过滤器。这就是您收到错误的原因。
此外,您可以使用深度链接测试应用程序直接在安卓上测试深度链接,而不是使用adb。

https://play.google.com/store/apps/details?id=com.manoj.dlt

不需要提及任何包名或组件名。只需输入实际的深度链接并触发。

我曾经使用过深度链接,并且个人认为通过adb进行测试很耗时间。因此,我创建了这个应用程序,直接测试深度链接,并将其放在Play商店上。


1

有一个由airbnb开发的DeepLinkDispatch库。它将解决您处理DeepLink的所有烦恼。

该库具有以下特点:

  • 易于使用
  • 处理所有类型的自定义URL
  • 处理链接参数
  • 处理查询参数

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接