1e41f4b71Sopenharmony_ci# Launching a UIAbility in the Background Through the call Event 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ciThere may be cases you want to provide in a widget access to features available in your application running in the foreground, for example, the play, pause, and stop buttons in a music application widget. This is where the **call** capability of the [postCardAction](../reference/apis-arkui/js-apis-postCardAction.md#postcardaction) API comes in handy. This capability, when used in a widget, can start the specified UIAbility of the widget provider in the background. It also allows the widget to call the specified method of the application and transfer data so that the application, while in the background, can behave accordingly in response to touching of the buttons on the widget. 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ci> **NOTE** 7e41f4b71Sopenharmony_ci> 8e41f4b71Sopenharmony_ci> This topic describes development for dynamic widgets. For static widgets, see [FormLink](../reference/apis-arkui/arkui-ts/ts-container-formlink.md). 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ci## Constraints 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ciThis action type requires that the widget provider should have the [ohos.permission.KEEP_BACKGROUND_RUNNING](../security/AccessToken/permissions-for-all.md#ohospermissionkeep_background_running) permission. 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ci## How to Develop 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ciTypically, the call event is triggered for touching of buttons. Below is an example. 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci- In this example, two buttons are laid out on the widget page. When one button is clicked, the **postCardAction** API is called to send a call event to the target UIAbility. Note that the **method** parameter in the API indicates the method to call in the target UIAbility. It is mandatory and of the string type. 20e41f4b71Sopenharmony_ci 21e41f4b71Sopenharmony_ci ```ts 22e41f4b71Sopenharmony_ci @Entry 23e41f4b71Sopenharmony_ci @Component 24e41f4b71Sopenharmony_ci struct WidgetEventCallCard { 25e41f4b71Sopenharmony_ci @LocalStorageProp('formId') formId: string = '12400633174999288'; 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci build() { 28e41f4b71Sopenharmony_ci Column() { 29e41f4b71Sopenharmony_ci //... 30e41f4b71Sopenharmony_ci Row() { 31e41f4b71Sopenharmony_ci Column() { 32e41f4b71Sopenharmony_ci Button() { 33e41f4b71Sopenharmony_ci //... 34e41f4b71Sopenharmony_ci } 35e41f4b71Sopenharmony_ci //... 36e41f4b71Sopenharmony_ci .onClick(() => { 37e41f4b71Sopenharmony_ci postCardAction(this, { 38e41f4b71Sopenharmony_ci action: 'call', 39e41f4b71Sopenharmony_ci abilityName: 'WidgetEventCallEntryAbility', // Only the UIAbility of the current application is allowed. The ability name must be the same as that defined in module.json5. 40e41f4b71Sopenharmony_ci params: { 41e41f4b71Sopenharmony_ci formId: this.formId, 42e41f4b71Sopenharmony_ci method: 'funA' // Set the name of the method to call in the EntryAbility. 43e41f4b71Sopenharmony_ci } 44e41f4b71Sopenharmony_ci }); 45e41f4b71Sopenharmony_ci }) 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci Button() { 48e41f4b71Sopenharmony_ci //... 49e41f4b71Sopenharmony_ci } 50e41f4b71Sopenharmony_ci //... 51e41f4b71Sopenharmony_ci .onClick(() => { 52e41f4b71Sopenharmony_ci postCardAction(this, { 53e41f4b71Sopenharmony_ci action: 'call', 54e41f4b71Sopenharmony_ci abilityName: 'WidgetEventCallEntryAbility', // Only the UIAbility of the current application is allowed. The ability name must be the same as that defined in module.json5. 55e41f4b71Sopenharmony_ci params: { 56e41f4b71Sopenharmony_ci formId: this.formId, 57e41f4b71Sopenharmony_ci method: 'funB', // Set the name of the method to call in the EntryAbility. 58e41f4b71Sopenharmony_ci num: 1 // Set other parameters to be passed in. 59e41f4b71Sopenharmony_ci } 60e41f4b71Sopenharmony_ci }); 61e41f4b71Sopenharmony_ci }) 62e41f4b71Sopenharmony_ci } 63e41f4b71Sopenharmony_ci }.width('100%').height('80%') 64e41f4b71Sopenharmony_ci .justifyContent(FlexAlign.Center) 65e41f4b71Sopenharmony_ci } 66e41f4b71Sopenharmony_ci .width('100%') 67e41f4b71Sopenharmony_ci .height('100%') 68e41f4b71Sopenharmony_ci .alignItems(HorizontalAlign.Center) 69e41f4b71Sopenharmony_ci } 70e41f4b71Sopenharmony_ci } 71e41f4b71Sopenharmony_ci ``` 72e41f4b71Sopenharmony_ci 73e41f4b71Sopenharmony_ci- The UIAbility receives the call event and obtains the transferred parameters. It then executes the target method specified by the **method** parameter. Other data can be obtained through the [readString](../reference/apis-ipc-kit/js-apis-rpc.md#readstring) method. Listen for the method required by the call event in the **onCreate** callback of the UIAbility. 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ci ```ts 76e41f4b71Sopenharmony_ci import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 77e41f4b71Sopenharmony_ci import { promptAction } from '@kit.ArkUI'; 78e41f4b71Sopenharmony_ci import { BusinessError } from '@kit.BasicServicesKit'; 79e41f4b71Sopenharmony_ci import { rpc } from '@kit.IPCKit'; 80e41f4b71Sopenharmony_ci import { hilog } from '@kit.PerformanceAnalysisKit'; 81e41f4b71Sopenharmony_ci 82e41f4b71Sopenharmony_ci const TAG: string = 'WidgetEventCallEntryAbility'; 83e41f4b71Sopenharmony_ci const DOMAIN_NUMBER: number = 0xFF00; 84e41f4b71Sopenharmony_ci const CONST_NUMBER_1: number = 1; 85e41f4b71Sopenharmony_ci const CONST_NUMBER_2: number = 2; 86e41f4b71Sopenharmony_ci 87e41f4b71Sopenharmony_ci class MyParcelable implements rpc.Parcelable { 88e41f4b71Sopenharmony_ci num: number; 89e41f4b71Sopenharmony_ci str: string; 90e41f4b71Sopenharmony_ci 91e41f4b71Sopenharmony_ci constructor(num: number, str: string) { 92e41f4b71Sopenharmony_ci this.num = num; 93e41f4b71Sopenharmony_ci this.str = str; 94e41f4b71Sopenharmony_ci } 95e41f4b71Sopenharmony_ci 96e41f4b71Sopenharmony_ci marshalling(messageSequence: rpc.MessageSequence): boolean { 97e41f4b71Sopenharmony_ci messageSequence.writeInt(this.num); 98e41f4b71Sopenharmony_ci messageSequence.writeString(this.str); 99e41f4b71Sopenharmony_ci return true; 100e41f4b71Sopenharmony_ci } 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ci unmarshalling(messageSequence: rpc.MessageSequence): boolean { 103e41f4b71Sopenharmony_ci this.num = messageSequence.readInt(); 104e41f4b71Sopenharmony_ci this.str = messageSequence.readString(); 105e41f4b71Sopenharmony_ci return true; 106e41f4b71Sopenharmony_ci } 107e41f4b71Sopenharmony_ci } 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ci export default class WidgetEventCallEntryAbility extends UIAbility { 110e41f4b71Sopenharmony_ci // If the UIAbility is started for the first time, onCreate is triggered after the call event is received. 111e41f4b71Sopenharmony_ci onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { 112e41f4b71Sopenharmony_ci try { 113e41f4b71Sopenharmony_ci // Listen for the method required by the call event. 114e41f4b71Sopenharmony_ci this.callee.on('funA', (data: rpc.MessageSequence) => { 115e41f4b71Sopenharmony_ci // Obtain all parameters passed in the call event. 116e41f4b71Sopenharmony_ci hilog.info(DOMAIN_NUMBER, TAG, `FunACall param: ${JSON.stringify(data.readString())}`); 117e41f4b71Sopenharmony_ci promptAction.showToast({ 118e41f4b71Sopenharmony_ci message: 'FunACall param:' + JSON.stringify(data.readString()) 119e41f4b71Sopenharmony_ci }); 120e41f4b71Sopenharmony_ci return new MyParcelable(CONST_NUMBER_1, 'aaa'); 121e41f4b71Sopenharmony_ci }); 122e41f4b71Sopenharmony_ci this.callee.on('funB', (data: rpc.MessageSequence) => { 123e41f4b71Sopenharmony_ci // Obtain all parameters passed in the call event. 124e41f4b71Sopenharmony_ci hilog.info(DOMAIN_NUMBER, TAG, `FunBCall param: ${JSON.stringify(data.readString())}`); 125e41f4b71Sopenharmony_ci promptAction.showToast({ 126e41f4b71Sopenharmony_ci message: 'FunBCall param:' + JSON.stringify(data.readString()) 127e41f4b71Sopenharmony_ci }); 128e41f4b71Sopenharmony_ci return new MyParcelable(CONST_NUMBER_2, 'bbb'); 129e41f4b71Sopenharmony_ci }); 130e41f4b71Sopenharmony_ci } catch (err) { 131e41f4b71Sopenharmony_ci hilog.error(DOMAIN_NUMBER, TAG, `Failed to register callee on. Cause: ${JSON.stringify(err as BusinessError)}`); 132e41f4b71Sopenharmony_ci } 133e41f4b71Sopenharmony_ci } 134e41f4b71Sopenharmony_ci 135e41f4b71Sopenharmony_ci // Deregister the listener when the process exits. 136e41f4b71Sopenharmony_ci onDestroy(): void | Promise<void> { 137e41f4b71Sopenharmony_ci try { 138e41f4b71Sopenharmony_ci this.callee.off('funA'); 139e41f4b71Sopenharmony_ci this.callee.off('funB'); 140e41f4b71Sopenharmony_ci } catch (err) { 141e41f4b71Sopenharmony_ci hilog.error(DOMAIN_NUMBER, TAG, `Failed to register callee off. Cause: ${JSON.stringify(err as BusinessError)}`); 142e41f4b71Sopenharmony_ci } 143e41f4b71Sopenharmony_ci } 144e41f4b71Sopenharmony_ci } 145e41f4b71Sopenharmony_ci ``` 146