【问题标题】:How to implement Android App Links with wildcard domains?如何使用通配符域实现 Android 应用链接?
【发布时间】:2016-09-21 12:43:39
【问题描述】:

Android 有a guide about how to implement app links.,也就是说,如果我的应用程序声明它处理某些网络链接,并且我尝试在任何其他应用程序中打开此链接,系统会拦截它并将用户直接带到我的应用程序,而不是浏览器,以便我可以直接在我的应用程序中显示相关内容。非常方便。

我在指南中缺少两件事:

  1. 如何使用通配符域实现应用链接。我希望我的应用能够处理指向 *.example.com 的链接,即指向 example.com 的 subdomains 的所有链接(test.example.com、something.example.com 等);

  2. 如何实现仅指向我网站上特定路径的应用链接。例如我想拦截 test.example.com/something,而不是 test.example.com/other。第一个应该出现在我的应用中,另一个应该出现在我的浏览器中;

The corresponding iOS guide 表明 iOS 可以处理这两种情况(尽管通配符部分在文档中并不清楚,我不得不向 Apple 支持人员澄清,您需要将关联文件放在根域中,而不是子域中)。

Android 应用链接能否处理通配符域和路径子集?

【问题讨论】:

  • 关于通配符域/主机,我在此处的意图过滤器源中看到一些对主机通配符的引用 - android.googlesource.com/platform/frameworks/base/+/master/core/…。在得出无法完成的结论之前,也许有人可以看看它,看看它是否与这个问题的上下文相关。
  • 如果您指的是mWildAuthorityEntry,那么match() 的实现似乎不正确。但是,除此之外,在<intent-filter>/IntentFilter 中使用通配符功能是必要的,但还不够。过滤器可能支持通配符,但应用链接不支持。
  • 我不知道该文档最近是否有更新,但我从上面发布的链接中了解到,它确实支持数据标签上主机属性的通配符

标签: android ios applinks


【解决方案1】:
  1. 更新:现在您可以使用数字资产链接处理通配符域

aurilio explained it in his newer answer

整个过程记录在这里:https://developer.android.com/training/app-links/verify-site-associations

总结一下,现在你可以在host标签中使用通配符你必须上传一个json文件assetlinks.json 到您的 root 域上的 /.well-known 文件夹/路由。

或者,如果您使用通配符声明您的主机名(例如 *.example.com),您必须在根主机名(example.com)发布您的assetlinks.json 文件

您还需要添加属性 android:autoVerify="true" 到您的intent-filter 标签。

这是 Android 端的完整示例:

<application>
  <activity android:name=”MainActivity”>
    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="https" android:host="*.example.com" />
    </intent-filter>
  </activity>
</application>

这是 2016 年的上一个答案: 不幸的是,Android 似乎无法处理通配符域

如果您查看 data 标记 (https://developer.android.com/guide/topics/manifest/data-element.html) 的 API 指南,您会看到他们提到通配符可用于 pathPattern 和 mimeType,但不适用于主机。

事实是,正如 CommonsWare 在关于该主题的另一篇文章 (https://stackoverflow.com/a/34068591/4160079) 中所解释的那样,

在安装时会检查域,除了通过发布带有新清单的新版本应用程序之外,无法添加新域。

因此,您必须手动列出所有可用的子域,并在启动新子域时更新应用程序。

以下是您声明多个子域的方式:

 <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" />
        <data android:scheme="http" />
        <data android:host="subdomain1.example.com" />
        <data android:host="subdomain2.example.com" />
        <data android:host="subdomain3.example.com" />
    </intent-filter>
</activity>

  1. 是的,您只能处理路径的子集

同样的想法,只需使用 path 属性列出您想要的路径(再次,请参阅上面的 data 标签 API 指南)。

如果您使用查询字符串或路径参数,最好使用 pathPrefix

如有必要,您可以在此处使用通配符,方法是选择 pathPattern

URI 的路径部分,必须以 / 开头。 path 属性指定与 Intent 对象中的完整路径匹配的完整路径。 pathPrefix 属性指定仅与 Intent 对象中路径的初始部分匹配的部分路径。 pathPattern 属性指定与 Intent 对象中的完整路径匹配的完整路径,但它可以包含以下通配符: 星号 ('') 匹配从 0 到多次出现的前一个字符的序列。 一个句点后跟一个星号 (".") 匹配任何 0 到多个字符的序列。

这里有几个例子:

 <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" />
        <data android:scheme="http" />
        <data android:host="subdomain1.example.com" />
        <data android:host="subdomain2.example.com" />
        <data android:host="subdomain3.example.com" />
        <data android:path="/path1" /> <!-- matches /path1 only -->
        <data android:pathPrefix="/path2" /> <!-- matches /path2, /path2/something or also /path2?key=value etc... -->
        <data android:pathPattern="/wild.*" /> <!-- matches /wild, /wild3, /wilderness etc... -->
    </intent-filter>
</activity>

【讨论】:

  • 查看我对通配符域问题的评论。似乎 Intent 过滤器源码中有一些通配符相关的代码。这相关吗?
  • 您提到的与通配符相关的代码适用于自定义方案。但是,对于 App Links,安装后会立即执行每个域的验证。
  • 主机也可以使用通配符。根据您分享的链接。
  • @MayurMore 你是对的 - 自从我发布我的答案以来,这似乎已经更新。我将编辑我的答案 - 同时,我建议查看 aurilio 的答案
  • android:autoVerify="true" 仅适用于 api 23
【解决方案2】:

Android 无法处理通配符域(根据他们今天的文档),但是,这将回答您关于包含和排除某些 /paths 的查询。

为 URL 的like 实现深层链接-

http://example.com/gizmos?1234, 
http://example.com/gizmos/1234,
http://example.com/gizmos/toys/1234,
etc.

您的 XML 应该如下所示-

<activity android:name="com.example.android.GizmosActivity" android:label="@string/title_gizmos" > 
    
    <intent-filter android:label="@string/filter_title_viewgizmos">
        <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:scheme="example" android:host="gizmos" />
    </intent-filter>
    <intent-filter android:label="@string/filter_title_viewgizmos">
        <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://example.com/gizmos” -->
        <data android:scheme="http" android:host="example.com" android:pathPrefix="/gizmos" /> 
    </intent-filter> 
</activity>

现在考虑到您能够实现这一点,以下是您如何限制对部分应用内容的访问-

<?xml version="1.0" encoding="utf-8"?>
<search-engine xmlns:android="http://schemas.android.com/apk/res/android">
    <noindex uri="http://example.com/gizmos/hidden_uri"/>
    <noindex uriPrefix="http://example.com/gizmos/hidden_prefix"/>
    <noindex uri="gizmos://hidden_path"/>
    <noindex uriPrefix="gizmos://hidden_prefix"/>
</search-engine>

还有清单部分-

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.Gizmos">
    <application> 
        <activity android:name="com.example.android.GizmosActivity" android:label="@string/title_gizmos" >
            <intent-filter android:label="@string/filter_title_viewgizmos">
            <action android:name="android.intent.action.VIEW"/> ... 
        </activity> 
            <meta-data android:name="search-engine" android:resource="@xml/noindex"/> 
    </application>
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

有关此示例的更多详细信息和解释,您可以查看-

Android Deep Linking

希望它有所帮助,快乐编码

【讨论】:

  • 我在这里没有看到任何关于通配符域的信息。
  • Android 无法处理通配符域,但是,这是为了包含和排除某些 /paths
【解决方案3】:

引用自:https://developer.android.com/training/app-links/verify-site-associations.html

或者,如果您使用通配符声明您的主机名(例如 *.example.com),您必须在根主机名 (example.com) 处发布您的assetlinks.json 文件。例如,只要assetlinks.json 文件发布在 https://example.com/ .well-known/assetlinks.json:

<application>
  <activity android:name=”MainActivity”>
    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="https" android:host="www.example.com" />
      <data android:scheme="https" android:host="mobile.example.com" />
    </intent-filter>
  </activity>
</application>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-15
    • 1970-01-01
    • 2020-04-07
    相关资源
    最近更新 更多