1# 使用App Linking实现应用间跳转 2 3## 简介 4 5使用App Linking进行跳转时,系统会根据接口传入的uri信息(HTTPS链接)将用户引导至目标应用中的特定内容,无论应用是否已安装,用户都可以访问到链接对应的内容,整个跳转体验相比[Deep Linking](deep-linking-startup.md)方式更加顺畅。 6 7 8## 适用场景 9 10* 适用于对安全性要求较高的场景,避免出现目标应用被其它应用仿冒的问题。 11 12* 适用于对体验要求较高的场景,不管目标应用是否安装,用户点击该链接都可以正常访问。 13 14## 实现原理 15 16* App Linking在Deep Linking基础上增加了域名校验环节,通过域名校验,可帮助用户消除歧义,识别合法归属于域名的应用,使链接更加安全可靠。 17 18* App Linking要求对于同一HTTPS网址,有应用和网页两种内容的呈现方式。当应用安装时则优先打开应用去呈现内容;当应用未安装时,则打开浏览器呈现Web版的内容。 19 20 21## 目标应用操作指导 22 23目标应用如需支持App Linking功能,需要执行如下操作: 24 251. 声明应用关联的网站域名。 262. 在开发者网站上关联应用。 273. 添加代码到应用的Ability中,以处理传入的链接。 28 29 30### 声明应用关联的网站域名 31 32在应用的[module.json5配置文件](../quick-start/module-configuration-file.md)中进行如下配置,以声明应用关联的域名地址,并开启域名校验开关。 33 34* "actions"列表中包含"ohos.want.action.viewData"。 35* "entities"列表中包含"entity.system.browsable"。 36* "uris"列表中包含"scheme"为"https"且"host"为域名地址的元素。 37* "domainVerify":设置为true,表示开启域名校验开关。 38 39> **说明**: 40> 41> skills标签下默认包含一个skill对象,用于标识应用入口。应用跳转链接不能在该skill对象中配置,需要创建独立的skill对象。如果存在多个跳转场景,需要在skills标签下创建不同的skill对象,否则会导致配置无法生效。 42 43 44例如,声明应用关联在域名是www.example.com,则需进行如下配置: 45 46```json 47{ 48 "module": { 49 // ... 50 "abilities": [ 51 { 52 // ... 53 "skills": [ 54 { 55 "entities": [ 56 "entity.system.home" 57 ], 58 "actions": [ 59 "ohos.want.action.home" 60 ] 61 }, 62 { 63 "entities": [ 64 // entities须包含"entity.system.browsable" 65 "entity.system.browsable" 66 ], 67 "actions": [ 68 // actions须包含"ohos.want.action.viewData" 69 "ohos.want.action.viewData" 70 ], 71 "uris": [ 72 { 73 // scheme须配置为https 74 "scheme": "https", 75 // host须配置关联的域名 76 "host": "www.example.com", 77 // path可选,为了避免匹配到多个应用,建议配置该字段 78 "path": "path1" 79 } 80 ], 81 // domainVerify须设置为true 82 "domainVerify": true 83 } // 新增一个skill对象,用于跳转场景。如果存在多个跳转场景,需配置多个skill对象。 84 ] 85 } 86 ] 87 } 88} 89``` 90 91 92### 在开发者网站上关联应用 93 94在开发者的网站上做如下配置,以关联应用。 95 961. 创建域名配置文件applinking.json。 97 98 内容为如下: 99 100 ```json 101 { 102 "applinking": { 103 "apps": [ 104 { 105 "appIdentifier": "1234" 106 } 107 ] 108 } 109 } 110 ``` 111 112 `app-identifer`是在应用签名阶段为应用分配的唯一标识,即[HarmonyAppProvision配置文件](../security/app-provision-structure.md)中声明的`app-identifer`字段的值。 113 1141. 将配置文件放在域名服务器的固定目录下。 115 固定目录为: 116 > https://*your.domain.name*/.well-known/applinking.json 117 118 例如开发者的域名为www.example.com,则需将applinking.json文件放在如下位置: 119 `https://www.example.com/.well-known/applinking.json` 120 121 122### 添加代码到应用的Ability中以处理传入的链接 123 124在应用的Ability(如EntryAbility)的onCreate()或者onNewWant()生命周期回调中添加代码,以处理传入的链接。 125 126```ts 127import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 128import { url } from '@kit.ArkTS'; 129 130export default class EntryAbility extends UIAbility { 131 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 132 // 从want中获取传入的链接信息。 133 // 如传入的url为:https://www.example.com/programs?action=showall 134 let uri = want?.uri 135 if (uri) { 136 // 从链接中解析query参数,拿到参数后,开发者可根据自己的的务需求进行后续的处理。 137 let urlObject = url.URL.parseURL(want?.uri); 138 let action = urlObject.params.get('action') 139 // 例如,当action为showall时,展示所有的节目。 140 if (action === "showall") { 141 // ... 142 } 143 } 144 } 145} 146``` 147 148 149 150## 拉起方应用实现应用跳转 151 152拉起方应用通过UIAbilityContext.openLink接口,传入目标应用的链接,拉起目标应用。 153 154openLink接口提供了两种拉起目标应用的方式,开发者可根据业务需求进行选择。 155 156 - **方式一:** 仅以App Linking的方式打开应用 157 将`appLinkingOnly`参数设为true,若有匹配的应用,则直接打开目标应用。若无App Linking匹配的应用,则抛异常给开发者进行处理。 158 159 - **方式二:** 以App Linking优先的方式打开应用 160 将`appLinkingOnly`参数设为false或者默认,则为App Linking优先的方式打开应用。若有App Linking匹配的应用,则直接打开目标应用。若无App Linking匹配的应用,则尝试以Deep Linking的方式打开应用。 161 162本文为了方便验证App Linking的配置是否正确,选择方式一,示例如下。 163 164```ts 165import common from '@ohos.app.ability.common'; 166import { BusinessError } from '@ohos.base'; 167 168@Entry 169@Component 170struct Index { 171 build() { 172 Button('start link', { type: ButtonType.Capsule, stateEffect: true }) 173 .width('87%') 174 .height('5%') 175 .margin({ bottom: '12vp' }) 176 .onClick(() => { 177 let context: common.UIAbilityContext = this.getUIContext().getHostContext() as common.UIAbilityContext; 178 let link: string = "https://www.example.com/programs?action=showall"; 179 // 仅以App Linking的方式打开应用 180 context.openLink(link, { appLinkingOnly: true }) 181 .then(() => { 182 console.info('openlink success.'); 183 }) 184 .catch((error: BusinessError) => { 185 console.error(`openlink failed. error:${JSON.stringify(error)}`); 186 }); 187 }) 188 } 189} 190``` 191 192在拉起方应用中执行上述代码,如果能够成功拉起目标应用,表明目标应的App Linking配置正确。 193 194## FAQ 195 196 1971. 应用的Modules.json5文件skills设置不正确。 198 199 检查"host"字段中是否是应用所对应的域名。 200 2012. 开发者网站服务器配置不正确。 202 203 * 检查服务器的 JSON 配置,并确保 `appIdentifier` 的值正确无误。 204 * 检查`applinking.json`是否放置在正确的目录(`.well-known`)下,通过浏览器等方式访问该json文件的地址:https://*your.domain.name*/.well-known/applinking.json,确保能正常访问。 205 2063. 系统尚未完成域名校验。 207 208 在设备上安装应用,需等待至少20秒,确保异步验证流程完成。 209 2104. 应用和域名的对应关系是怎样的? 211 212 应用和域名的关系是多对多的关系:一个应用可以关联多个不同的域名,同样的,一个域名也可以关联多个不同的应用。 213 2145. 如果同一域名关联了多个应用,那么该域名的链接将拉起哪个应用呢? 215 216 开发者可以通过配置applinking.json以关联多个应用。如果每个应用的module.json5的uris字段配置的都是一样的,那么系统将弹出列表框供用户选择要拉起的目标应用。 217 为了更好的体验,开发者也可以通过链接的path去区分拉起的目标应用,如链接`https://www.example.com/path1`拉起目标应用1,链接`https://www.example.com/path2`拉起目标应用2。 218