App Linking相比Deep Linking增加了域名校验环节,使链接更加安全可靠。无论应用是否已安装,用户都可以访问到链接对应的内容,跳转体验更加顺畅。

一、场景介绍

使用App Linking应用链接进行跳转时,系统会根据接口传入的uri信息(HTTPS链接)将用户引导至目标应用中的特定内容,无论应用是否已安装,用户都可以访问到链接对应的内容,跳转体验相比Deep Linking方式更加顺畅。

例如:当使用App Linking应用链接接入“扫码直达”服务后,用户可通过控制中心扫一扫这类系统级扫码入口,扫描应用的二维码、条形码并跳转到应用对应服务页,实现一步直达的体验。

说明:该能力目前仅适用于5.0.0(12)及以上版本的HarmonyOS应用。

二、原理机制

2.1 App Linking vs Deep Linking

App Linking在Deep Linking基础上增加了域名校验环节,通过域名校验,可帮助用户消除歧义,识别合法归属于域名的应用,使链接更加安全可靠。

2.2 呈现方式

App Linking对于同一HTTPS网址,有应用网页两种内容的呈现方式:

情况 行为
应用已安装 优先打开应用去呈现内容
应用未安装 打开浏览器呈现Web版内容

三、支持版本

设备类型 支持版本
Phone 支持
PC/2in1 支持
Tablet 支持
TV 5.1.1(19)开始支持

四、前提条件

开通App Linking服务

五、开发流程

角色 操作步骤
云端开发 开通App Linking服务
云端开发 建立域名与应用关联关系
云端开发 在AGC为应用创建关联的网址域名
客户端开发 在module.json5中配置关联的网址域名
客户端开发 处理传入的链接
前端开发 开发链接对应的H5网页(应用未安装时呈现Web版内容)
客户端开发 验证应用被拉起效果

六、配置应用链接能力

6.1 建立域名与应用关联关系

在开发者的网站域名服务器上做如下配置,后续在AGC创建关联网址域名时,AGC会通过此文件确认哪些应用才是合法归属于此域名的。

步骤1:创建域名配置文件applinking.json
{
  "applinking": {
    "apps": [
      {
        "appIdentifier": "1234567",
        "index": 1
      },
      {
        "appIdentifier": "7654321",
        "index": 2
      }
    ]
  }
}

参数

参数 必选 类型 说明
appIdentifier M String 创建应用时生成的APP ID
index O Integer 优先级(-100~100),值越大优先级越高(起始版本:6.1.0(23))

说明:同一个网站域名可以关联多个应用,只需要在"apps"列表里放置多个"appIdentifier"元素即可。

index优先级规则

情况 行为
匹配到多个应用,都未配置index 拉起所有匹配的应用,弹出对话框让用户选择
部分或全部配置了index 拉起index值最大的应用;多个index值最大时,拉起这些应用并弹窗选择
步骤2:上传配置文件

将applinking.json配置文件放在域名服务器的固定目录下:

https://domain.name/.well-known/applinking.json

示例:服务器域名为www.example.com,则必须将applinking.json文件放在:

https://www.example.com/.well-known/applinking.json

6.2 在AGC为应用创建关联的网址域名

  1. 登录AppGallery Connect

  2. 点击"开发与服务"

  3. 在项目列表中点击HarmonyOS应用所在的项目

  4. 左侧导航栏选择"增长 → App Linking → 应用链接",点击"创建"

填写域名:填写建立域名与应用关联关系的网址域名,例如:https://www.example.com

注意:必须输入精确的域名,不可输入包含特殊字符的模糊网址,不可以在域名后面添加/

发布状态

状态 说明
发布成功 配置文件中存在本项目中的应用
发布中 还在校验中
发布失败 配置文件中没有包含任何本项目中的应用

说明:如果距离上次更新超过24小时,系统会去域名服务器上重新获取配置文件进行交集校验。

6.3 在module.json5中配置关联的网址域名

在应用的module.json5文件中进行如下配置。

配置要求

配置项 要求
entities 必须包含"entity.system.browsable"
actions 必须包含"ohos.want.action.viewData"
uris 必须包含scheme"https"host为域名地址的元素
domainVerify 设置为true,开启域名校验开关
exported 设置为true

注意:skills标签下默认包含一个skill对象用于标识应用入口,应用跳转链接不能在第一个skill对象中配置,需要创建独立的skill对象。如果存在多个跳转场景,需要在skills标签下创建不同的skill对象。

{
  "module": {
    "abilities": [
      {
        "name": "EntryAbility",
        "srcEntry": "./ets/entryability/EntryAbility.ets",
        "exported": true,
        "skills": [
          {
            "entities": ["entity.system.home"],
            "actions": ["ohos.want.action.home"]
          },
          {
            "entities": ["entity.system.browsable"],
            "actions": ["ohos.want.action.viewData"],
            "uris": [
              {
                "scheme": "https",
                "host": "www.example.com",
                "path": "path1"
              }
            ],
            "domainVerify": true
          }
        ]
      }
    ]
  }
}

6.4 处理传入的链接

在应用的Ability(如EntryAbility)的onCreate()或者onNewWant()生命周期回调中添加代码处理传入的链接。

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { url } from '@kit.ArkTS';

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    let uri = want?.uri;
    if (uri) {
      try {
        let urlObject = url.URL.parseURL(want?.uri);
        let action = urlObject.params.get('action');
        if (action === "showall") {
          // 处理业务逻辑
        }
      } catch (error) {
        hilog.error(0x0000, 'testTag', `Failed to parse url.`);
      }
    }
  }
}

七、验证应用被拉起效果

7.1 签名要求

必须使用手动签名,不能使用自动签名。

7.2 验证方式

方式 说明
点击链接验证 将链接存入备忘录,点击验证
openLink接口拉起 通过UIAbilityContext.openLink()接口拉起
系统浏览器/ArkWeb拉起 在系统浏览器或ArkWeb网页上点击链接
系统级扫码入口拉起 扫描二维码验证(如美团扫码直达)

7.3 通过openLink接口拉起示例

GlobalContext.ets

import { common } from '@kit.AbilityKit';

export class GlobalContext {
  private static context: common.UIAbilityContext;
  public static initContext(context: common.UIAbilityContext): void {
    GlobalContext.context = context;
  }
  public static getContext(): common.UIAbilityContext {
    return GlobalContext.context;
  }
}

Index.ets

import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { GlobalContext } from '../common/GlobalContext';

@Entry
@Component
struct Index {
  build() {
    Button('start link')
      .onClick(() => {
        let context = GlobalContext.getContext();
        let link: string = "https://www.example.com/programs?action=showall";
        context.openLink(link, { appLinkingOnly: true })
          .then(() => {
            hilog.info(0x0000, 'testTag', `Succeeded in opening link.`);
          })
          .catch((error: BusinessError) => {
            hilog.error(0x0000, 'testTag', `Failed to open link, code: ${error.code}, message: ${error.message}`);
          });
      })
  }
}

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐