H5唤起App技术DeepLink方案总结
唤醒方式:
1、URL Schemes
2、android appLink
3、chrome intent
DeepLink实践URL Schemes方式
需要在AndroidManifest.xml文件进行配置
<activity
android:name=".ui.activity.SplashActivity"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/NormalSplash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!--DeepLink h5唤醒app配置-->
<intent-filter>
<!--ACTION_VIEW:支持被检索-->
<action android:name="android.intent.action.VIEW" />
<!--CATEGORY_DEFAULT:响应隐式Intent-->
<category android:name="android.intent.category.DEFAULT" />
<!--CATEGORY_BROWSABLE:可被Web浏览器唤起-->
<category android:name="android.intent.category.BROWSABLE" />
<!--data:一个或多个,必须含有scheme标签,决定被唤起的URL格式-->
<data
android:host="app.puxinwangxiao.com"
android:scheme="pxwxstudent" />
<!--
<data
android:host="app.puxinwangxiao.com"
android:scheme="pxwxstudent"
android:pathPrefix="/pxwx"/>
<data
android:host="app.puxinwangxiao.com"
android:scheme="pxwxstudent"
android:path="/pxwx/user"/>
-->
</intent-filter>
</activity>
注意:
- App可以配置多个支持唤起的Activity
- Activity可以支持被多个URL唤起
- 若一个App配置了多个支持唤起的Activity,它们的scheme和host一般一致,然后通过path、pathPrefix等进行定向区分
被唤起后解析URL数据
Uri数据的解析可以在Activity中通过getIntent().getData()
实现
@Override
public void onCreate(Bundle savesInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
// 尝试获取WebApp页面上过来的URL
Uri uri = getIntent().getData();
if (uri != null) {
// scheme部分
String scheme = data.getScheme();
// host部分
String host = data.getHost();
// 访问路径
String path = data.getPath();
//参数
Set<String> paramKeySet = data.getQueryParameterNames();
}
}
在h5页面上,通过如下方式使用
<!--1.通过a标签打开,点击标签是启动-->
<!-- 注意这里的href格式 -- >
<a href="pxwxstudent://app.puxinwangxiao.com">open android app</a>
<!--2.通过iframe打开,设置iframe.src即会启动-->
<iframe src="pxwxstudent://app.puxinwangxiao.com"></iframe>
<!--3.直接通过window.location 进行跳转-->
window.location.href="pxwxstudent://app.puxinwangxiao.com";
在原生App中唤起通过Intent方式
Intent intent = new Intent();
intent.setData(Uri.parse("pxwxstudent://app.puxinwangxiao.com/"));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
DeepLink实践Android AppLink方式
Android AppLink介绍
- Android M以上版本可以通过AppLinks,让用户在点击一个链接时跳转到App的指定页面
- 前提是这个App已经安装并经过验证
- App Links的最大作用,就是可以避免从页面唤醒App时出现的选择浏览器选项框;
- 前提是必须注册相应的Scheme,就可以实现直接打开关联的App
Android App Links有以下几点好处:
- 安全性/特殊性:由于Android App Links使用了HTTP/HTTPS URL的方式向开发者的服务器进行连接认证,所以其他应用无法使用我们的链接
- 无缝的用户体验:当用户未安装我们的应用时,由于使用的是HTTP/HTTPS URL,会直接打开一个网页,我们可以在这个网页中展示应用介绍等,而不是显示404或者是其他错误页面
- 支持Instant Apps:可以使用App Links直接打开一个未安装的Instant App
- 支持Google Search或其他浏览器:用户可以直接在Google Search/Google Assistant/手机浏览器/屏幕搜索中直接通过点击一个URL来打开我们的指定页面
Android AppLink集成
https://developer.android.com/studio/write/app-link-indexing.html
创建intent filter
我们在此处先假设用户是通过http://resource.puxinwangxiao.com/pxwx
来打开我们的应用的。
Android Studio 2.3以后提供了App Links Assistant
来帮助开发者快速在AndroidManifest.xml
中创建需要配置的intent filter
,使用App Links Assistant
有以下几个步骤:
- 点击Android Studio的菜单栏中的 Tools > App Links Assistant
- 点击Open URL Mapping Editor,然后在对话框底部点击+去添加一个新的URL mapping
- 在弹出的Add URL Mapping对话框中输入对应的内容,包括Host、Path、Activity,输入完成后点击OK
注:App Link 支持多个域名
使用App Links Assistant
在manifest文件中自动生成的内容如下:
<activity
android:name=".ui.activity.SplashActivity"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/NormalSplash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</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:scheme="http"
android:host="resource.puxinwangxiao.com"
android:path="/pxwx" />
</intent-filter>
</activity>
检查URL Mapping是否配置正确
App Links Assistant
提供了检查URL Mapping是否配置正确的快捷方式,操作如下:
点击Open URL Mapping Editor
,然后在Check URL Mapping
对话框中输入URL,当输入一个能够成功匹配到Acitivty的URL后,输入框下方会显示This URL maps to xxxxx(app)
处理App Links进入应用的场景
通过App Links Assistant
-> Select Activity
选择之前配置的URL对应的Activity,点击Insert Code即可在onCreate方法中插入获取从App Links跳转而来的URL的代码,生成代码如下
// ATTENTION: This was auto-generated to handle app links.
Intent appLinkIntent = getIntent();
String appLinkAction = appLinkIntent.getAction();
Uri appLinkData = appLinkIntent.getData();
检查assetlinks.json是否上传成功
为了在应用安装成功后,系统能自动验证该应用是否有权使用对应的域名,系统会向http://resource.puxinwangxiao.com/.well-known/assetlinks.json
请求数据,根据获取到的文件内容,验证应用域名的合法性。
通过App Links Assistant
-> Open Digital Asset Links File Generator
-> Generate Digital Asset Links file
的方式生成assetlinks.json
文件,然后将该文件放置到正确的域名地址中。
通过App Links Assistant
-> Open Digital Asset Links File Generator
-> Generate Digital Asset Links file
-> Link and Verify
可以检测是否正确的在服务器中放置配置文件,检测成功的话,显示如下图:
我这里检测后提示Network error.
不影响,主要是http://resource.puxinwangxiao.com/.well-known/assetlinks.json
能访问到json文件
如果要让网站和不同的应用关联起来
网站可以在同一个assetlinks.json
文件里声明和不同的app的关系。下面这个文件列出了两个声明,这两个声明声明了网站和两个应用之间的关联,这个文件位于https://app-pre.puxinwangxiao.com/.well-known/assetlinks.json
。
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.pxwx.student",
"sha256_cert_fingerprints":
["BD:EF:57:3D:01:D0:32:79:6E:32:73:18:32:E2:36:B9:35:1B:9C:7D:0F:F0:B0:A9:BE:91:18:CE:27:1A:D8:4C"]
}
},
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.pxwx.assistant",
"sha256_cert_fingerprints":
["BD:EF:57:3D:01:D0:32:79:6E:32:73:18:32:E2:36:B9:35:1B:9C:7D:0F:F0:B0:A9:BE:91:18:CE:27:1A:D8:4C"]
}
}]
注意:path、 pathPrefix、 pathPattern 之间的区别
例如:https://app-pre.puxinwangxiao.com/assistant/download.html
- path 用来匹配完整的路径,这里将 path 设置为
/assistant/download.html
才能够进行匹配 - pathPrefix 用来匹配路径的开头部分,拿上面的 Uri 来说,这里将 pathPrefix 设置为
/assistant
就能进行匹配了 - pathPattern 用表达式来匹配整个路径,这里需要说下匹配符号与转义
Chrome Intent方式实现从浏览器启动应用
在很多应用中需要我们从浏览器中直接启动应用,大多数采用的是上面提到的第一种scheme的方式,问题是如果手机中没有应用,该url会跳转到一个错误的界面。
Google官方在chrome中推出了一种Android Intents的方式来实现应用启动,通过在iframe中设置src为
intent:HOST/URI-path // Optional host
#Intent;
package=[string];
action=[string];
category=[string];
component=[string];
scheme=[string];
end;
Mainfest文件中定义要启动的Activity
<activity
android:name=".ui.activity.SplashActivity"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@style/NormalSplash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</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="app.puxinwangxiao.com"
android:scheme="pxwxstudent" />
</intent-filter>
</activity>
定义一个a标签为
<a href="intent://app.puxinwangxiao.com/#Intent;scheme=pxwxstudent;package=com.xxx.xxx;end">open Android App</a>
在浏览器中点击a标签,就可以启动应用程序的对应activity了.
如果手机中没有相应的应用,防止跳转到错误页面,将a标签设置为
<a href="intent://app.puxinwangxiao.com/#Intent;scheme=pxwxstudent;package=com.xxx.xxx;S.browser_fallback_url=https://www.puxinwangxiao.com;end">open Android App</a>
这样如果没有对应应用,该链接就会跳转到S.browser_fallback_url
指定的url上。
总结:
URL Scheme兼容性
URL Scheme只需要原生App开发时注册Scheme即可,用户点击此类链接时,会自动唤醒App,并借助URL Router机制跳转到指定页面。
URL Scheme兼容性高,但却存在许多限制:
- 国内各个厂商浏览器差异很大,当要被唤醒的目标App未安装时,这个链接很容易出错
- 当注册有多个Scheme相同的时候,目前是没有办法区分的
- 不支持从其他App中的UIWebView中跳转到目标App
- 被部分主流平台禁止,微信、微博、QQ浏览器、手机百度中都已经被禁止使用
由于这些限制的存在,安卓发布了自己的第二套方案:Android的App Links
App Links兼容性
- App links在国内的支持还不够,部分安卓浏览器并不支持跳转至App,而是直接在浏览器上打开对应页面
- 系统询问是否打开对应App时,假如用户选择“取消”并且选中了“记住此操作”,那么用户以后就无法再跳转App
chrome intent兼容性
- Google通过chrome浏览器启动的优化方案
- 很多第三方浏览器会拦截掉chrome intent启动应用的请求
三种方案都有各自的兼容性,这几项技术是基于系统平台的,每个系统版本的迭代后,配置方式都会有新的变化,国内的第三方平台openinstall也提供了专项功能,毕竟是专门做这个的,兼容性也都经受过市场考验,可以参考下。
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/30/h5-summarise-app-technology-deeplink-solution-summary/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论