Using UIServiceExtensionAbility for System Floating Windows
Overview
The UIServiceExtensionAbility is an extension service component that includes a User Interface (UI). System applications can use the UIServiceExtensionAbility to implement a service capability with specific functions and a UI, and then expose this UI service for other third-party applications to call.
In this document, the component that starts or connects to a UIServiceExtensionAbility is called the client, and the UIServiceExtensionAbility is called the server.
An application can use a UIServiceExtensionAbility in two modes:
- Call startUIServiceExtensionAbility() in the UIExtensionContext class to start a UIServiceExtensionAbility.
- Call connectUIServiceExtensionAbility() in the UIAbilityContext or UIExtensionContext class to connect to a UIServiceExtensionAbility.
Constraints
-
This API takes effect only for 2-in-1 devices.
-
Third-party applications can connect to a UIServiceExtensionAbility provided by a system application only when they gain focus in the foreground.
-
The UIServiceExtensionAbility lifecycle is closely related to the window it binds. It is destroyed once the window is destroyed.
Starting a UIServiceExtensionAbility
An application (client) calls startUIServiceExtensionAbility() to start a UIServiceExtensionAbility. Once the UIServiceExtensionAbility is started, its lifecycle is independent of the client. Even if the client is destroyed, the background service remains alive. However, the service is destroyed if the window fails to be created or is destroyed.
The following example uses the startUIServiceExtensionAbility API to start a UIServiceExtensionAbility. For details about how to obtain the context, see Obtaining the Context of UIAbility.
import { common, Want } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct Start {
build() {
Column() {
Row() {
// Create a Start button.
Button('start UIServiceExtensionAbility')
.enabled(true)
.onClick(() => {
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
let startWant: Want = {
bundleName: 'com.samples.uiserviceextensionability', // This is just an example. Replace it with the actual bundle name of your UIServiceExtensionAbility.
abilityName: 'UiServiceExtAbility', // This is just an example. Replace it with the actual name of your UIServiceExtensionAbility.
};
try {
// Start the UIServiceExtensionAbility.
context.startUIServiceExtensionAbility(startWant).then(() => {
console.info('startUIServiceExtensionAbility success.');
}).catch((error: BusinessError) => {
console.error(`startUIServiceExtensionAbility failed, err code: ${error.code}, err msg: ${error.message}.`);
});
} catch (err) {
let code = (err as BusinessError).code;
let msg = (err as BusinessError).message;
console.error(`startUIServiceExtensionAbility failed, err code: ${code}, err msg: ${msg}.`);
}
})
}
}
}
}
Connecting to a UIServiceExtensionAbility
The client connects to the server through connectUIServiceExtensionAbility() and obtains a UIServiceProxy object. The client calls sendData() of the proxy object to send data to the server. The server calls the system API onData() of the UIServiceExtensionAbility class to receive data from the client.
The following example uses the connectUIServiceExtensionAbility API to connect to a UIServiceExtensionAbility. For details about how to obtain the context, see Obtaining the Context of UIAbility.
import { common, Want } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
struct Connect {
comProxy: common.UIServiceProxy | null = null;
connectCallback: common.UIServiceExtensionConnectCallback = {
onData: (data: Record<string, Object>) => {
console.info(`data received, data: ${JSON.stringify(data)}.`);
},
onDisconnect: () => {
console.info(`onDisconnect.`);
}
}
build() {
Column() {
Row() {
// Create a Connect button.
Button('connect ability')
.enabled(true)
.onClick(() => {
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
let startWant: Want = {
bundleName: 'com.acts.uiserviceextensionability', // This is just an example. Replace it with the actual bundle name of your UIServiceExtensionAbility.
abilityName: 'UiServiceExtAbility', // This is just an example. Replace it with the actual name of your UIServiceExtensionAbility.
};
try {
// Connect to the UIServiceExtensionAbility.
context.connectUIServiceExtensionAbility(startWant, this.connectCallback)
.then((proxy: common.UIServiceProxy) => {
this.comProxy = proxy;
let formData: Record<string, string> = {
'test': 'test'
};
try {
this.comProxy.sendData(formData);
} catch (err) {
let code = (err as BusinessError).code;
let msg = (err as BusinessError).message;
console.error(`sendData failed, err code:${code}, err msg:${msg}.`);
}
})
.catch((err: BusinessError) => {
console.error(`connectUIServiceExtensionAbility failed, err code: ${err.code}, err msg: ${err.message}.`);
});
} catch (err) {
let code = (err as BusinessError).code;
let msg = (err as BusinessError).message;
console.error(`connectUIServiceExtensionAbility failed, err code:${code}, err msg:${msg}.`);
}
})
}
}
}
}