Arkts进阶<应用间跳转 - Deep Linking>
Arkts进阶<应用间跳转 - Deep Linking>
在实际开发过程中,会遇到需要外跳其他三方应用的情况,我们会用到App Linking和Deep Linking。这里讲解Deep Linking 跳转实现方式。
跳转逻辑
采用Deep Linking进行跳转时,系统会根据接口中传入的uri信息,在本地已安装的应用中寻找到符合条件的应用并进行拉起。当匹配到多个应用时,会拉起应用选择框。
跳转原理
Deep Linking基于隐式Want匹配机制中的uri匹配来查询、拉起目标应用。
跳转条件
目标应用(需要跳转的三方应用)需要在module.json5配置文件中配置skills标。这里做演示,获取目标应用信息方式,请查看<应用间跳转 - 判断应用是否可访问>
{
"module": {
"abilities": [
{
"skills": [
// entities和actions是可以缺省的
{
"entities": [
"entity.system.home"
],
"actions": [
"ohos.want.action.home"
]
},
{
"actions": [
// actions不能为空,actions为空会造成目标方匹配失败。
"ohos.want.action.viewData"
],
"uris": [
{
// scheme必选,可以自定义,以link为例,需要替换为实际的scheme
"scheme": "link",
"host": "www.example.com",
"port":"80",
"path":"path",
"type": "text/*",
"linkFeature": "Login"
}
]
} // 新增一个skill对象,用于跳转场景。如果存在多个跳转场景,需配置多个skill对象。
]
},
],
}
}
skills:
1、actions:标识能够接收的Action值集合,取值通常为系统预定义的action值,也允许自定义。一个skill中不建议配置多个action,否则可能导致无法匹配预期场景。
2、entities:标识能够接收的Entity值的集合。一个skill中不建议配置多个entity,否则可能导致无法匹配预期场景。
3、uris:标识与Want中URI(Uniform Resource Identifier)相匹配的集合。
4、permissions:标识当前UIAbility或ExtensionAbility组件的权限信息。其他应用访问该组件时,需要申请相应的权限。一个数组元素为一个权限名称,不超过255字节。
5、domainVerify:标识是否开启域名校验。- true:表示开启域名校验。- false:表示不开启域名校验。
uris:
1、scheme:标识URI的协议名部分,常见的有http、https、file、ftp等。(从API 18开始,该标签在参与隐式Want匹配时不区分大小写。)uris中仅配置type时可以缺省,缺省值为空,否则不可缺省。可以理解为简单实用跳转功能时,这个是必须的,以下都是可以缺省的。
2、host:标识URI的主机地址部分,该标签只有当scheme配置时才生效。
3、port:标识URI的端口部分。(如http默认端口为80,https默认端口是443,ftp默认端口是21。该标签只有当scheme和host都配置时才生效。)
4、linkFeature:标识URI提供的功能类型(如文件打开、分享、导航等),用于实现应用间跳转。取值为长度不超过127字节的字符串,不支持中文。同一Bundle中声明的linkFeature数量不能超过150个。
5、path | pathStartWith | pathRegex:标识URI的路径部分,path、pathStartWith和pathRegex配置时三选一。path标识URI与want中的路径部分全匹配,pathStartWith标识URI与want中的路径部分允许前缀匹配,pathRegex标识URI与want中的路径部分允许正则匹配。该标签只有当scheme和host都配置时才生效。
6、type:标识与Want相匹配的数据类型,使用MIME(Multipurpose Internet Mail Extensions)类型规范和UniformDataType类型规范。可以与scheme同时配置,也可以单独配置。
7、utd:标识与Want相匹配的标准化数据类型,适用于分享等场景。
8、maxFileSupported:对于指定类型的文件,标识一次能接收或打开的最大数量,适用于分享等场景,需要与utd配合使用。
拉起方应用实现应用跳转
1、使用openLink实现
在openLink接口的link字段中传入目标应用的URL信息,并将options字段中的appLinkingOnly配置为false。
let link: string = 'link://www.example.com'; // 此处为实际应用链接
let openLinkOptions: OpenLinkOptions = {
appLinkingOnly: false
};
try {
context.openLink(link, openLinkOptions)
.then(() => {
hilog.info(DOMAIN_NUMBER, TAG, 'openLink success.');
}).catch((err: BusinessError) => {
hilog.error(DOMAIN_NUMBER, TAG, `openLink failed. Code is ${err.code}, message is ${err.message}`);
});
} catch (paramError) {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to start link. Code is ${paramError.code}, message is ${paramError.message}`);
}
})
这里需要注意的是:单独使用scheme是无法拉起的,会抛出异常,所以要使用下面的格式。
uri: 'link://www.example.com'
要对应被拉起方
"scheme": "link",
"host": "www.example.com"
2、使用startAbility实现
startAbility接口是将应用链接放入Want中,通过调用隐式Want匹配的方法触发应用跳转。
Button('DeepLink')
.onClick(() =>{
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
let want: Want = {
uri: 'link://www.example.com', // 此处为实际应用链接
};
try {
context.startAbility(want).then(() =>{
hilog.info(DOMAIN_NUMBER, TAG, 'openLink success.');
}).catch((err: BusinessError )=>{
hilog.error(DOMAIN_NUMBER, TAG, `openLink failed. Code is ${err.code}, message is ${err.message}`);
})
}catch (e) {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to start link. Code is ${e.code}, message is ${e.message}`);
}
})
这里需要注意的是:
1、配置方式:
uri: 'link://www.example.com'
要对应被拉起方
"scheme": "link",
"host": "www.example.com"
如果写成下面这种方式是不对的:
uri: 'link://',
bundleName: 'www.example.com'
2、配置方式
"scheme": "link"
那么,拉起方只需要这样写就可以:
let want: Want = {
uri: 'link://', // 此处为实际应用链接
// bundleName: 'www.example.com' 如果使用bundleName字段,那么包名错误会导致无法正常拉起,这个地方需要特别注意
};
3、Web组件实现应用跳转(目前开发中没有遇到这里引用官方文档内容)
Web组件可以在onLoadIntercept的回调函数中实现应用跳转。
// DeepWebIndex.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
const DOMAIN_NUMBER = 0xF811;
const TAG = '[Sample_PullLinking]';
struct DeepWebIndex {
controller: webview.WebviewController = new webview.WebviewController();
build() {
Column() {
Web({ src: $rawfile('index.html'), controller: this.controller })
.onLoadIntercept((event) => {
const url: string = event.data.getRequestUrl();
if (url === 'link://www.example.com') {
(this.getUIContext().getHostContext() as common.UIAbilityContext).openLink(url)
.then(() => {
hilog.info(DOMAIN_NUMBER, TAG, 'openLink success.');
}).catch((err: BusinessError) => {
hilog.error(DOMAIN_NUMBER, TAG, `openLink failed, err: ${JSON.stringify(err)}.`);
});
return true;
}
// 返回true表示阻止此次加载,否则允许此次加载
return false;
})
}
}
}
前端代码
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>Hello World</h1>
<!--方式一、通过绑定事件window.open方法实现跳转-->
<button class="doOpenLink" onclick="doOpenLink()">跳转其他应用一</button>
<!--方式二、通过超链接实现跳转-->
<a href="link://www.example.com">跳转其他应用二</a>
</body>
</html>
<script>
function doOpenLink() {
window.open("link://www.example.com")
}
</script>
更多推荐



所有评论(0)