[AI Readability Summary] HarmonyOS 6.0 extends Call Service Kit’s VoIP capabilities to Wearable devices, allowing developers to use the same
voipCallAPI across phones, tablets, and smartwatches. It addresses wearable-side incoming call handling, outgoing call reporting, state synchronization, and foreground/background activation. Keywords: HarmonyOS 6.0,voipCall, Wearable.
Technical specifications are easy to verify at a glance
| Parameter | Description |
|---|---|
| Platform language | ArkTS / TypeScript |
| Core protocols | VoIP, Push-based wake-up, system call UI event callbacks |
| Version baseline | HarmonyOS 6.0.0(20) / API 21 |
| Supported devices | Phone, Tablet, Wearable |
| Calling capabilities | Incoming calls, outgoing calls, state changes, UI interaction events |
| Core dependencies | @kit.CallServiceKit, @kit.ImageKit, @kit.PerformanceAnalysisKit |
| Regional availability | Currently supported in mainland China |
| Concurrency limits | Up to 3 incoming calls and 1 outgoing call |
AI Visual Insight: The image shows the HarmonyOS Call Service Kit calling interface in a multi-device scenario, highlighting system-level incoming call presentation, wearable notification layouts, and a consistent cross-device experience powered by a unified API.
Wearable support brings VoIP into true full-scenario collaboration
The key change in HarmonyOS 6.0 is not the introduction of a separate watch-specific API. Instead, it extends the existing voipCall capability to Wearable devices. For developers, this means you do not need to rewrite the business-layer call model. You only need to add device capability checks, UI constraints, and lifecycle handling.
For users, the value is even more direct: when the phone is not nearby, the smartwatch can still receive or initiate a VoIP call. This capability moves the smartwatch beyond being a simple notification mirror and turns it into a device that can independently carry the communication flow.
You must confirm version and capability boundaries first
Full Wearable support starts with HarmonyOS 6.0.0(20), which corresponds to API 21. If the device version or SDK version is below this baseline, the code may still compile, but the system incoming call banner or UI event callbacks may not work correctly.
| Capability scenario | Supported devices |
|---|---|
| Incoming call reporting | Phone, Tablet, Wearable |
| Outgoing call reporting | Phone, Tablet, Wearable |
| Enterprise contact display | Phone, Tablet, PC/2in1, Wearable |
This matrix makes two points clear. First, smartwatch support is not a reduced or limited implementation. Second, enterprise communication apps can reuse the same capability to display contact identity information.
The voipCall module is the core entry point for Wearable calling
voipCall connects in-app VoIP sessions to the system call interaction layer. Its core responsibilities include reporting incoming calls, reporting outgoing calls, synchronizing call state, and listening for answer, reject, hang-up, and mute actions from the system UI.
Core enums define the state machine design
export enum VoipCallType {
VOIP_CALL_VOICE = 0, // Voice call
VOIP_CALL_VIDEO = 1 // Video call
}
export enum VoipCallState {
VOIP_CALL_STATE_IDLE = 0, // Idle
VOIP_CALL_STATE_RINGING = 1, // Ringing
VOIP_CALL_STATE_ACTIVE = 2, // Active
VOIP_CALL_STATE_HOLDING = 3, // On hold
VOIP_CALL_STATE_DISCONNECTED = 4, // Disconnected
VOIP_CALL_STATE_DIALING = 5, // Dialing
VOIP_CALL_STATE_ANSWERED = 6, // Answering
VOIP_CALL_STATE_DISCONNECTING = 7 // Disconnecting
}
These enums define the standard state machine for a VoIP session from setup to termination. They form the foundation for call synchronization and failure recovery.
The timing of UI event subscription matters more than reporting itself
The most common pitfall is not reportIncomingCall(), but the subscription order for voipCallUiEvent. If the app reports an incoming call before subscribing to events, the user’s answer or reject action on the system banner may be lost.
import { voipCall } from '@kit.CallServiceKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
function subscribeVoipEvent() {
voipCall.on('voipCallUiEvent', (eventInfo) => {
// Subscribe early to ensure user actions on the system banner are not lost
hilog.info(0x0000, 'CallDemo', `event=${eventInfo.event}, callId=${eventInfo.callId}`);
});
}
This code subscribes to system UI events in advance so user actions can reliably flow back to the business layer.
Incoming and outgoing call flows still follow a unified model on smartwatches
The incoming call flow usually has four steps: subscribe to events, report the incoming call, handle the user action, and continuously report call state. The outgoing call flow is simpler. The main difference is that it calls reportOutgoingCall(), and the system displays a call capsule instead of an incoming call banner.
Incoming call reporting requires complete call attributes
import { voipCall } from '@kit.CallServiceKit';
async function reportIncomingCall(callId: string, callerName: string, avatar: PixelMap) {
const attr: voipCall.VoipCallAttribute = {
callId,
voipCallType: voipCall.VoipCallType.VOIP_CALL_VOICE,
userName: callerName,
userProfile: avatar,
abilityName: 'EntryAbility' // Page entry launched after the user answers
};
// Report the incoming call to the system so it can display the incoming call banner
return await voipCall.reportIncomingCall(attr);
}
This code connects an app-side incoming call session to the system call entry point and specifies which UIAbility should be opened after the user answers.
State synchronization determines whether the system UI is trustworthy
System display does not mean the call is actually established. After the user taps Answer, the app still needs to establish the media channel itself and then call the state reporting API to synchronize with the system. Otherwise, the system UI and the real session state will drift apart.
async function reportCallState(callId: string, state: voipCall.VoipCallState) {
// Sync immediately after a call state change to avoid inconsistency between system UI and app state
await voipCall.reportCallStateChange(callId, state);
}
This code continuously maps the business-layer state machine to the system layer so the smartwatch UI remains accurate.
You must actively restore the app to the foreground after answering in the background
The voipCallUiEvent callback does not automatically bring the app back to the foreground. This is especially important on Wearable devices. After the user answers from the banner, the app UI may still remain in the background unless you explicitly restore the window.
private async handleVoiceAnswer(callId: string): Promise
<void> {
await this.establishVoipConnection(callId); // Establish the audio/video channel
await voipCall.reportCallStateChange(
callId,
voipCall.VoipCallState.VOIP_CALL_STATE_ACTIVE
);
const windowStage = AppStorage.get<window.WindowStage>('windowStage');
if (windowStage) {
const mainWindow = await windowStage.getMainWindow();
await windowStage.restoreWindow(mainWindow); // Actively restore the foreground window
}
}
This code fixes a common issue where the call is successfully answered but the app does not become visible. It is a critical step in closing the wearable experience loop.
Smartwatch adaptation is more about constraints than APIs
The main challenge on Wearable devices is not API differences, but resource limits, screen size, and system behavior. Smartwatch screens are smaller, batteries are more sensitive, and foreground/background switching happens more frequently. You should treat these constraints as first-class concerns during development.
You should narrow device capabilities and image sizes early
import { bundleManager, common } from '@kit.AbilityKit';
async function checkVoipSupport(context: common.Context): Promise
<boolean> {
// Confirm at runtime whether the system exposes VoIP calling capability
return await bundleManager.canIUse('SystemCapability.Telephony.VoipCallManager');
}
This code checks whether the target device exposes the required system capability before runtime execution, which helps you avoid direct failures on unsupported devices.
These limitations directly affect production implementation
- The system supports up to 3 simultaneous incoming calls and 1 outgoing call.
- The capability currently supports only mainland China.
- Background incoming calls depend on Push Kit to wake the main process first.
- On smartwatches, the incoming call banner and call capsule UI must adapt to round screens or small square displays.
If your app targets enterprise IM, customer service, or meeting scenarios, you should add these constraints to the test matrix early instead of waiting until the final integration phase.
Developers should treat Wearable calling as a state-driven system
From an architectural perspective, HarmonyOS 6.0 does not change the essence of VoIP. The system provides a unified entry point and interaction layer, while the app remains responsible for real session establishment, audio routing, failure recovery, and lifecycle management. Wearable support simply extends this mechanism to a lighter class of device.
Therefore, the best practice is not to copy phone code directly to a smartwatch. Instead, abstract a unified call state machine and then layer UI and resource strategies by device form factor. This approach gives you both high code reuse and strong stability.
FAQ: The 3 questions developers ask most often
Q1: Why can I see the incoming call banner on the watch, but the app never receives the answer event?
A: In most cases, voipCallUiEvent was subscribed too late. You must call voipCall.on() before the business flow starts. Do not wait until after the incoming call has been reported.
Q2: Why doesn’t the app open automatically after the user taps Answer on the watch?
A: The event callback does not automatically bring the app to the foreground. You need to explicitly call windowStage.restoreWindow() inside the callback to restore the window.
Q3: Why do background incoming calls sometimes not appear at all?
A: Background scenarios depend on Push Kit to wake the main process first, so the app can continue and call reportIncomingCall(). If the push delivery chain is not working, the system cannot display the complete incoming call flow.
Core Summary: This article systematically reconstructs HarmonyOS 6.0 Call Service Kit support for Wearable VoIP, focusing on the API 21 baseline, the voipCall event model, incoming and outgoing call reporting flows, smartwatch UI and lifecycle adaptation, and key engineering constraints such as Push Kit, regional availability, and concurrency limits.