Android M的App Links实现详解
谷歌2015年的I/O大会上宣布了一个新特性:允许开发者将app和他们的web域名关联。这一举措是为了最小化用户遇到“打开方式”对话框的概率。
比如,我们安装了两个推ter应用 – 官方的和Falcon Pro。当你在某个地方点击了推ter URL的时候,你会看到如下的对话框:
但是在安卓M中,如果一个app明确的指定了App链接-这个对话框将不复存在。点击一个链接将立即打开官方的app,没有第三方app的机会,更不会打开一个浏览器。
在上图的例子中,当你点击了那个链接,安卓系统会检查是否有一个app可以处理推ter.com URL,然后跟推ter.com核对哪个app(s)可以处理该域名的链接,这样我们就能避免影响用户。
注意安卓并不会在点击链接的时候才核对这些链接,因此在安卓决定使用哪个app之前并不会有网络阻塞。关于这点后面有更多讨论。
虽然这会使安卓更方便- 多数情况下,你确实希望点击一个链接打开的是最合适的那个app- 但是对于那些喜欢使用第三方app的人来说,似乎是一件坏事。不过这种行为可以在Android M的系统设置中关掉。
app开发者如何实现App Links
实现的细节可以在Android Developers' Preview 网站上找到。
如果你有一个需要处理链接(比如example.com)的app,你应该:
- 有上传文件到example.com根路径的权限,如果没有,你无法让你的app成为这些链接的默认打开方式。
- 在build.gradle文件中设置compileSdkVersion 'android-MNC'。
- 为每个这样的<intent-filter>标签
<intent-filter> <data android:scheme="http" /> ... </intent-filter>
添加属性android:autoVerify="true"。http也可以是https。
注:这里对filter的写法略去了很多,其实官网(上面的那个链接)有完整的示例:
<activity ...> <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="http" android:host="www.android.com" /> <data android:scheme="https" android:host="www.android.com" /> </intent-filter> </activity>
认证是以主机名为单位的而不是以intent filter为单位的,因此从技术上讲,并不需要为每个标签都添加该属性,但是添加了也不会出什么问题。
创建JSON文件
为了能让安卓可以认证,你的app需要被允许使用app链接行为,为此,需要提供一个JSON文件,JSON文件中需要包含app的ID以及APK的公钥证书。
这个文件必须包含一个JSON数组,数组中可以有一个或者多个对象,每个对象对应一个你想认证的app ID:
[ { "relation": ["delegate_permission/common.handle_all_urls"], "target": { "namespace": "android_app", "package_name": "com.example.myapp", "sha256_cert_fingerprints": ["6C:EC:C5:0E:34:AE....EB:0C:9B"] } } ]
比如,你现在有一个com.example.myapp的发行版app,同时还有一个叫com.example.myapp.beta的beta版app,你可以通过在数组中设置两个对象来允许两者都可以接受认证,每个对象带有各自的app ID和公钥值。
注意,这个文件的验证是非常严格的:数组中的每个对象都必须和上面的那个一模一样。在数组中添加了任意其他的对象,或者对象中有额外的属性都会导致整个验证失败。- 即便这个app对象是有效的。
为了防止为同一个构建注册了不同的key,貌似一个app可以指定多个SHA256指纹证书,不管怎样,指纹证书可以通过如下方式获得:
1 </div> </td> | </tr> </tbody> </table> </div> </div> echo | keytool - list - v - keystore app . keystore 2 > / dev / null | grep SHA256 : 上传JSON文件创建完文件之后,你需要上传它同时保证它可以使用这个URL访问http://example.com/.well-known/statements.json。 目前这个URL是http的,最终的M版本将只允许通过HTTPS访问该URL。 URL的scheme和<intent-filter>标签中的android:scheme值是互不相干的,即使你有一个只接受HTTPS URLs的filter,认证URL仍然需要通过HTTP访问。 在了解了安卓如何使用这些信息之后,我们来看看如果debug这个过程。 Android M是如何实现App Links的App链接认证涉及到安卓系统的两个组建:Package Manager和Intent Filter Verifier。 PackageManager是一个无处不在的标准组建 – 它负责验证所安装的apk是否有效,授予app权限,另外还可以通过它知道系统上安装了些什么app。 而Intent Filter Verifier则是Android M上才有的新玩意儿。这个组建负责获取链接指向的JSON认证,解析它,验证它,然后将报告返回给PackageManger。 虽然这个组建不是用户轻易就能替换的,但似乎系统中只能有一个活动状态的Intent Filter Verifier – 想要注册成为一个verifier,必须要有android.permission.INTENT_FILTER_VERIFICATION_AGENT 权限,而这个权限只有签名了系统密钥的app才能得到。 你可以通过如下的命令查看当前激活的intent filter verifier: adb shell dumpsys package ifv
|