鸿蒙跨设备剪贴板同步系统 原创

进修的泡芙
发布于 2025-6-18 22:11
浏览
0收藏

鸿蒙跨设备剪贴板同步系统

本文将基于HarmonyOS的分布式能力,实现一个跨设备剪贴板同步功能,允许用户在一台设备上复制内容后,在其他设备上直接粘贴使用。

技术架构
本地剪贴板监听:监控本地剪贴板变化

数据同步层:通过分布式数据管理实现内容同步

安全处理层:敏感内容过滤和加密传输

UI展示层:剪贴板历史记录和同步状态显示

完整代码实现
剪贴板数据模型定义

// model/ClipboardData.ts
export class ClipboardData {
id: string = ‘’; // 唯一标识
content: string = ‘’; // 剪贴板内容
contentType: ‘text’ ‘image’
‘url’ = ‘text’; // 内容类型
timestamp: number = 0; // 时间戳
sourceDevice: string = ‘’; // 来源设备
isSynced: boolean = false; // 是否已同步

constructor(data?: Partial<ClipboardData>) {
if (data) {
Object.assign(this, data);
if (!this.id) {
this.id = this.generateId();
if (!this.timestamp) {

    this.timestamp = Date.now();

}

private generateId(): string {

return 'clip-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);

// 内容摘要(用于显示)

get summary(): string {
if (this.contentType === ‘text’) {
return this.content.length > 30
this.content.substring(0, 30) + ‘…’

this.content;

return this.contentType === ‘image’ ? ‘[图片]’ : ‘[链接]’;

}

分布式剪贴板同步服务

// service/ClipboardSyncService.ts
import distributedData from ‘@ohos.data.distributedData’;
import deviceInfo from ‘@ohos.deviceInfo’;
import { ClipboardData } from ‘…/model/ClipboardData’;

const STORE_ID = ‘clipboard_sync_store’;
const CLIPBOARD_KEY_PREFIX = ‘clip_’;

export class ClipboardSyncService {
private kvManager: distributedData.KVManager;
private kvStore: distributedData.SingleKVStore;
private localDeviceId: string = deviceInfo.deviceId;

// 初始化分布式数据存储
async initialize() {
const config = {
bundleName: ‘com.example.clipboard’,
userInfo: {
userId: ‘clip_user’,
userType: distributedData.UserType.SAME_USER_ID
};

this.kvManager = distributedData.createKVManager(config);
const options = {
  createIfMissing: true,
  encrypt: true,  // 启用加密
  backup: false,
  autoSync: true,
  kvStoreType: distributedData.KVStoreType.SINGLE_VERSION
};

this.kvStore = await this.kvManager.getKVStore(STORE_ID, options);

// 订阅数据变更
this.kvStore.on('dataChange', distributedData.SubscribeType.SUBSCRIBE_TYPE_ALL, (data) => {
  this.handleDataChange(data);
});

// 处理数据变更

private handleDataChange(data: distributedData.ChangeNotification) {
if (data.insertEntries.length > 0) {
data.insertEntries.forEach(entry => {
if (entry.key.startsWith(CLIPBOARD_KEY_PREFIX)) {
const clipData: ClipboardData = JSON.parse(entry.value.value);
this.processNewClipboardData(clipData);
});

}

// 处理新剪贴板数据
private processNewClipboardData(data: ClipboardData) {
// 忽略来自本设备的数据
if (data.sourceDevice === this.localDeviceId) return;

// 更新AppStorage中的剪贴板数据
const history: ClipboardData[] = AppStorage.get('clipboardHistory') || [];
const newHistory = [data, ...history].slice(0, 50); // 保留最近50条
AppStorage.setOrCreate('clipboardHistory', newHistory);

// 自动设置到系统剪贴板
if (this.shouldAutoPaste(data)) {
  this.setSystemClipboard(data.content);

}

// 判断是否应该自动粘贴
private shouldAutoPaste(data: ClipboardData): boolean {
// 这里可以添加业务逻辑判断
return data.contentType === ‘text’ && data.content.length < 500;
// 设置系统剪贴板

private setSystemClipboard(content: string) {
// 实际项目中需要使用系统剪贴板API
console.log(‘设置剪贴板内容:’, content);
// 同步剪贴板内容

async syncClipboardContent(data: ClipboardData) {
data.sourceDevice = this.localDeviceId;
data.isSynced = true;
const clipKey = {CLIPBOARD_KEY_PREFIX}{data.id};
await this.kvStore.put(clipKey, JSON.stringify(data));

// 更新本地历史记录
const history: ClipboardData[] = AppStorage.get('clipboardHistory') || [];
const newHistory = [data, ...history].slice(0, 50);
AppStorage.setOrCreate('clipboardHistory', newHistory);

// 获取当前设备ID

getLocalDeviceId(): string {
return this.localDeviceId;
}

剪贴板监听服务

// service/ClipboardMonitorService.ts
import { ClipboardData } from ‘…/model/ClipboardData’;

export class ClipboardMonitorService {
private syncService: ClipboardSyncService;
private lastContent: string = ‘’;
private checkInterval: number = 0;

constructor(syncService: ClipboardSyncService) {
this.syncService = syncService;
// 开始监听剪贴板变化

startMonitoring() {
this.checkInterval = setInterval(() => {
this.checkClipboardChange();
}, 1000); // 每秒检查一次
// 停止监听

stopMonitoring() {
if (this.checkInterval) {
clearInterval(this.checkInterval);
this.checkInterval = 0;
}

// 检查剪贴板变化
private async checkClipboardChange() {
try {
// 实际项目中需要调用系统API获取剪贴板内容
const currentContent = await this.getSystemClipboard();

  if (currentContent && currentContent !== this.lastContent) {
    this.lastContent = currentContent;
    this.handleNewClipboardContent(currentContent);

} catch (err) {

  console.error('检查剪贴板失败:', err);

}

// 处理新剪贴板内容
private handleNewClipboardContent(content: string) {
const clipData = new ClipboardData({
content: content,
contentType: this.detectContentType(content)
});

this.syncService.syncClipboardContent(clipData);

// 检测内容类型

private detectContentType(content: string): ‘text’ ‘image’
‘url’ {
if (content.startsWith(‘http://’) || content.startsWith(‘https://’)) {
return ‘url’;
// 实际项目中需要更复杂的图像检测逻辑

return 'text';

// 获取系统剪贴板内容

private async getSystemClipboard(): Promise<string> {
// 实际项目中需要调用系统API
return Promise.resolve(‘’); // 模拟实现
}

剪贴板管理页面实现

// pages/ClipboardManagerPage.ets
import { ClipboardSyncService } from ‘…/service/ClipboardSyncService’;
import { ClipboardMonitorService } from ‘…/service/ClipboardMonitorService’;
import { ClipboardData } from ‘…/model/ClipboardData’;

@Entry
@Component
struct ClipboardManagerPage {
private syncService: ClipboardSyncService = new ClipboardSyncService();
private monitorService: ClipboardMonitorService;
@StorageLink(‘clipboardHistory’) clipboardHistory: ClipboardData[] = [];
@State isSynced: boolean = false;
@State autoSyncEnabled: boolean = true;

async aboutToAppear() {
await this.syncService.initialize();
this.isSynced = true;

this.monitorService = new ClipboardMonitorService(this.syncService);
this.monitorService.startMonitoring();

onPageHide() {

this.monitorService.stopMonitoring();

build() {

Column() {
  // 标题和设置
  Row() {
    Text('跨设备剪贴板')
      .fontSize(24)
      .fontWeight(FontWeight.Bold)
      .layoutWeight(1)
    
    Toggle({ type: ToggleType.Switch, isOn: this.autoSyncEnabled })
      .onChange((isOn: boolean) => {
        this.autoSyncEnabled = isOn;
      })

.padding(16)

  .width('100%')

  // 同步状态
  Row() {
    Circle()
      .width(10)
      .height(10)
      .fill(this.isSynced ? '#4CAF50' : '#F44336')
      .margin({ right: 5 })
    
    Text(this.isSynced ? '已连接' : '连接中...')
      .fontSize(14)
      .fontColor('#666666')

.margin({ bottom: 16 })

  // 剪贴板历史记录
  List() {
    ForEach(this.clipboardHistory, (item: ClipboardData) => {
      ListItem() {
        ClipboardItem({
          data: item,
          onTap: () => this.copyToClipboard(item)
        })

})

.layoutWeight(1)

  .width('100%')

.width(‘100%’)

.height('100%')

// 复制内容到剪贴板

private copyToClipboard(data: ClipboardData) {
// 实际项目中需要调用系统API
console.log(‘复制内容:’, data.content);
prompt.showToast({ message: '已复制: ’ + data.summary, duration: 2000 });
}

@Component
struct ClipboardItem {
@Prop data: ClipboardData;
@Prop onTap: () => void;

build() {
Row() {
Column() {
Text(this.data.summary)
.fontSize(16)
.fontColor(‘#333333’)

    Row() {
      Text(this.data.sourceDevice === AppStorage.get('localDeviceId') ? '本设备' : '其他设备')
        .fontSize(12)
        .fontColor('#666666')
      
      Text(this.formatTime(this.data.timestamp))
        .fontSize(12)
        .fontColor('#666666')
        .margin({ left: 8 })

.margin({ top: 4 })

.layoutWeight(1)

  Image($r('app.media.ic_copy'))
    .width(24)
    .height(24)

.padding(16)

.width('100%')
.backgroundColor('#FFFFFF')
.borderRadius(8)
.margin({ bottom: 8 })
.onClick(() => {
  this.onTap();
})

// 格式化时间显示

private formatTime(timestamp: number): string {
const date = new Date(timestamp);
return {date.getHours().toString().padStart(2, ‘0’)}:{date.getMinutes().toString().padStart(2, ‘0’)};
}

实现原理详解
剪贴板监听机制:

定期检查系统剪贴板内容变化

发现新内容后创建ClipboardData对象

通过分布式服务同步到其他设备
数据同步流程:

使用加密的分布式数据库存储剪贴板内容

设备间自动同步最新剪贴板条目

可选自动粘贴功能
安全与隐私:

敏感内容过滤

传输加密

本地历史记录限制

扩展功能建议
内容加密传输:

  // 加密剪贴板内容

async encryptContent(content: string): Promise<string> {
const crypto = require(‘@ohos.security.crypto’);
const cipher = await crypto.createCipher(‘AES-GCM’);
const encrypted = await cipher.encrypt(content);
return encrypted;

敏感内容检测:

  // 检测敏感内容

function containsSensitiveInfo(content: string): boolean {
const patterns = [/\bpassword\b/i, /\bcredit\b/i, /\bcard\b/i];
return patterns.some(pattern => pattern.test(content));

设备白名单控制:

  // 设备白名单检查

function isAllowedDevice(deviceId: string): boolean {
const allowedDevices = AppStorage.get(‘allowedDevices’) || [];
return allowedDevices.includes(deviceId);

总结

本文展示了如何利用HarmonyOS的分布式能力构建一个跨设备剪贴板同步系统。通过监听本地剪贴板变化并将内容同步到分布式数据库,实现了在多设备间无缝共享剪贴板内容的功能。

该方案不仅支持文本内容,还可以扩展支持图片、链接等多种类型。通过合理的安全控制措施,可以在提供便利的同时保护用户隐私和数据安全。这种架构可以广泛应用于多设备协同工作场景,大幅提升工作效率。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报
回复
    相关推荐