开发语言:ArkTs
开发工具:DevEco Studio 5.0.0 Release
API版本:API 12
使用Deep Linking实现应用间跳转,系统会根据接口中传入的uri信息,在本地已安装的应用中寻找到符合条件的应用并进行拉起(当匹配到多个应用时,会拉起应用选择框)。此种方式与iOS、Android中的配置scheme方式相同,都是通过特定scheme的方式拉起指定APP。
本文演示A应用(拉起方)拉起B应用(被拉起方)。
一、B应用(被拉起方)的代码及配置
1、配置B应用(被拉起方)的module.json5
文件
为了能够支持被A应用(拉起方)访问,B应用(被拉起方)需要在module.json5
配置文件中配置skills
标签。
说明:
skills
标签下默认包含一个skill
对象,用于标识应用入口。应用跳转链接不能在该skill
对象中配置,需要创建独立的skill
对象。如果存在多个跳转场景,需要在skills
标签下创建不同的skill
对象,否则会导致配置无法生效。Deep Linking
中的scheme
取值支持自定义,可以为任意不包含特殊字符、非ohos开头
的字符串。通常不为https、http、file
,否则会拉起默认的系统浏览器。
ts
{
"module": {
// ...
"abilities": [
{
// ...
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
},
{
"actions": [
// actions不能为空,actions为空会造成目标方匹配失败。
"ohos.want.action.viewData"
],
"uris": [
{
// scheme必选,可以自定义,以blink为例,需要替换为实际的scheme
"scheme": "blink",
// host必选,配置待匹配的域名
"host": "www.blink.com"
}
]
} // 新增一个skill对象,用于跳转场景。如果存在多个跳转场景,需配置多个skill对象。
]
}
]
}
}
2、在B应用(被拉起方)中获取并解析A应用(拉起方)传入的应用链接
在B应用(被拉起方)的UIAbility
的onCreate()
或者onNewWant()
生命周期回调中,获取、解析A应用(拉起方)传入的应用链接。
ts
// 以EntryAbility.ets为例
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { url } from '@kit.ArkTS';
export default class EntryAbility extends UIAbility {
// 冷启动
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 从want中获取传入的链接信息。
// 如传入的url为:blink://www.blink.com/open?action=scan
let uri = want?.uri;
if (uri) {
// 从链接中解析query参数,拿到参数后,开发者可根据自己的业务需求进行后续的处理。
let urlObject = url.URL.parseURL(want?.uri);
let action = urlObject.params.get('action');
// 例如,当action为showall时,展示所有的节目。
if (action === "scan") {
// 跳转扫一扫
router.pushUrl({url: "pages/HMQRCodeScanPage"});
}
}
}
// 热启动
onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): void {
// 从want中获取传入的链接信息。
// 如传入的url为:blink://www.blink.com/open?action=scan
let uri = want?.uri;
if (uri) {
// 从链接中解析query参数,拿到参数后,开发者可根据自己的业务需求进行后续的处理。
let urlObject = url.URL.parseURL(want?.uri);
let action = urlObject.params.get('action');
// 例如,当action为showall时,展示所有的节目。
if (action === "scan") {
// 跳转扫一扫
router.pushUrl({url: "pages/HMQRCodeScanPage"});
}
}
}
}
二、A应用(拉起方)的代码配置
下面介绍如何使用openLink()
与startAbility()
接口实现应用跳转,以及如何在Web组件
中实现应用跳转。
1、判断B应用(被拉起方)是否安装
① 在entry
模块的module.json5
文件中配置querySchemes
属性,声明想要查询的URL scheme
。
typescript
{
"module": {
//...
"querySchemes": [
"blink"
]
}
}
② 调用bundleManager.canOpenLink()接口。
typescript
let canOpen = bundleManager.canOpenLink(link);
2、使用openLink()
实现应用跳转
在openLink接口的link字段中传入目标应用的URL信息,并将options字段中的appLinkingOnly配置为false。
typescript
import { common, OpenLinkOptions } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { bundleManager } from '@kit.AbilityKit';
const TAG: string = '[UIAbilityComponentsOpenLink]';
const DOMAIN_NUMBER: number = 0xFF00;
@Entry
@Component
struct Index {
build() {
Button('start link', { type: ButtonType.Capsule, stateEffect: true })
.width('87%')
.height('5%')
.margin({ bottom: '12vp' })
.onClick(() => {
let link: string = "blink://www.blink.com/open?action=scan";
let canOpen = bundleManager.canOpenLink(link);
if (canOpen) {
try {
let context = getContext(this) as common.UIAbilityContext;
context.openLink(link, {appLinkingOnly: false})
.then(() => {
hilog.info(DOMAIN_NUMBER, TAG, 'open link success.');
}).catch((err: BusinessError) => {
hilog.error(DOMAIN_NUMBER, TAG, `open link failed. `);
});
} catch (paramError) {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to start link. `);
}
} else {
hilog.error(DOMAIN_NUMBER, TAG, `Not installed to open link. `);
}
})
}
}
3、使用startAbility()
实现应用跳转
startAbility
接口是将应用链接放入want
中,通过调用隐式want
匹配的方法触发应用跳转。通过startAbility
接口启动时,还需要调用方传入待匹配的action
和entity
。
typescript
import { common, Want } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { bundleManager } from '@kit.AbilityKit';
const TAG: string = '[UIAbilityComponentsOpenLink]';
const DOMAIN_NUMBER: number = 0xFF00;
@Entry
@Component
struct Index {
build() {
Button('start ability', { type: ButtonType.Capsule, stateEffect: true })
.width('87%')
.height('5%')
.margin({ bottom: '12vp' })
.onClick(() => {
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
let link: string = "blink://www.blink.com/open?action=scan";
let canOpen = bundleManager.canOpenLink(link);
if (canOpen) {
let want: Want = {
uri: link
};
try {
context.startAbility(want).then(() => {
hilog.info(DOMAIN_NUMBER, TAG, 'start ability success.');
}).catch((err: BusinessError) => {
hilog.error(DOMAIN_NUMBER, TAG, `start ability failed. `);
});
} catch (paramError) {
hilog.error(DOMAIN_NUMBER, TAG, `Failed to start ability. `);
}
} else {
hilog.error(DOMAIN_NUMBER, TAG, `Not installed to open link. `);
}
})
}
}
4、使用Web组件
实现应用跳转
Web组件
需要跳转DeepLink
链接应用时,可通过拦截回调onLoadIntercept
中对定义的事件进行处理,实现应用跳转。
typescript
// index.ets
import { webview } from '@kit.ArkWeb';
import { BusinessError } from '@kit.BasicServicesKit';
import { common, bundleManager } from '@kit.AbilityKit';
@Entry
@Component
struct WebComponent {
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.startWith('blink://')) {
let canOpen = bundleManager.canOpenLink(link);
if (canOpen) {
let context = getContext() as common.UIAbilityContext
context.openLink(url)
.then(() => {
console.log('openLink success');
}).catch((err: BusinessError) => {
console.error('openLink failed, err:' + JSON.stringify(err));
});
return true;
} else {
hilog.error(DOMAIN_NUMBER, TAG, `Not installed to open link. `);
}
}
// 返回true表示阻止此次加载,否则允许此次加载
return false;
})
}
}
}