【HarmonyOS】鸿蒙原生实现应用间跳转之Deep Linking

开发语言: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应用(被拉起方)的UIAbilityonCreate()或者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接口启动时,还需要调用方传入待匹配的actionentity

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;
        })
    }
  }
}
相关推荐
拥有一颗学徒的心5 小时前
鸿蒙第三方库MMKV源码学习笔记
笔记·学习·性能优化·harmonyos
海绵宝宝_5 小时前
【HarmonyOS NEXT】获取正式应用签名证书的签名信息
android·前端·华为·harmonyos·鸿蒙·鸿蒙应用开发
林钟雪5 小时前
HarmonyOS全栈开发指南:从入门到精通,构建万物智联的未来生态(三)
harmonyos·鸿蒙
林钟雪5 小时前
深入探索HarmonyOS——构建万物智联的新时代
华为·harmonyos
别说我什么都不会6 小时前
鸿蒙轻内核M核源码分析系列九 互斥锁Mutex
操作系统·harmonyos
纯爱掌门人10 小时前
鸿蒙Next复杂列表性能优化:让滑动体验如丝般顺滑
前端·性能优化·harmonyos
元芳想去看海10 小时前
仿京东短信验证码UI效果(鸿蒙)
harmonyos
鸿蒙程序媛11 小时前
【鸿蒙开发】第三十八章 ArkTS代码调试
harmonyos
别说我什么都不会13 小时前
鸿蒙轻内核M核源码分析系列七 动态内存Dynamic Memory
操作系统·harmonyos
SuperHeroWu715 小时前
【HarmonyOS Next】鸿蒙监听手机按键
华为·harmonyos·鸿蒙·监听事件·按键·onkeyevent·按下