1# @ohos.arkui.uiExtension (uiExtension) 2 3用于EmbeddedUIExtensionAbility(或UIExtensionAbility)中获取宿主应用的窗口信息或对应的EmbeddedComponent<!--Del-->(或UIExtensionComponent)<!--DelEnd-->组件的信息。 4 5> **说明** 6> 7> 从API Version 12开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8> 9 10## 导入模块 11 12``` 13import { uiExtension } from '@kit.ArkUI' 14``` 15 16## WindowProxy 17 18### getWindowAvoidArea 19 20getWindowAvoidArea(type: window.AvoidAreaType): window.AvoidArea 21 22获取宿主应用窗口内容规避的区域;如系统栏区域、刘海屏区域、手势区域、软键盘区域等与宿主窗口内容重叠时,需要宿主窗口内容避让的区域。 23 24**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 25 26**系统能力**:SystemCapability.ArkUI.ArkUI.Full 27 28| 参数名 | 类型 | 必填 | 说明 | 29| -------- | -------- | -------- | -------- | 30| type |[window.AvoidAreaType](./js-apis-window.md#avoidareatype7) | 是 | 表示规避区类型。 | 31 32**返回值:** 33 34| 类型 | 说明 | 35| -------- | -------- | 36|[window.AvoidArea](./js-apis-window.md#avoidarea7) | 宿主窗口内容规避区域。 | 37 38**错误码**: 39 40以下错误码详细介绍请参考[通用错误码](../errorcode-universal.md)。 41 42| 错误码ID | 错误信息 | 43| ------- | -------- | 44| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 45 46**示例** 47 48```ts 49// ExtensionProvider.ts 50import { EmbeddedUIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit'; 51import { window } from '@kit.ArkUI'; 52 53export default class EntryAbility extends EmbeddedUIExtensionAbility { 54 onSessionCreate(want: Want, session: UIExtensionContentSession) { 55 const extensionWindow = session.getUIExtensionWindowProxy(); 56 // 获取宿主应用窗口的避让信息 57 let avoidArea: window.AvoidArea | undefined = extensionWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); 58 console.info(`avoidArea: ${JSON.stringify(avoidArea)}`); 59 } 60} 61``` 62 63### on('avoidAreaChange') 64 65on(type: 'avoidAreaChange', callback: Callback<AvoidAreaInfo>): void 66 67注册系统规避区变化的监听。 68 69**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 70 71**系统能力**:SystemCapability.ArkUI.ArkUI.Full 72 73| 参数名 | 类型 | 必填 | 说明 | 74| ------ | ---- | ---- | ---- | 75| type | string | 是 | 监听的事件类型,固定为'avoidAreaChange',即系统规避区变化事件。 | 76| callback | [Callback](../apis-basic-services-kit/js-apis-base.md#callback)<[AvoidAreaInfo](#avoidareainfo)> | 是 | 回调函数:入参用于接收当前规避区的信息。 | 77 78**错误码**: 79 80以下错误码详细介绍请参考[通用错误码](../errorcode-universal.md)。 81 82| 错误码ID | 错误信息 | 83| ------- | -------- | 84| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 85 86**示例** 87 88```ts 89// ExtensionProvider.ts 90import { EmbeddedUIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit'; 91import { uiExtension } from '@kit.ArkUI'; 92 93export default class EntryAbility extends EmbeddedUIExtensionAbility { 94 onSessionCreate(want: Want, session: UIExtensionContentSession) { 95 const extensionWindow = session.getUIExtensionWindowProxy(); 96 // 注册避让区变化的监听 97 extensionWindow.on('avoidAreaChange', (info: uiExtension.AvoidAreaInfo) => { 98 console.info(`The avoid area of the host window is: ${JSON.stringify(info.area)}.`); 99 }); 100 } 101} 102``` 103 104### off('avoidAreaChange') 105 106off(type: 'avoidAreaChange', callback?: Callback<AvoidAreaInfo>): void 107 108注销系统规避区变化的监听。 109 110**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 111 112**系统能力**:SystemCapability.ArkUI.ArkUI.Full 113 114| 参数名 | 类型 | 必填 | 说明 | 115| -------- | ---- | ---- | --- | 116| type | string | 是 | 注销的事件类型,固定为'avoidAreaChange',即系统规避区变化事件。 | 117| callback | [Callback](../apis-basic-services-kit/js-apis-base.md#callback)<[AvoidAreaInfo](#avoidareainfo)> | 否 | 回调函数:如果传入该参数,则关闭该监听。如果未传入参数,则关闭所有系统规避区变化的监听。 | 118 119**错误码**: 120 121以下错误码详细介绍请参考[通用错误码](../errorcode-universal.md)。 122 123| 错误码ID | 错误信息 | 124| -------- | ------------------------------------------------------------ | 125| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 126 127**示例** 128 129```ts 130// ExtensionProvider.ts 131import { EmbeddedUIExtensionAbility, UIExtensionContentSession } from '@kit.AbilityKit'; 132 133export default class EntryAbility extends EmbeddedUIExtensionAbility { 134 onSessionDestroy(session: UIExtensionContentSession) { 135 const extensionWindow = session.getUIExtensionWindowProxy(); 136 // 注销所有避让区变化的监听 137 extensionWindow.off('avoidAreaChange'); 138 } 139} 140``` 141 142### on('windowSizeChange') 143 144on(type: 'windowSizeChange', callback: Callback<window.Size>): void 145 146注册宿主应用窗口尺寸变化的监听。 147 148**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 149 150**系统能力**:SystemCapability.ArkUI.ArkUI.Full 151 152| 参数名 | 类型 | 必填 | 说明 | 153| -------- | --------------------- | ---- | ---------------------- | 154| type | string | 是 | 监听的事件类型,固定为'windowSizeChange',即窗口尺寸变化事件。 | 155| callback | [Callback](../apis-basic-services-kit/js-apis-base.md#callback)<[window.Size](js-apis-window.md#size7)> | 是 | 回调函数:入参用于接收当前窗口的尺寸。 | 156 157**错误码**: 158 159以下错误码详细介绍请参考[通用错误码](../errorcode-universal.md)。 160 161| 错误码ID | 错误信息 | 162| ------- | -------- | 163| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 164 165**示例** 166 167```ts 168// ExtensionProvider.ts 169import { EmbeddedUIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit'; 170import { window } from '@kit.ArkUI'; 171 172export default class EntryAbility extends EmbeddedUIExtensionAbility { 173 onSessionCreate(want: Want, session: UIExtensionContentSession) { 174 const extensionWindow = session.getUIExtensionWindowProxy(); 175 // 注册宿主应用窗口大小变化的监听 176 extensionWindow.on('windowSizeChange', (size: window.Size) => { 177 console.info(`The avoid area of the host window is: ${JSON.stringify(size)}.`); 178 }); 179 } 180} 181``` 182 183### off('windowSizeChange') 184 185off(type: 'windowSizeChange', callback?: Callback<window.Size>): void 186 187注销宿主应用窗口尺寸变化的监听。 188 189**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 190 191**系统能力**:SystemCapability.ArkUI.ArkUI.Full 192 193| 参数名 | 类型 | 必填 | 说明 | 194| -------- | --------------------- | ---- | ---------------------- | 195| type | string | 是 | 注销的事件类型,固定值:'windowSizeChange',即窗口尺寸变化事件。 | 196| callback | [Callback](../apis-basic-services-kit/js-apis-base.md#callback)<[window.Size](js-apis-window.md#size7)> | 否 | 回调函数:如果传入该参数,则关闭该监听。如果未传入参数,则关闭所有系统规避区变化的监听。 | 197 198**错误码**: 199 200以下错误码详细介绍请参考[通用错误码](../errorcode-universal.md)。 201 202| 错误码ID | 错误信息 | 203| ------- | -------- | 204| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 205 206**示例** 207 208```ts 209// ExtensionProvider.ts 210import { EmbeddedUIExtensionAbility, UIExtensionContentSession } from '@kit.AbilityKit'; 211 212export default class EntryAbility extends EmbeddedUIExtensionAbility { 213 onSessionDestroy(session: UIExtensionContentSession) { 214 const extensionWindow = session.getUIExtensionWindowProxy(); 215 // 注销宿主应用窗口大小变化的监听 216 extensionWindow.off('windowSizeChange'); 217 } 218} 219``` 220 221### createSubWindowWithOptions 222 223createSubWindowWithOptions(name: string, subWindowOptions: window.SubWindowOptions): Promise<window.Window> 224 225创建该WindowProxy实例下的子窗口,使用Promise异步回调。 226 227**系统能力:** SystemCapability.ArkUI.ArkUI.Full 228 229**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 230 231**模型约束:** 此接口仅可在Stage模型下使用。 232 233**参数:** 234 235| 参数名 | 类型 | 必填 | 说明 | 236| ------ | ------ | ---- | -------------- | 237| name | string | 是 | 子窗口的名字。 | 238| subWindowOptions | [window.SubWindowOptions](js-apis-window.md#subwindowoptions12) | 是 | 子窗口参数。 | 239 240**返回值:** 241 242| 类型 | 说明 | 243| -------------------------------- | ------------------------------------------------ | 244| Promise<[window.Window](js-apis-window.md#window)> | Promise对象。返回当前WindowProxy下创建的子窗口对象。 | 245 246**错误码:** 247 248以下错误码的详细介绍请参见[通用错误码](../errorcode-universal.md)和[窗口错误码](errorcode-window.md)。 249 250| 错误码ID | 错误信息 | 251| ------- | ------------------------------ | 252| 401 | Parameter error. Possible causes: 1. Mandatory parameters are left unspecified; 2.Incorrect parameters types; 3. Parameter verification failed. | 253| 801 | Capability not supported. Failed to call the API due to limited device capabilities. | 254| 1300002 | This window state is abnormal. | 255| 1300005 | This window proxy is abnormal. | 256 257**示例:** 258 259```ts 260// ExtensionProvider.ts 261import { EmbeddedUIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit'; 262import { window } from '@kit.ArkUI'; 263import { BusinessError } from '@kit.BasicServicesKit'; 264 265export default class EntryAbility extends EmbeddedUIExtensionAbility { 266 onSessionCreate(want: Want, session: UIExtensionContentSession) { 267 const extensionWindow = session.getUIExtensionWindowProxy(); 268 const subWindowOpts: window.SubWindowOptions = { 269 title: 'This is a subwindow', 270 decorEnabled: true 271 }; 272 // 创建子窗口 273 extensionWindow.createSubWindowWithOptions('subWindowForHost', subWindowOpts) 274 .then((subWindow: window.Window) => { 275 subWindow.setUIContent('pages/Index', (err, data) =>{ 276 if (err && err.code != 0) { 277 return; 278 } 279 subWindow?.resize(300, 300, (err, data)=>{ 280 if (err && err.code != 0) { 281 return; 282 } 283 subWindow?.moveWindowTo(100, 100, (err, data)=>{ 284 if (err && err.code != 0) { 285 return; 286 } 287 subWindow?.showWindow((err, data) => { 288 if (err && err.code == 0) { 289 console.info(`The subwindow has been shown!`); 290 } else { 291 console.error(`Failed to show the subwindow!`); 292 } 293 }); 294 }); 295 }); 296 }); 297 }).catch((error: BusinessError) => { 298 console.error(`Create subwindow failed: ${JSON.stringify(error)}`); 299 }) 300 } 301} 302``` 303 304## AvoidAreaInfo 305 306用于表示窗口规避区的信息。 307 308**原子化服务API:** 从API version 12开始,该接口支持在原子化服务中使用。 309 310**系统能力**:SystemCapability.ArkUI.ArkUI.Full 311 312| 名称 | 类型 | 必填 | 说明 | 313| ------ | -------------------- | ------------------ | ------------------ | 314| type | [window.AvoidAreaType](js-apis-window.md#avoidareatype7) | 是 | 窗口规避区类型。 | 315| area | [window.AvoidArea](js-apis-window.md#avoidarea7) | 是| 窗口内容规避区域。 | 316 317 318## 完整示例 319 320本示例展示文档中所有API在EmbeddedUIExtensionAbility中的基础使用方式,示例应用的`bundleName`为"com.example.embeddeddemo", 被拉起的`EmbeddedUIExtensionAbility`为"ExampleEmbeddedAbility". 321 322- 示例应用中的EntryAbility(UIAbility)加载首页文件:`pages/Index.ets`,其中内容如下: 323 324 ```ts 325 // pages/Index.ets -- UIAbility启动时加载此页面 326 import { Want } from '@kit.AbilityKit'; 327 328 @Entry 329 @Component 330 struct Index { 331 @State message: string = 'Message: ' 332 private want: Want = { 333 bundleName: "com.example.embeddeddemo", 334 abilityName: "ExampleEmbeddedAbility", 335 } 336 337 build() { 338 Row() { 339 Column() { 340 Text(this.message).fontSize(30) 341 EmbeddedComponent(this.want, EmbeddedType.EMBEDDED_UI_EXTENSION) 342 .width('100%') 343 .height('90%') 344 .onTerminated((info)=>{ 345 this.message = 'Termination: code = ' + info.code + ', want = ' + JSON.stringify(info.want); 346 }) 347 .onError((error)=>{ 348 this.message = 'Error: code = ' + error.code; 349 }) 350 } 351 .width('100%') 352 } 353 .height('100%') 354 } 355 } 356 ``` 357 358- EmbeddedComponent拉起的EmbeddedUIExtensionAbility在`ets/extensionAbility/ExampleEmbeddedAbility`文件中实现,内容如下: 359 360 ```ts 361 import { EmbeddedUIExtensionAbility, UIExtensionContentSession, Want } from '@kit.AbilityKit'; 362 363 const TAG: string = '[ExampleEmbeddedAbility]' 364 export default class ExampleEmbeddedAbility extends EmbeddedUIExtensionAbility { 365 366 onCreate() { 367 console.info(TAG, `onCreate`); 368 } 369 370 onForeground() { 371 console.info(TAG, `onForeground`); 372 } 373 374 onBackground() { 375 console.info(TAG, `onBackground`); 376 } 377 378 onDestroy() { 379 console.info(TAG, `onDestroy`); 380 } 381 382 onSessionCreate(want: Want, session: UIExtensionContentSession) { 383 console.info(TAG, `onSessionCreate, want: ${JSON.stringify(want)}`); 384 let param: Record<string, UIExtensionContentSession> = { 385 'session': session 386 }; 387 let storage: LocalStorage = new LocalStorage(param); 388 session.loadContent('pages/extension', storage); 389 } 390 } 391 ``` 392 393- EmbeddedUIExtensionAbility的入口页面文件`pages/extension.ets`内容如下: 394 395 ```ts 396 import { UIExtensionContentSession } from '@kit.AbilityKit'; 397 import { uiExtension, window } from '@kit.ArkUI'; 398 import { BusinessError } from '@kit.BasicServicesKit'; 399 let storage = LocalStorage.getShared() 400 401 @Entry(storage) 402 @Component 403 struct Extension { 404 @State message: string = 'EmbeddedUIExtensionAbility Index'; 405 private session: UIExtensionContentSession | undefined = storage.get<UIExtensionContentSession>('session'); 406 private extensionWindow: uiExtension.WindowProxy | undefined = this.session?.getUIExtensionWindowProxy(); 407 private subWindow: window.Window | undefined = undefined; 408 409 aboutToAppear(): void { 410 this.extensionWindow?.on('windowSizeChange', (size: window.Size) => { 411 console.info(`size = ${JSON.stringify(size)}`); 412 }); 413 this.extensionWindow?.on('avoidAreaChange', (info: uiExtension.AvoidAreaInfo) => { 414 console.info(`type = ${JSON.stringify(info.type)}, area = ${JSON.stringify(info.area)}`); 415 }); 416 } 417 418 aboutToDisappear(): void { 419 this.extensionWindow?.off('windowSizeChange'); 420 this.extensionWindow?.off('avoidAreaChange'); 421 } 422 423 build() { 424 Column() { 425 Text(this.message) 426 .fontSize(20) 427 .fontWeight(FontWeight.Bold) 428 Button("获取系统规避区信息").width('90%').margin({top: 5, bottom: 5}).fontSize(16).onClick(() => { 429 let avoidArea: window.AvoidArea | undefined = this.extensionWindow?.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); 430 console.info(`系统规避区: ${JSON.stringify(avoidArea)}`); 431 }) 432 Button("创建子窗口").width('90%').margin({top: 5, bottom: 5}).fontSize(16).onClick(() => { 433 let subWindowOpts: window.SubWindowOptions = { 434 'title': 'This is a subwindow', 435 decorEnabled: true 436 }; 437 this.extensionWindow?.createSubWindowWithOptions('subWindowForHost', subWindowOpts) 438 .then((subWindow: window.Window) => { 439 this.subWindow = subWindow; 440 this.subWindow.loadContent('pages/Index', storage, (err, data) =>{ 441 if (err && err.code != 0) { 442 return; 443 } 444 this.subWindow?.resize(300, 300, (err, data)=>{ 445 if (err && err.code != 0) { 446 return; 447 } 448 this.subWindow?.moveWindowTo(100, 100, (err, data)=>{ 449 if (err && err.code != 0) { 450 return; 451 } 452 this.subWindow?.showWindow((err, data) => { 453 if (err && err.code == 0) { 454 console.info(`The subwindow has been shown!`); 455 } else { 456 console.error(`Failed to show the subwindow!`); 457 } 458 }); 459 }); 460 }); 461 }); 462 }).catch((error: BusinessError) => { 463 console.error(`Create subwindow failed: ${JSON.stringify(error)}`); 464 }) 465 }) 466 }.width('100%').height('100%') 467 } 468 } 469 ``` 470 471- 最后,示例应用的`module.json5`中的"extensionAbilities"中需要增加一项,具体内容如下: 472 ```json 473 { 474 "name": "ExampleEmbeddedAbility", 475 "srcEntry": "./ets/extensionAbility/ExampleEmbeddedAbility.ets", 476 "type": "embeddedUI" 477 } 478 ``` 479