参考https://developer.android.com/about/versions/marshmallow/android-6.0.html
参考https://developer.android.com/training/app-links/index.html
当我们在应用中点击一个链接,通常会提示我们选择合适的浏览器或者app去打开它。
从Android6.0开始,你可以让你的app作为对给定类型链接的默认处理者。当然,如果用户不想你的app作为默认处理者,他们可以在设置中修改。
自动处理链接需要app开发者和网页所有者的共同协作。app开发者需要通过配置来声明处理哪些链接,同时需要系统验证这些链接。网站所有者需要发布一个Digital Asset Links文件来提供验证。Handling App Links通常的步骤包括:
1、app开发者:在app的manifest文件中,创建包括网站uri的intent filter。
2、app开发者:配置app,请求验证app links。
3、网站所有者:在网站上发布一个Digital Asset Links JSON文件,用于提供验证。
一、Understand URI Request Handling
android6.0提供的app links特点,能够让你的app作为特定网站uri的默认处理者,即使用户从没有设置过默认的处理者。
当用户点击一个链接,或者程序启动一个网页uri意图,android系统按照以下顺序决定如何处理它们:
1、用户设置了此链接处理者:如果用户设置了哪个app处理,系统把网页的uri传递给此app。用户设置有两种方式:
-在曾经点击此链接弹出的app选择对话框中勾选了“总是”’;
-在设置-应用-应用链接中选择一个app,设置这个app的“app links”属性为打开这个app。
2、用户没有设置此链接处理者,并且有一个支持处理此链接的app:系统自动传递网页uri给这个app。
3、用户没有设置此链接处理者,并且有多个支持处理此链接的app:系统会显示一个app选择对话框,提示用户选择最合适的app。
二、Create an Intent Handler for URIs
App links基于Intent框架,它允许app去处理来自系统或其它app的请求。
多个app可以在intent filter中声明一样的uri模式,当用户点击一个链接并且没有设置默认的处理者时,系统会弹出app选择对话框让用户去选择。
想要让你的app处理链接,需要在manifest文件中使用intent filter来声明app需要处理的uri模式。下面的例子,声明了一个intent filter能够处理http://www.android.com和https://www.android.com:
<activity …>
<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:scheme="https" />
<data android:host="www.android.com" />
</intent-filter>
</activity>
请看上面这个例子,处理链接的intent filter中必须声明android:scheme的值为“http”、“https”或者两者,并且不能声明其它的schemes。intent filter必须声明name为android.intent.action.VIEW的action和name为android.intent.category.BROWSABLE的category。
这个manifest中的intent filter声明就让你的app和网站建立了联系,为了让系统使用你的app作为你声明的uri的默认处理者,你需要请求系统验证这种联系。请看下一节如何实现这种验证。
三、Request App Links Verification
除了使用intent filter声明你的app和网站之间的联系,你的manifest文件还需要额外声明:请求自动验证。
当这个声明之后,在你的app安装后,android系统会尝试验证你的app。如果验证成功,并且用户没有设置处理你声明的uri的app,系统自动传递这些uri请求给你的app。
系统通过对比你声明的intent filter中data元素的host name和每个网站的Digital Asset Links files (assetlinks.json)来进行验证。为了触发系统进行验证,请确保intent filter中包括android.intent.action.VIEW intent action和android.intent.category.BROWSABLE intent category。
3.1、Enabling automatic verification
为了触发系统自动验证,需要设置intent filter的android:autoVerify为true,请看下面的例子
<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>
当android:autoVerify设置为true后,android系统会自你的app安装后进行验证,验证所有声明的uri和对应的网站。如果你声明的所有uri都验证成功,系统会把你的app作为这些uri的默认处理者。
3.2、Supporting app linking for multiple hosts
系统会验证intent filter中声明的每个host和每个网站中的Digital Asset Links,如果任何一组验证失败,你的app都不会作为任何一个你声明的uri的默认处理者。请看下面的例子,如果在https://www.domain1.com/.well-known/assetlinks.json和and https://www.domain2.com/.well-known/assetlinks.json都没有找到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="http" android:host="www.domain1.com" />
<data android:scheme="https" android:host="www.domain1.com" />
</intent-filter>
</activity>
<activity android:name=”SecondActivity”>
<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="https" android:host="www.domain2.com" />
</intent-filter>
</activity>
</application>
3.3、Supporting app linking for multiple subdomains
Digital Asset Links协议把subdomains看作是唯一的、单独的host。如果你的intent filter包括www.example.com和mobile.example.com,你必须为每个subdomain提供一份单独的assetlink.json。请看下面的例子,只有网站所有者在https://www.example.com/.well-known/assetlinks.jsonhe和https://mobile.example.com/.well-known/assetlinks.json都提供了合法的assetlinks.json文件,验证才能通过。json文件必须通过加密的HTTPS连接获取,请看下一节。
<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="http" android:host="www.example.com" />
<data android:scheme="https" android:host="mobile.example.com" />
</intent-filter>
</activity>
</application>
四、Declare Website Associations
要使得验证成功,网站所有者必须声明和app的联系。网站所有者通过持有一个名为assetlinks.json的Digital Asset Links JSON文件来声明与一个app的联系,它在domain的well-known位置:https://domain[:optional_port]/.well-known/assetlinks.json。
注意:系统通过加密的HTTPS协议来验证json文件,所以不管intent filter中是否声明了https,请确保json文件能够通过HTTPS连接来获取。
Digital Asset Links JSON文件声明了与此网站关联的app,下面的示例assetlinks.json文件允许包名为com.example的app打开链接:
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.example",
"sha256_cert_fingerprints":
["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
}
}]
json文件使用package_name和sha256_cert_fingerprints来标示一个app。
package_name:为app的包名;
sha256_cert_fingerprints:是app签名证书的SHA256 fingerprints,它支持多个fingerprints,用于支持你的app的多个版本(debug、release)。
你可以使用java的keytool命令来获取fingerprints:$ keytool -list -v -keystore my-release-key.keystore。
4.1、Associating a website with multiple apps
一个网站可以使用一份assetlinks.json文件来声明与多个app的联系。下面的文件位于https://www.example.com/.well-known/assetlinks.json,它单独声明了与两个app的联系:
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "example.com.puppies.app",
"sha256_cert_fingerprints":
["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
}
},
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "example.com.monkeys.app",
"sha256_cert_fingerprints":
["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
}
}]
不同的app能够处理同一个host下面的不同的资源,比如app1声明处理https://example.com/articles的intent filter,app2声明处理https://example.com/videos的intent filter。
注意:与同一个网站建立联系的多个app,可以用相同/不同的证书签名。
4.2、Associating multiple websites with a single app
多个网站可以使用单独的assetlinks.json文件声明与同一个app建立联系。下面的两个assetlinks.json文件显示了如果让domain1、domain2都与app1建立联系。
https://www.domain1.com/.well-known/assetlinks.json
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.mycompany.app1",
"sha256_cert_fingerprints":
["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
}
}]
https://www.domain2.com/.well-known/assetlinks.json
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.mycompany.app1",
"sha256_cert_fingerprints":
["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
}
}]
五、Test App Links
当实现了上述app linking功能后,需要进行测试,确保android系统能够关联你的app和网站、处理uri请求。
5.1、Confirm the list of hosts to verify
首先,列出系统需要验证的与你的app关联的网站uri,列出包括如下属性、元素的intent filter中的uri:
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host=“一个domain uri" />
然和使用列出的uri去检查每个host、subdomain是否有一个Digital Asset Links JSON文件。
5.2、Confirm the Digital Asset Links files
使用Digital Asset Links API去检查每个网站的json文件是否存在并定义正确,将下方的source.web.site替换成你的app关联的网站,然后在浏览器输入即可验证。
https://digitalassetlinks.googleapis.com/v1/statements:list?
source.web.site=https://<domain1>:<port>&
relation=delegate_permission/common.handle_all_urls
比如输入:
https://digitalassetlinks.googleapis.com/v1/statements:list?
source.web.site=https:www.google.com&
relation=delegate_permission/common.handle_all_urls
可以看到如下结果,说明包名为com.google.android.calendar的app关联了www.google.com。
{
"statements": [
{
"source": {
"web": {
"site": "https://www.google.com."
}
},
"relation": "delegate_permission/common.handle_all_urls",
"target": {
"androidApp": {
"packageName": "com.google.android.calendar",
"certificate": {
"sha256Fingerprint": "F0:FD:6C:5B:41:0F:25:CB:25:C3:B5:33:46:C8:97:2F:AE:30:F8:EE:74:11:DF:91:04:80:AD:6B:2D:60:DB:83" }
}
}
}
],
"maxAge": "59.998761836s",
"debugString": "********************* ERRORS *********************\nNone!\n********************* INFO MESSAGES *********************\n* Info: The following statements were considered when processing the request:\n\n---\nSource: Web asset with site https://www.google.com. (which is equivalent to 'https://www.google.com')\nRelation: delegate_permission/common.handle_all_urls\nTarget: Android app asset with package name com.google.android.calendar and certificate fingerprint F0:FD:6C:5B:41:0F:25:CB:25:C3:B5:33:46:C8:97:2F:AE:30:F8:EE:74:11:DF:91:04:80:AD:6B:2D:60:DB:83\nWhere this statement came from:\n Origin of the statement: Web asset with site https://www.google.com. (which is equivalent to 'https://www.google.com')\n Include directives followed (in order):\n \u003cNone\u003e\nMatches source query: Yes\nMatches relation query: Yes\nMatches target query: Yes\n\n--- End of statement list. ---\n\n\n"
}
5.3、Testing a web URI intent
在确认了与你的app关联的网站并验证了网站的json文件之后,把app安装在你的手机上。然后等待至少20秒,使得异步的验证过程得以完成。
然后,使用以下命令判断系统是否已经验证了你的app并正确设置了link handling机制:
adb shell am start -a android.intent.action.VIEW \
-c android.intent.category.BROWSABLE \
-d "http://<domain1>:<port>"
5.4、Check link policies
你还可以检测当前系统的link handling设置,使用以下命令可以获取当前系统对所有app的link handling设置:
adb shell dumpsys package domain-preferred-apps
--or--
adb shell dumpsys package d
命令行返回的结果类似:
App linkages for user 0:
Package: com.android.vending
Domains: play.google.com market.android.com
Status: always : 200000002
结果展示了对于哪个用户而言,哪个app关联了哪个网站。
Package:app的包名
Domains:以空格分隔的此app能够处理的uri
Status:此app当前的link handling设置,如果通过了验证并且manifest文件包括android:autoVerify=“true”,会显示“always”。后面的16进制数与系统记录用户app linkpage设置有关,不能表明验证的结果。
注意:如果用户在验证完成之前更改app link设置,那么不管验证结果,你都会看到成功。即使失败,也不会影响用户使用此app打开uri。这是因为用户设置优先于程序验证。
5.5、Test example
看下面的intent filters,
<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="http" android:host="www.example.com" />
<data android:scheme="https" android:host="mobile.example.com" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="www.example2.com" />
</intent-filter>
</activity>
<activity android:name=”SecondActivity”>
<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="account.example.com" />
</intent-filter>
</activity>
<activity android:name=”ThirdActivity”>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" android:host="map.example.com" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="market" android:host="example.com" />
</intent-filter>
</activity>
</application>
根据Confirm the list of hosts to verify这一小节内容,其中只有几个host会被系统验证:
www.example.com
mobile.example.com
www.example2.com
account.example.com
不会被验证的原因是:
map.example.com (没有android.intent.category.BROWSABLE)
market://example.com (没有“http”或者“https” scheme)
六、广告
- 手机如何连电脑?
- 如何与电脑互发文件?
- 如何与电脑互发文字?
- 如何推送通知到电脑?
- 电脑如何远程控制手机的相机?
快牙网传——全部搞定!
不想试试吗?
在豌豆荚等应用商店搜索“快牙网传“,或立即下载 Apk,也可以扫码下载。