Problem Description
Establishing reliable peer-to-peer (P2P) communication between Android phone applications and HarmonyOS wearable device applications presents unique challenges due to the mixed platform architecture. This guide addresses message delivery, connection stability, and proper synchronization between Android (using HiWear SDK) and HarmonyOS(using wearEngine SDK) platforms.
Background Knowledge
Communication Architecture
The P2P communication system uses the wearEngine SDK to establish a bidirectional communication channel between phone and wearable applications. The system uses three primary API clients: wearEngine.AuthClient for authorization management, wearEngine.P2pClient for peer-to-peer communication, and wearEngine.DeviceClient for device discovery and management.
The hybrid P2P communication system uses:
Key Capabilities
- Message Communication: Short text messages up to 1KB
- File Transfer: Files up to 100MB (phone to wearable) or 4MB (wearable to phone)
- Status Checking: Verification of app installation and running status
- Device Management: Connection monitoring and device pairing
Prerequisites
- Android Side: DEVICE_MANAGER permission
- HarmonyOS Side: Developer console permission approval (3-5 days processing)
- Both applications must be installed on their respective devices
- Wearable device must be connected to phone via Huawei Health app
- Proper signing certificate fingerprint configuration on both sides
Key Components
- wearEngine.AuthClient: Authorization and permission management
- wearEngine.DeviceClient: Device discovery and connection management
- wearEngine.P2pClient: Core P2P communication object
- wearEngine.P2pMessage: Message objects for communication
- wearEngine.Permission: Permission enumeration for different access levels
- Message Communication: Short text messages up to 1KB
- File Transfer: Files up to 100MB (phone to wearable) or 4MB (wearable to phone)
Permission Requirements
Available permission enumerations are:
- USER_STATUS (User status data)
- HEALTH_SENSOR (Health sensor data like heart rate)
- MOTION_SENSOR (Motion sensor data like accelerometer)
- DEVICE_IDENTIFIER (Device identifier information)
Troubleshooting Process
Step 1: Verify Device Connection and App Installation
Enter the "Management Center" of the Huawei Developer Alliance, and click on the "Wear Engine" card under the "Application Service" tab.
Please refer to: Development Preparations
Step 2: Requesting User Authorization
In order to safeguard user privacy, the Wear Engine APIs require the user's authorization. It's advisable to execute the actions outlined in this section during the user's initial invocation of Wear Engine's open capabilities.
Please refer to: Requesting User Authorization
Step 3: Establish Communication Channel
Android FingerPrint Configuration:
Please refer to: setPeerPkgName
P2pClient p2pClient = HiWear.getP2pClient(this);
p2pClient.setPeerPkgName("com.example.wearableapp");
p2pClient.setPeerFingerPrint("FINGERPRINT");
Harmony OS Wearable Configuration (Stage Model):
Please refer to: P2pAppParam
let appInfo: wearEngine.AppInfo = {
// Set the device-side app information, including the bundle name and fingerprint.
bundleName: '',
fingerprint: ''
}
let appParam: wearEngine.P2pAppParam = {
remoteApp: appInfo
// The default value of transformLocalAppInfo is false, indicating that the bundle name and fingerprint are not converted.
}
Harmony OS Wearable Configuration (FA Model):
Please refer to: P2pAppParam
var p2pClient = new P2pClient();
p2pClient.setPeerPkgName("com.example.phoneapp");
p2pClient.setPeerFingerPrint("FINGERPRINT")
Step 4: Verify Device Connection and App Installation / Test Communication with Ping
Android Side (Phone):
Please refer to: Querying Wearable Device
// Step 2: Obtain the P2P communication object.
P2pClient p2pClient = HiWear.getP2pClient(this);
// Package name of an app on a specific device.
String devicePkgName = "com.*.*";
// Step 3: Obtain the version number of your app on the wearable device.
if (connectedDevice != null && connectedDevice.isConnected()) {
p2pClient.getAppVersion(connectedDevice, devicePkgName)
.addOnSuccessListener(new OnSuccessListener<Integer>() {
@Override
public void onSuccess(Integer versionCode) {
// The logic used when the task of obtaining the app version number on the device is successfully executed.
// -1: The app has not been installed.
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// The logic used when the task of obtaining the app version number on the device fails to be executed.
}
});
}
FA Model Hmos - Wearable Side:
Please refer to: P2pClient.ping
// Step 1: Create a P2P communication object.
var p2pClient = new P2pClient();
var peerPkgName = "com.*.*";
// Step 2: Set the package name of your phone app to be communicated with.
p2pClient.setPeerPkgName(peerPkgName);
// Step 3: Check whether your app has been installed on the phone.
p2pClient.ping({
onSuccess: function() {
console.log('ping success.');
},
onFailure: function() {
console.log('ping failed');
},
onPingResult: function(resultCode) {
console.log(resultCode.data + resultCode.code);
},
});
Stage Model Hmos - Wearable Side:
Please refer to: P2pClient
import { wearEngine } from '@kit.WearEngine';
import { BusinessError } from '@kit.BasicServicesKit';
let deviceClient: wearEngine.DeviceClient = wearEngine.getDeviceClient(this.getUIContext().getHostContext());
let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(this.getUIContext().getHostContext());
let deviceList: wearEngine.Device[] = await deviceClient.getConnectedDevices();
deviceList.forEach(async (device, idx, arr) => {
// Select the device that supports app installation.
if (await device.isDeviceCapabilitySupported(wearEngine.DeviceCapability.APP_INSTALLATION)) {
// Define the device-side app bundle name as remoteBundleName.
let remoteBundleName: string = '';
p2pClient.isRemoteAppInstalled(device.randomId, remoteBundleName).then((isInstall) => {
console.info(`Succeeded in checking remote app install, result is ${isInstall}.`);
}).catch((error: BusinessError) => {
console.error(`Failed to check remote app install. Code is ${error.code}, message is ${error.message}.`);
})
}
if (idx === deviceList.length - 1) {
// An error is thrown if the target device does not exist.
throw new Error('cannot find target device');
}
})
Step 5: Implement Message Sending
Android to Wearable:
Please refer to: Sending P2P Messages
// Step 2: Send a message.
String messageStr = "Hello, Wear Engine!";
Message.Builder builder = new Message.Builder();
builder.setPayload(messageStr.getBytes(StandardCharsets.UTF_8));
Message sendMessage = builder.build();
// Step 3: Obtain the P2P communication object.
P2pClient p2pClient = HiWear.getP2pClient(this);
// Step 4: Specify the package name of your wearable app to be communicated with.
String peerPkgName = "com.*.*";
p2pClient.setPeerPkgName(peerPkgName);
// Step 5: Specify the signing certificate fingerprint of your wearable app to be communicated with. The maximum length of the fingerprint on the lite wearable device is 127 bits.
String peerFingerPrint = "*******";
p2pClient.setPeerFingerPrint(peerFingerPrint);
// Step 6: Send short messages from your phone app to the wearable app.
// Create the callback method.
SendCallback sendCallback = new SendCallback() {
@Override
public void onSendResult(int resultCode) {
// If the resultCode value is 207, the messages have been sent successfully. Other values indicate that the messages fail to be sent.
}
@Override
public void onSendProgress(long progress) {
}
};
if(connectedDevice != null && connectedDevice.isConnected() && sendMessage != null && sendCallback != null){
p2pClient.send(connectedDevice, sendMessage, sendCallback)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void successVoid) {
// Related processing logic for your app after the send task is successfully executed.
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// Related processing logic for your app after the send task fails.
}
});
}
FA Model Wearable to Android:
Please refer to: P2P Send Message
// Step 1: Create a P2P communication object.
var p2pClient = new P2pClient();
var peerPkgName = "com.*.*";
var peerFinger = "67DFB7FD********";
// Step 2: Set the package name of your phone app to be communicated with.
p2pClient.setPeerPkgName(peerPkgName);
// Step 3: Set the app fingerprint information on the phone.
p2pClient.setPeerFingerPrint(peerFinger);
// Step 4: Send a short message to your phone app.
// Build a Builder object.
var builderClient = new Builder();
var messageStr = "Hello, Wear Engine!";
builderClient.setDescription(messageStr);
// Build a Message object
var sendMessage = new Message();
sendMessage.builder = builderClient;
// Define the callback function.
var sendCallback = {
onSuccess: function() {
// Related processing logic for your app after the send task is successfully executed.
},
onFailure: function() {
// Related processing logic for your app after the send task fails.
},
onSendResult: function(resultCode) {
// Process the result code and information returned after the send task is complete.
console.log(resultCode.data + resultCode.code);
},
}
if(sendMessage != null && sendCallback != null){
p2pClient.send(sendMessage, sendCallback);
};
Stage Model Wearable to Android
Please refer to: P2P Send Message
import { wearEngine } from '@kit.WearEngine';
import { BusinessError } from '@kit.BasicServicesKit';
import { util } from '@kit.ArkTS';
let deviceClient: wearEngine.DeviceClient = wearEngine.getDeviceClient(this.getUIContext().getHostContext());
let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(this.getUIContext().getHostContext());
let deviceList: wearEngine.Device[] = await deviceClient.getConnectedDevices();
deviceList.forEach(async (device, idx, arr) => {
// Select the device that supports app installation.
if (await device.isDeviceCapabilitySupported(wearEngine.DeviceCapability.APP_INSTALLATION)) {
// Set the device-side app information, including the bundle name and fingerprint.
let appInfo: wearEngine.AppInfo = {
bundleName: '',
fingerprint: ''
}
// Define the device-side app parameter class as appParam.
let appParam: wearEngine.P2pAppParam = {
remoteApp: appInfo
// The default value of transformLocalAppInfo is false, indicating that the bundle name and fingerprint are not converted.
}
// Set the message to be sent.
let messageContent: string = 'this is message';
let textEncoder: util.TextEncoder = new util.TextEncoder;
let message: wearEngine.P2pMessage = {
content: textEncoder.encodeInto(messageContent)
}
p2pClient.sendMessage(device.randomId, appParam, message).then((p2pResult) => {
console.info(`Succeeded in sending message, result is ${p2pResult.code}.`);
}).catch((error: BusinessError) => {
console.error(`Failed to send message. Code is ${error.code}, message is ${error.message}.`);
})
}
if (idx === deviceList.length - 1) {
// An error is thrown if the target device does not exist.
throw new Error('cannot find target device');
}
})
Step 5: Set Up Message Receivers
Android Receiver:
Please refer to: P2P Receiver Android
Receiver receiver = new Receiver() {
@Override
public void onReceiveMessage(Message message) {
if (message.getType() == Message.MESSAGE_TYPE_DATA) {
// Process messages sent by your wearable app.
} else if (message.getType() == Message.MESSAGE_TYPE_FILE) {
// Process the file sent by your wearable app.
}
}
};
FA Model Wearable Receiver:
Please refer to: P2P Receiver FA
// Step 1: Create a P2P communication object.
var p2pClient = new P2pClient();
var peerPkgName = "com.*.*";
var peerFinger = "67DFB7FD********";
// Step 2: Set the package name of your phone app to be communicated with.
p2pClient.setPeerPkgName(peerPkgName);
// Step 3: Set the app fingerprint information on the phone.
p2pClient.setPeerFingerPrint(peerFinger);
// Step 4: Receive short messages or files from your phone app.
// Define the receiver
var flash = this;
var receiver = {
onSuccess: function() {
// Process the callback function returned when messages or files have been received from the phone during registration.
flash.receiveMessageOK="Succeeded in receiving the message";
},
onFailure: function() {
// Process the callback function returned when messages or files fail to be received from the phone during registration.
flash.receiveMessageOK="Failed to receive the message";
},
onReceiveMessage: function (data) {
if (data && data.isFileType) {
// Process the file sent by your phone app.
flash.receiveMessageOK = "file:"+data.name;
} else {
// Process the message sent from your phone app.
flash.receiveMessageOK = "message:"+data;
}
},
}
p2pClient.registerReceiver(receiver);
// Step 5: Cancel the reception of messages or files from your phone app.
p2pClient.unregisterReceiver({
onSuccess:function() {
console.log = ("Stopped receiving messages");
},
onFailure:function() {
console.log = ("Failed to stop receiving messages");
}
});
Stage Model Wearable Receiver:
Please refer to: P2P Receiver Stage
import { wearEngine } from '@kit.WearEngine';
import { BusinessError } from '@kit.BasicServicesKit';
let deviceClient: wearEngine.DeviceClient = wearEngine.getDeviceClient(this.getUIContext().getHostContext());
let p2pClient: wearEngine.P2pClient = wearEngine.getP2pClient(this.getUIContext().getHostContext());
let deviceList: wearEngine.Device[] = await deviceClient.getConnectedDevices();
deviceList.forEach(async (device, idx, arr) => {
// Select the device that supports app installation.
if (await device.isDeviceCapabilitySupported(wearEngine.DeviceCapability.APP_INSTALLATION)) {
// Set the device-side app information, including the bundle name and fingerprint.
let appInfo: wearEngine.AppInfo = {
bundleName: '',
fingerprint: ''
}
// Define the device-side app parameter class as appParam.
let appParam: wearEngine.P2pAppParam = {
remoteApp: appInfo
// The default value of transformLocalAppInfo is false, indicating that the bundle name is not converted.
}
// Set information about the file to be sent.
let callback = (p2pMessage: wearEngine.P2pMessage) => {
console.info(`Succeeded in receiving message, the message is ${p2pMessage.content}.`)
}
p2pClient.registerMessageReceiver(device.randomId, appParam, callback).then(() => {
console.info(`Succeeded in registering message receiver.`);
}).catch((error: BusinessError) => {
console.error(`Failed to register message receiver. Code is ${error.code}, message is ${error.message}.`);
})
}
if (idx === deviceList.length - 1) {
// An error is thrown if the target device does not exist.
throw new Error('cannot find target device');
}
})
Analysis Conclusion
Critical Success Factors
- Proper Permission Management: DEVICE_MANAGER permission is mandatory
- Certificate Fingerprint Matching: Fingerprints must be correctly configured
- Package Name Consistency: Peer package names must match exactly
- Connection State Verification: Always check device connection before operations
- Lifecycle Management: Proper registration/unregistration of receivers
- Permission Management: The permissions you request must correspond to the permissions you've applied for in the developer console. Permission mismatches result in error code 1008500004.
- Data Format Conversion: Only binary data can be sent, so it is necessary to convert it into the corresponding format through textEncoder.encodeInto.
- Remote App Configuration: Configure the package name and appid of the current application on both the mobile phone side and the watch side. If not configured properly, errors such as 206 and 207 will occur.
- Early Permission Application: The permission review may take a long time. Even if expedited, it may take 3 to 5 days. Therefore, if you need to use this permission, you should apply for it as early as possible.
Common Failure Points
- Permission mismatch between requested and approved permissions (error 1008500004)
- Missing or incorrect wearEngineRemoteAppNameList configuration
- Attempting to send non-binary data without proper conversion
- Remote app not installed or not properly launched
- Incorrect bundleName or fingerprint configuration
Solution
Complete Implementation Template
Wearable App Implementation Example:
public class P2PCommunicationManager {
private P2pClient p2pClient;
private Device connectedDeice;
private static final String PEER_PKG_NAME = "com.example.wearableapp";
private static final String PEER_FINGERPRINT = "FINGERPRINT";
public void initializeP2P(Context context) {
p2pClient = HiWear.getP2pClient(context);
p2pClient.setPeerPkgName(PEER_PKG_NAME);
p2pClient.setPeerFingerPrint(PEER_FINGERPRINT);
}
public void sendMessage(String message) {
if (isDeviceReady()) {
Message.Builder builder = new Message.Builder();
builder.setPayload(message.getBytes(StandardCharsets.UTF_8));
Message sendMessage = builder.build();
p2pClient.send(connectedDevice, sendMessage, new SendCallback() {
@Override
public void onSendResult(int resultCode) {
handleSendResult(resultCode);
}
@Override
public void onSendProgress(long progress) {
// Handle progress
}
});
}
}
public void registerMessageReceiver() {
if (isDeviceReady()) {
Receiver receiver = new Receiver() {
@Override
public void onReceiveMessage(Message message) {
processReceivedMessage(message);
}
};
p2pClient.registerReceiver(connectedDevice, receiver);
}
}
private boolean isDeviceReady() {
return connectedDevice != null && connectedDevice.isConnected();
}
FA Model Wearable App Implementation Example:
var p2pClient = new P2pClient();
var messageClient = new Message();
var builderClient = new Builder();
export default {
data: {
},
onInit() {
p2pClient.setPeerPkgName("com.example.phoneapp");
p2pClient.setPeerFingerPrint("PEER_FINGERPRINT");
this.registerMessage()
},
onDestroy() {
this.unregisterMessage();
},
registerMessage() {
var flash = this;
console.log('Register message button click');
p2pClient.registerReceiver({
onSuccess: function () {
console.log('Message receive success');
},
onFailure: function () {
console.log('Message receive fail');
},
onReceiveMessage: function (data) {
if (data && data.isFileType) {
console.log("Receive file name:" + data.name);
} else {
console.log('Received message: ' + data);
}
},
});
},
unregisterMessage() {
p2pClient.unregisterReceiver({
onSuccess: function () {
console.log("Stop receiving messages is sent");
},
});
},
sendMessage() {
builderClient.setDescription("hello wearEngine");
messageClient.builder = builderClient;
p2pClient.send(messageClient, {
onSuccess: function () {
console.log("Message sent successfully");
},
onFailure: function () {
console.log("Failed to send message");
},
onSendResult: function (resultCode) {
console.log(resultCode.data + resultCode.code);
},
onSendProgress: function (count) {
console.log(count);
},
});
},
}
Stage Model Wearable App Implementation Example:
import { wearEngine } from '@kit.WearEngine';
import { BusinessError } from '@kit.BasicServicesKit';
import { util } from '@kit.ArkTS';
export class StageModelWearableP2PManager {
private deviceClient: wearEngine.DeviceClient;
private p2pClient: wearEngine.P2pClient;
private authClient: wearEngine.AuthClient;
private targetDevice: wearEngine.Device | null = null;
private appParam: wearEngine.P2pAppParam;
private isInitialized: boolean = false;
constructor(context: Context, phoneAppBundleName: string, phoneAppFingerprint: string) {
this.deviceClient = wearEngine.getDeviceClient(context);
this.p2pClient = wearEngine.getP2pClient(context);
this.authClient = wearEngine.getAuthClient(context);
// Set the phone app information
let appInfo: wearEngine.AppInfo = {
bundleName: phoneAppBundleName,
fingerprint: phoneAppFingerprint
};
this.appParam = {
remoteApp: appInfo,
transformLocalAppInfo: false
};
}
async initializeP2P(): Promise<boolean> {
try {
// Step 1: Request authorization
let request: wearEngine.AuthorizationRequest = {
permissions: [wearEngine.Permission.USER_STATUS]
};
await this.authClient.requestAuthorization(request);
console.info('Authorization granted successfully');
// Step 2: Get connected devices
let deviceList: wearEngine.Device[] = await this.deviceClient.getConnectedDevices();
console.info(`Found ${deviceList.length} connected devices`);
if (deviceList.length === 0) {
throw new Error('No connected devices found');
}
// Step 3: Find target device with app installation capability
for (let idx = 0; idx < deviceList.length; idx++) {
const device = deviceList[idx];
if (await device.isDeviceCapabilitySupported(wearEngine.DeviceCapability.APP_INSTALLATION)) {
this.targetDevice = device;
console.info(`Target device found: ${device.category}`);
break;
}
if (idx === deviceList.length - 1 && !this.targetDevice) {
throw new Error('Cannot find target device with app installation capability');
}
}
// Step 4: Check remote app installation
const isInstalled = await this.p2pClient.isRemoteAppInstalled(
this.targetDevice!.randomId,
this.appParam.remoteApp.bundleName
);
console.info(`Remote app installation status: ${isInstalled}`);
if (!isInstalled) {
console.warn('Remote app not installed');
// Optionally try to start the remote app
await this.startRemoteApp();
}
this.isInitialized = true;
return true;
} catch (error) {
console.error(`P2P initialization failed: ${error}`);
return false;
}
}
async sendMessage(messageContent: string): Promise<boolean> {
if (!this.isInitialized || !this.targetDevice) {
console.error('P2P not initialized or no target device');
return false;
}
try {
const textEncoder: util.TextEncoder = new util.TextEncoder();
const message: wearEngine.P2pMessage = {
content: textEncoder.encodeInto(messageContent)
};
const result = await this.p2pClient.sendMessage(
this.targetDevice.randomId,
this.appParam,
message
);
console.info(`Message sent successfully, result code: ${result.code}`);
return result.code === 0;
} catch (error) {
console.error(`Failed to send message: ${error}`);
return false;
}
}
async registerMessageReceiver(): Promise<boolean> {
if (!this.isInitialized || !this.targetDevice) {
console.error('P2P not initialized or no target device');
return false;
}
try {
const callback = (p2pMessage: wearEngine.P2pMessage) => {
const textDecoder = new util.TextDecoder();
const messageText = textDecoder.decodeWithStream(p2pMessage.content);
console.info(`Received message: ${messageText}`);
this.handleReceivedMessage(messageText);
};
await this.p2pClient.registerMessageReceiver(
this.targetDevice.randomId,
this.appParam,
callback
);
console.info('Message receiver registered successfully');
return true;
} catch (error) {
console.error(`Failed to register message receiver: ${error}`);
return false;
}
}
private async startRemoteApp(): Promise<boolean> {
if (!this.targetDevice) {
return false;
}
try {
const result = await this.p2pClient.startRemoteApp(
this.targetDevice.randomId,
this.appParam.remoteApp.bundleName
);
console.info(`Remote app start result: ${result.code}`);
return result.code === 0;
} catch (error) {
console.error(`Failed to start remote app: ${error}`);
return false;
}
}
private handleReceivedMessage(message: string) {
try {
// Try to parse as JSON, fallback to plain text
let data: any;
try {
data = JSON.parse(message);
} catch {
data = { type: 'text', content: message };
}
// Handle different message types
switch (data.type) {
case 'notification':
this.showNotification(data.content);
break;
case 'health_request':
this.sendHealthData();
break;
case 'command':
this.executeCommand(data.command);
break;
default:
console.info(`Received text message: ${message}`);
}
} catch (error) {
console.error(`Error handling received message: ${error}`);
}
}
private showNotification(content: string) {
console.info(`Showing notification: ${content}`);
// Implement notification display logic here
}
private async sendHealthData() {
const healthData = {
type: 'health_data',
heartRate: 72,
steps: 8500,
calories: 320,
timestamp: Date.now()
};
await this.sendMessage(JSON.stringify(healthData));
}
private executeCommand(command: string) {
console.info(`Executing command: ${command}`);
switch (command) {
case 'vibrate':
// Implement vibration
break;
case 'get_battery':
this.sendBatteryStatus();
break;
default:
console.warn(`Unknown command: ${command}`);
}
}
private async sendBatteryStatus() {
const batteryData = {
type: 'battery_status',
level: 85,
charging: false,
timestamp: Date.now()
};
await this.sendMessage(JSON.stringify(batteryData));
}
// Public method to send specific data types
async sendSensorData(sensorType: string, value: number): Promise<boolean> {
const sensorData = {
type: 'sensor_data',
sensorType: sensorType,
value: value,
timestamp: Date.now()
};
return await this.sendMessage(JSON.stringify(sensorData));
}
// Public method to check connection status
isConnected(): boolean {
return this.isInitialized && this.targetDevice !== null;
}
// Cleanup method
async cleanup(): Promise<void> {
try {
// Unregister receivers if needed
this.isInitialized = false;
this.targetDevice = null;
console.info('P2P cleanup completed');
} catch (error) {
console.error(`Cleanup error: ${error}`);
}
}
}
// Usage in Wearable App Main Class
export default class WearableMainAbility {
private p2pManager: StageModelWearableP2PManager | null = null;
onCreate() {
console.info('Wearable app created');
this.initializeP2P();
}
private async initializeP2P() {
try {
// Initialize P2P manager with phone app details
this.p2pManager = new StageModelWearableP2PManager(
getContext(this),
'com.example.phoneapp', // Phone app bundle name
'PHONE_APP_FINGERPRINT' // Phone app fingerprint
);
// Initialize connection
const success = await this.p2pManager.initializeP2P();
if (success) {
// Register message receiver
await this.p2pManager.registerMessageReceiver();
// Send initial status
const initialStatus = {
type: 'wearable_ready',
deviceModel: 'Huawei Watch GT',
appVersion: '1.0.0',
timestamp: Date.now()
};
await this.p2pManager.sendMessage(JSON.stringify(initialStatus));
console.info('Wearable P2P communication initialized successfully');
// Example: Send periodic health data
this.startPeriodicHealthUpdates();
} else {
console.error('Failed to initialize P2P communication');
}
} catch (error) {
console.error(`P2P initialization error: ${error}`);
}
}
private startPeriodicHealthUpdates() {
// Send health data every 30 seconds
setInterval(async () => {
if (this.p2pManager?.isConnected()) {
await this.p2pManager.sendSensorData('heart_rate', Math.floor(Math.random() * 40) + 60);
}
}, 30000);
}
onDestroy() {
console.info('Wearable app destroying');
this.p2pManager?.cleanup();
}
// Example method to handle user interactions
onUserButtonClick() {
if (this.p2pManager?.isConnected()) {
const userAction = {
type: 'user_action',
action: 'button_pressed',
timestamp: Date.now()
};
this.p2pManager.sendMessage(JSON.stringify(userAction));
}
}
}
Verification Result
Testing Checklist
- Developer Console Permissions: Applied for and approved WearEngine permissions (3-5 days processing time)
- Both apps installed and permissions granted
- Device connection established and verified
- Ping test successful (appropriate result codes returned)
- Message sending works in both directions
- File transfer functional within size limits
- Receivers properly registered and processing messages
- App launch via ping method functional (if applicable)
- Module Configuration: client_id and wearEngineRemoteAppNameList properly configured in module.json5
- Authorization Success: requestAuthorization() completes without error 1008500004
- Device Discovery: getConnectedDevices() returns the target wearable device
- Remote App Installation: isRemoteAppInstalled() returns true for the target bundle
- Binary Data Conversion: Messages are properly converted using textEncoder.encodeInto()
- Bidirectional Communication: Both send and receive operations working correctly
- Error Handling: Proper handling for common error codes (206, 207, 1008500004)
Expected Results
- Authorization callback succeeds with proper permissions
- Device discovery returns connected HarmonyOS wearable devices
- Remote app installation check returns appropriate status
- Message sending completes without exceptions
- Message receiver callback triggers on the target device
- Binary data converts properly using textEncoder.encodeInto()
Common Error Codes
- 1008500004: Permission mismatch between requested and approved permissions
- 206/207: Configuration errors with wearEngineRemoteAppNameList or bundleName
Related Documents or Links
Official Documentation
- Huawei Wear Engine SDK Documentation
WearEngine HMOS API Reference: https://developer.huawei.com/consumer/en/doc/harmonyos-references/wearengine_api
Developer Console: Huawei Developer AGC - Wear Engine Service
Top comments (0)