
鸿蒙 5 多端协同:手机与手表的数据通信实战
一、鸿蒙分布式通信基础框架
核心依赖配置
// build.gradle
dependencies {
implementation ‘com.huawei.ohos:distributed_scheduler:1.0.0.100’
implementation ‘com.huawei.ohos:distributed_data:1.0.0.100’
}
权限声明
<!-- config.json -->
“reqPermissions”: [
{
“name”: “ohos.permission.DISTRIBUTED_DATASYNC”,
“reason”: “分布式数据同步”
},
{
“name”: “ohos.permission.GET_DISTRIBUTED_DEVICE_INFO”,
“reason”: “获取分布式设备信息”
},
{
“name”: “ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE”,
“reason”: “监听设备状态变化”
}
]
二、设备发现与连接管理
设备发现控制器
public class DeviceManager {
private static final HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP, 0x00101, “DeviceManager”);
private IDeviceDiscoveryCallback discoveryCallback;
private IDeviceStateCallback stateCallback;
public void startDiscovery() {
DeviceDiscoveryManager discoveryManager =
DistributedScheduleManager.getDeviceDiscoveryManager();
// 设置发现过滤器
DeviceFilter filter = new DeviceFilter(IDeviceInfo.DEVICE_TYPE_WATCH);
discoveryCallback = new IDeviceDiscoveryCallback() {
@Override
public void onDeviceFound(DeviceInfo deviceInfo) {
HiLog.info(TAG, "发现设备: %{public}s", deviceInfo.getDeviceName());
if (deviceInfo.getDeviceType() == IDeviceInfo.DEVICE_TYPE_WATCH) {
connectDevice(deviceInfo);
}
}
@Override
public void onDiscoveryFailed(int reason) {
HiLog.error(TAG, "设备发现失败: %{public}d", reason);
}
};
// 开始发现设备
discoveryManager.startDiscovery(filter, discoveryCallback);
}
private void connectDevice(DeviceInfo device) {
DeviceConnectManager connectManager =
DistributedScheduleManager.getDeviceConnectManager();
stateCallback = new IDeviceStateCallback() {
@Override
public void onConnected(DeviceInfo device) {
HiLog.info(TAG, "设备已连接: %{public}s", device.getDeviceId());
}
@Override
public void onDisconnected(DeviceInfo device) {
HiLog.warn(TAG, "设备断开: %{public}s", device.getDeviceId());
}
};
// 发起连接
connectManager.connectDevice(device, stateCallback);
}
}
三、数据传输方案实现
-
小数据实时传输(<100KB)
public class MessageSender {
private static final HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP, 0x00101, “MessageSender”);public static void sendTextMessage(String deviceId, String message) {
DistributedDataManager dataManager = DistributedDataManager.getInstance();// 创建消息对象 MessageData messageData = new MessageData.Builder() .setId(UUID.randomUUID().toString()) .setPayload(message.getBytes(StandardCharsets.UTF_8)) .setPriority(MessageData.PRIORITY_HIGH) .build(); // 发送消息 dataManager.sendMessage(deviceId, messageData, new IMessageCallback() { @Override public void onSendSuccess(String messageId) { HiLog.info(TAG, "消息发送成功: %{public}s", messageId); } @Override public void onSendFailed(String messageId, int errorCode) { HiLog.error(TAG, "消息发送失败: %{public}s, 错误码: %{public}d", messageId, errorCode); } });
}
} -
大数据传输(>100KB)
public class FileTransferService {
public void transferHealthData(String deviceId, HealthData data) {
// 1. 序列化数据
String jsonData = new Gson().toJson(data);// 2. 创建本地临时文件 File file = new File(getContext().getFilesDir(), "health_data.json"); try (FileOutputStream fos = new FileOutputStream(file)) { fos.write(jsonData.getBytes()); } catch (IOException e) { HiLog.error(TAG, "文件创建失败: %{public}s", e.getMessage()); return; } // 3. 使用分布式文件系统传输 DistributedFileManager fileManager = DistributedScheduleManager.getDistributedFileManager(); TransferRequest request = new TransferRequest.Builder() .setFileName(file.getName()) .setFilePath(file.getAbsolutePath()) .setFileSize(file.length()) .setFileType(TransferRequest.FILE_TYPE_HEALTH) .build(); // 4. 发起传输 fileManager.transferFile(deviceId, request, new ITransferCallback() { @Override public void onProgress(long transferred, long total) { int percent = (int) ((transferred * 100) / total); HiLog.info(TAG, "传输进度: %{public}d%%", percent); } @Override public void onSuccess(String filePath) { HiLog.info(TAG, "文件传输成功: %{public}s", filePath); file.delete(); // 清理临时文件 } @Override public void onFailed(int errorCode) { HiLog.error(TAG, "文件传输失败: %{public}d", errorCode); } });
}
}
四、双向通信实现
手机端消息接收
public class PhoneMessageReceiver implements IMessageCallback {
@Override
public void onMessageReceived(MessageData messageData) {
String senderId = messageData.getSenderId();
String message = new String(messageData.getPayload(), StandardCharsets.UTF_8);HiLog.info(TAG, "来自%{public}s的消息: %{public}s", senderId, message); // 处理手表消息 if (messageData.getType() == MessageData.TYPE_HEART_RATE) { HeartRateData heartRate = parseHeartRate(message); updateHeartRateUI(heartRate); }
}
// 注册接收器
public void registerReceiver() {
DistributedDataManager.getInstance()
.registerMessageReceiver(this, MessageData.TYPE_DEFAULT);
}
}
手表端消息处理
public class WatchMessageHandler extends Ability {
private static final HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP, 0x00102, “WatchHandler”);@Override
public void onStart(Intent intent) {
super.onStart(intent);
registerMessageReceiver();
}private void registerMessageReceiver() {
DistributedDataManager dataManager = DistributedDataManager.getInstance();// 注册多种消息类型处理器 dataManager.registerMessageReceiver(new HeartRateCallback(), MessageData.TYPE_HEART_RATE_REQUEST); dataManager.registerMessageReceiver(new WeatherRequestCallback(), MessageData.TYPE_WEATHER_REQUEST);
}
private class HeartRateCallback implements IMessageCallback {
@Override
public void onMessageReceived(MessageData message) {
// 1. 获取当前心率数据
HealthDataManager manager = HealthDataManager.getInstance();
HeartRateData latestRate = manager.getLatestHeartRate();// 2. 发送回手机 sendHeartRateToPhone(message.getSenderId(), latestRate); } private void sendHeartRateToPhone(String deviceId, HeartRateData data) { MessageData.Builder builder = new MessageData.Builder() .setType(MessageData.TYPE_HEART_RATE) .setPayload(data.toJson().getBytes()); DistributedDataManager.getInstance() .sendMessage(deviceId, builder.build()); }
}
}
五、数据同步策略实现 -
分布式数据库同步
public class HealthDataSyncService {
private static final String TABLE_NAME = “health_data”;public void initSyncEnvironment() {
// 配置数据库
DistributedDatabaseConfig config = new DistributedDatabaseConfig.Builder()
.setDatabaseName(“health_db”)
.setKvStoreType(KVStoreType.DEVICE_COLLABORATION)
.setSchema(createSchema())
.build();// 创建分布式数据库 DistributedDatabaseManager dbManager = DistributedDatabaseManager.getInstance(); DistributedDatabase database = dbManager.createDatabase(context, config); // 设置同步策略 SyncStrategy strategy = new SyncStrategy.Builder() .setMode(SyncStrategy.SYNC_MODE_PUSH_PULL) // 双向同步 .setTriggerMode(SyncStrategy.TRIGGER_MODE_MANUAL) // 按需同步 .setDelayTime(1000) // 1秒延迟 .build(); database.setSyncStrategy(strategy);
}
public void syncHeartRateData(HeartRateData data) {
// 转换为ContentValues
ContentValues values = new ContentValues();
values.put(“timestamp”, data.getTimestamp());
values.put(“heart_rate”, data.getValue());// 插入数据并触发同步 database.insert(TABLE_NAME, values, new DatabaseCallback() { @Override public void onInsertComplete(int count) { // 手动触发同步 database.sync(new SyncCallback() { @Override public void onComplete(SyncStats stats) { HiLog.info(TAG, "同步完成: %{public}d条更新", stats.getTotalChanges()); } }); } });
}
}
六、最佳实践:健康数据协同案例
手机端完整实现
public class PhoneHealthApp extends AbilitySlice {
private DeviceManager deviceManager;
private String watchDeviceId;@Override
protected void onStart(Intent intent) {
super.onStart(intent);// 初始化设备管理器 deviceManager = new DeviceManager(); deviceManager.startDiscovery(); // 注册设备连接监听 deviceManager.setConnectionListener(new ConnectionListener() { @Override public void onDeviceConnected(String deviceId) { watchDeviceId = deviceId; // 发送请求获取当前心率 requestHeartRateUpdate(); // 配置自动同步 setupAutoSync(); } });
}
private void requestHeartRateUpdate() {
MessageData request = new MessageData.Builder()
.setType(MessageData.TYPE_HEART_RATE_REQUEST)
.setPriority(MessageData.PRIORITY_HIGH)
.build();DistributedDataManager.getInstance() .sendMessage(watchDeviceId, request);
}
private void setupAutoSync() {
// 每分钟自动同步历史数据
Timer syncTimer = new Timer();
syncTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
HealthDataSyncService syncService = new HealthDataSyncService();
syncService.syncLatestData(watchDeviceId);
}
}, 0, 60 * 1000); // 每分钟
}
}
手表端完整实现
public class WatchHealthService extends Ability {
private HeartRateMonitor heartRateMonitor;
private HealthDataSyncService syncService;@Override
public void onStart(Intent intent) {
super.onStart(intent);// 初始化心率监测 heartRateMonitor = new HeartRateMonitor(context); heartRateMonitor.start(); // 初始化数据同步服务 syncService = new HealthDataSyncService(); syncService.initSyncEnvironment(); // 注册消息处理器 WatchMessageHandler handler = new WatchMessageHandler(); handler.registerReceivers();
}
// 心率监听器
private class HeartRateListener implements HeartRateMonitor.Callback {
@Override
public void onHeartRateUpdated(HeartRateData data) {
// 本地存储
LocalDataStore.saveHeartRate(data);// 实时发送到手机 if (DeviceManager.isPhoneConnected()) { sendRealtimeData(data); } // 批量同步 syncService.syncHeartRateData(data); } private void sendRealtimeData(HeartRateData data) { MessageData message = new MessageData.Builder() .setType(MessageData.TYPE_HEART_RATE) .setPayload(data.toJson().getBytes()) .build(); String phoneId = DeviceManager.getConnectedPhoneId(); DistributedDataManager.getInstance() .sendMessage(phoneId, message); }
}
}
七、安全与性能优化 -
通信安全加固
public class SecurityManager {
// 数据加密传输
public static byte[] encryptData(byte[] rawData) {
try {
KeyGenerator keyGen = KeyGenerator.getInstance(“AES”);
keyGen.init(256);
SecretKey secretKey = keyGen.generateKey();Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); return cipher.doFinal(rawData); } catch (Exception e) { HiLog.error(TAG, "加密失败: %{public}s", e.getMessage()); return rawData; // 失败时返回原始数据 }
}
// 设备验证
public static boolean verifyDevice(String deviceId) {
try {
DeviceAuthManager authManager = DeviceAuthManager.getInstance();
DeviceVerifyInfo info = authManager.getDeviceVerifyInfo(deviceId);// 检查设备证书有效性 if (info.getValidTime() > System.currentTimeMillis()) { HiLog.warn(TAG, "设备证书过期: %{public}s", deviceId); return false; } // 检查设备是否在信任名单 return TrustedDeviceList.contains(deviceId); } catch (RemoteException e) { HiLog.error(TAG, "设备验证异常: %{public}s", e.getMessage()); return false; }
}
} -
性能优化策略
public class CommunicationOptimizer {
// 带宽自适应策略
public static void adaptBandwidth() {
NetworkCapabilities capabilities =
NetworkManager.getInstance().getNetworkCapabilities();int maxPacketSize; if (capabilities.hasBandwidth(NetworkCapabilities.BANDWIDTH_HIGH)) { maxPacketSize = 1024 * 50; // 50KB } else if (capabilities.hasBandwidth(NetworkCapabilities.BANDWIDTH_MEDIUM)) { maxPacketSize = 1024 * 20; // 20KB } else { maxPacketSize = 1024 * 5; // 5KB } DistributedDataManager.getInstance() .setMaxPacketSize(maxPacketSize);
}
// 自动重连机制
public static void setupAutoRetry(String deviceId) {
ConnectionRetryPolicy policy = new ConnectionRetryPolicy.Builder()
.setMaxAttempts(5) // 最大重试次数
.setBackoffMultiplier(1.5) // 退避乘数
.setInitialBackoff(3000) // 初始间隔3秒
.setMaxBackoff(60000) // 最大间隔60秒
.build();DeviceConnectManager.getInstance() .setRetryPolicy(deviceId, policy);
}
}
八、调试与测试工具 -
设备模拟器
public class DeviceSimulator {
// 模拟手表设备
public static void startPhoneSimulator() {
DistributedSimulatorManager simulator =
DistributedSimulatorManager.getInstance();SimulatorConfig config = new SimulatorConfig.Builder() .setDeviceType(IDeviceInfo.DEVICE_TYPE_PHONE) .setDeviceId("SIM-PHONE-001") .enableMessageReceive() .enableDataSync() .build(); simulator.startSimulator(config, new SimulatorCallback() { @Override public void onMessageReceived(SimulatedMessage message) { HiLog.info(TAG, "收到模拟消息: %{public}s", message.getContent()); } @Override public void onFileReceived(String filePath) { HiLog.info(TAG, "收到模拟文件: %{public}s", filePath); } });
}
} -
性能监控工具
public class PerformanceMonitor {
private static PerformanceMonitor instance;
private Map<String, StatData> stats = new HashMap<>();public static void logCommunication(String type, long startTime, long dataSize) {
long duration = System.currentTimeMillis() - startTime;StatData stat = stats.getOrDefault(type, new StatData()); stat.totalCount++; stat.totalSize += dataSize; stat.totalTime += duration; stats.put(type, stat);
}
public static void printReport() {
for (Map.Entry<String, StatData> entry : stats.entrySet()) {
String type = entry.getKey();
StatData stat = entry.getValue();double avgSize = stat.totalCount > 0 ? stat.totalSize / stat.totalCount : 0; double avgTime = stat.totalCount > 0 ? stat.totalTime / stat.totalCount : 0; double throughput = avgTime > 0 ? avgSize / avgTime * 1000 : 0; // KB/s HiLog.info(TAG, "[%{public}s] 传输统计: " + "总次数=%{public}d, " + "平均尺寸=%.2fKB, " + "平均耗时=%.2fms, " + "吞吐量=%.2fKB/s", type, stat.totalCount, avgSize/1024, avgTime, throughput/1024); }
}
}
九、总结:多端通信最佳实践
设备发现优化
// 使用过滤条件减少扫描范围
filter.setDeviceType(IDeviceInfo.DEVICE_TYPE_WATCH);
filter.setMaxDistance(10); // 10米内设备
数据传输策略选择
// 根据数据大小自动选择传输方式
if (dataSize < 100 * 1024) { // <100KB
sendViaMessageApi();
} else {
transferViaFileSystem();
}
关键性能指标监控
指标 目标值 监控方式
连接延迟 <200ms 连接事件计时
消息延迟 <500ms 消息时间戳对比
传输带宽 >100KB/s 传输速度监控
数据同步模式
// 按需同步替代全量同步
syncConfig.setStrategy(SyncStrategy.PUSH_ON_CHANGE);
安全增强措施
// 传输层加密
setTransmissionSecurityLevel(SECURITY_LEVEL_HIGH);
通过以上方案,鸿蒙系统可以实现高效可靠的手机-手表协同通信:
低延迟通信:平均消息延迟<500ms
高效数据传输:支持高达100KB/s的传输速度
智能设备管理:自动重连+带宽自适应
企业级安全:端到端加密传输
开发效率提升:分布式API简化开发
