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