HarmonyOS Sample 之 Pasteboard 分布式粘贴板

开发 分布式 OpenHarmony
HarmonyOS提供系统剪贴板服务的操作接口,支持用户程序从系统剪贴板中读取、写入和查询剪贴板数据,以及添加、移除系统剪贴板数据变化的回调。

[[435097]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

一、介绍

HarmonyOS提供系统剪贴板服务的操作接口,支持用户程序从系统剪贴板中读取、写入和查询剪贴板数据,以及添加、移除系统剪贴板数据变化的回调。

设备内:

用户通过系统剪贴板服务,可实现应用之间的简单数据传递。例如:在应用A中复制的数据,可以在应用B中粘贴,反之亦可。

设备间:

在分布式粘贴板场景中,粘贴的数据可以跨设备写入。例如,设备A上的应用程序使用系统粘贴板接口将从设备A复制的数据通过IDL接口存储到设备B的系统粘贴板中。如果数据允许,设备B上的应用程序可以读取并粘贴系统粘贴板中的复制数据。实现设备之间粘贴板的分布式协同。

基于以上理解,实现一个分布式粘贴板应用程序,应用程序分为客户端(copy)和服务端(paste)两部分,通过idl实现数据传递。

客户端负责数据采集,服务端负责数据的展示和应用,客户端和服务端可以安装在同一台设备中,也可以安装在不同的设备中,服务端也可以按照在多台设备中,服务端通过分布式数据库实现粘贴板数据的自动同步。

二、效果展示

HarmonyOS Sample 之 Pasteboard 分布式粘贴板-鸿蒙HarmonyOS技术社区
HarmonyOS Sample 之 Pasteboard 分布式粘贴板-鸿蒙HarmonyOS技术社区

三、搭建环境

安装DevEco Studio,详情请参考DevEco Studio下载

设置DevEco Studio开发环境,DevEco Studio开发环境需要依赖于网络环境,需要连接上网络才能确保工具的正常使用,可以根据如下两种情况来配置开发环境:

如果可以直接访问Internet,只需进行下载HarmonyOS SDK操作。

如果网络不能直接访问Internet,需要通过代理服务器才可以访问,请参考配置开发环境

下载源码后,使用DevEco Studio 打开项目,模拟器运行即可。

真机运行需要将config.json中的buddleName修改为自己的,如果没有请到AGC上进行配置,参见 使用模拟器进行调试

四、项目结构

HarmonyOS Sample 之 Pasteboard 分布式粘贴板-鸿蒙HarmonyOS技术社区
HarmonyOS Sample 之 Pasteboard 分布式粘贴板-鸿蒙HarmonyOS技术社区

五、代码讲解

5.1 系统粘贴板基础功能介绍

系统粘贴板对象介绍

1.SystemPasteboard //系统粘贴板对象,定义系统粘贴板操作,包括复制、粘贴和设置粘贴板内容更改的侦听器。

2.PasteData//表示粘贴板上的粘贴数据。

3.PasteData.DataProperty //该类定义了系统粘贴板上 PasteData 的属性,包括时间戳、MIME 类型和其他属性数据。

4.PasteData.Record//该类将单个粘贴的数据定义为 Record,它可以是纯文本、HTML 文本、URI 和意图。 PasteData 对象包含一个或多个记录。

客户端(copy)CopyAbilitySlice.java

获取系统粘贴板,监听粘贴板数据变化

  1. /** 
  2.  * 获取系统粘贴板 
  3.  * 监听粘贴板数据变化 
  4.  */ 
  5. private void initPasteboard() { 
  6.     HiLog.debug(LABEL, "initPasteboard"); 
  7.     //获取系统粘贴板对象 
  8.     pasteboard = SystemPasteboard.getSystemPasteboard(this); 
  9.     //监听粘贴板数据变化 
  10.     pasteboard.addPasteDataChangedListener(() -> { 
  11.         if (pasteboard.hasPasteData()) { 
  12.             sync_text = getPasteData(); 
  13.             HiLog.debug(LABEL, "%{public}s""pasteStr:" + sync_text); 
  14.         } 
  15.     }); 

获取粘贴板内容

  1. /** 
  2.  * 获取粘贴板记录 
  3.  * 
  4.  * @return 
  5.  */ 
  6. private String getPasteData() { 
  7.     HiLog.debug(LABEL, "getPasteData"); 
  8.     String result = ""
  9.  
  10.     //粘贴板数据对象 
  11.     PasteData pasteData = pasteboard.getPasteData(); 
  12.     if (pasteData == null) { 
  13.         return result; 
  14.     } 
  15.     PasteData.DataProperty dataProperty = pasteData.getProperty(); 
  16.     // 
  17.     boolean hasHtml = dataProperty.hasMimeType(PasteData.MIMETYPE_TEXT_HTML); 
  18.     boolean hasText = dataProperty.hasMimeType(PasteData.MIMETYPE_TEXT_PLAIN); 
  19.  
  20.     //数据格式类型 
  21.     if (hasHtml || hasText) { 
  22.         for (int i = 0; i < pasteData.getRecordCount(); i++) { 
  23.             //粘贴板数据记录 
  24.             PasteData.Record record = pasteData.getRecordAt(i); 
  25.             //不同类型获取方式不同 
  26.             String mimeType = record.getMimeType(); 
  27.             //HTML文本 
  28.             if (mimeType.equals(PasteData.MIMETYPE_TEXT_HTML)) { 
  29.                 result = record.getHtmlText(); 
  30.                 //纯文本 
  31.             } else if (mimeType.equals(PasteData.MIMETYPE_TEXT_PLAIN)) { 
  32.                 result = record.getPlainText().toString(); 
  33.                 // 
  34.             } else { 
  35.                 HiLog.info(LABEL, "%{public}s""getPasteData mimeType :" + mimeType); 
  36.             } 
  37.         } 
  38.     } 
  39.     return result; 

设置文本到粘贴板中

  1. /** 
  2.  * 设置文本到粘贴板 
  3.  * 
  4.  * @param component 
  5.  */ 
  6. private void setTextToPaste(Component component) { 
  7.     HiLog.info(LABEL, "setTextToPaste"); 
  8.     if (pasteboard != null) { 
  9.         String text = syncText.getText(); 
  10.         if (text.isEmpty()) { 
  11.             showTips(this, "请填写内容"); 
  12.             return
  13.         } 
  14.         //把记录添加到粘贴板 
  15.         PasteData pasteData=  PasteData.creatPlainTextData(text); 
  16.         //设置文本到粘贴板 
  17.         pasteboard.setPasteData(pasteData); 
  18.  
  19.         showTips(this, "复制成功"); 
  20.         HiLog.info(LABEL, "setTextToPaste succeeded"); 
  21.     } 

清空粘贴板

  1. /** 
  2.  * 清空粘贴板 
  3.  * 
  4.  * @param component 
  5.  */ 
  6. private void clearPasteboard(Component component) { 
  7.     if (pasteboard != null) { 
  8.         pasteboard.clear(); 
  9.         showTips(this, "Clear succeeded"); 
  10.     } 

5.2 分布式粘贴板应用构建思路介绍

HarmonyOS Sample 之 Pasteboard 分布式粘贴板-鸿蒙HarmonyOS技术社区

选择远端连接设备

本实例是通过新增加一个DevicesSelectAbility来实现的。

  1. private void showDevicesDialog() { 
  2.     Intent intent = new Intent(); 
  3.     //打开选择设备的Ability页面DevicesSelectAbility 
  4.     Operation operation = 
  5.             new Intent.OperationBuilder() 
  6.                     .withDeviceId(""
  7.                     .withBundleName(getBundleName()) 
  8.                     .withAbilityName(DevicesSelectAbility.class) 
  9.                     .build(); 
  10.     intent.setOperation(operation); 
  11.     //携带一个设备选择请求标识,打开设备选择页面(DevicesSelectAbility) TODO 
  12.     startAbilityForResult(intent, Constants.PRESENT_SELECT_DEVICES_REQUEST_CODE); 
  13.  
  14. /** 
  15.  * 打开设备选择Ability后,选择连接的设备执行setResult后触发 
  16.  * 
  17.  * @param requestCode 
  18.  * @param resultCode 
  19.  * @param resultIntent 
  20.  */ 
  21. @Override 
  22. protected void onAbilityResult(int requestCode, int resultCode, Intent resultIntent) { 
  23.     HiLog.debug(LABEL, "onAbilityResult"); 
  24.     if (requestCode == Constants.PRESENT_SELECT_DEVICES_REQUEST_CODE && resultIntent != null) { 
  25.         //获取用户选择的设备 
  26.         String devicesId = resultIntent.getStringParam(Constants.PARAM_DEVICE_ID); 
  27.         //连接粘贴板服务端 
  28.         connectService(devicesId); 
  29.         return
  30.     } 

连接粘贴板服务端ServiceAbility服务

idl文件放在ohos.samples.pasteboard.paste目录下,Gradl窗口,执行compileDebugIdl 后,系统生成代理对象。

  1. interface ohos.samples.pasteboard.paste.ISharePasteAgent { 
  2.     /* 
  3.      * 设置系统粘贴板 
  4.      */ 
  5.     void setSystemPaste([in] String param); 

连接服务端ServiceAbility,如果组网中没有其他设备就连接本地的服务端。

连接成功后,初始化idl的SharePasteAgentProxy代理,用于下一步的同步数据。

  1. //idl共享粘贴板代理 
  2. private SharePasteAgentProxy remoteAgentProxy; 
  3.  
  4. /** 
  5.  * 连接粘贴板服务中心 
  6.  */ 
  7. private void connectService(String deviceId) { 
  8.     HiLog.debug(LABEL, "%{public}s""connectService"); 
  9.     if (!isConnect) { 
  10.         boolean isConnectRemote = deviceId != null
  11.         //三元表达式,判断连接本地还是远端Service 
  12.         Intent intent = isConnectRemote 
  13.                 ? getRemoteServiceIntent(REMOTE_BUNDLE, REMOTE_SERVICE, deviceId) 
  14.                 : getLocalServiceIntent(REMOTE_BUNDLE, REMOTE_SERVICE); 
  15.  
  16.         HiLog.debug(LABEL, "%{public}s""intent:" + intent); 
  17.         //连接 Service 
  18.         connectAbility(intent, new IAbilityConnection() { 
  19.             @Override 
  20.             public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int resultCode) { 
  21.                 //发个通知,Service 连接成功了 
  22.                 eventHandler.sendEvent(EVENT_ABILITY_CONNECT_DONE); 
  23.                 //初始化代理 
  24.                 remoteAgentProxy = new SharePasteAgentProxy(iRemoteObject); 
  25.                 HiLog.debug(LABEL, "%{public}s""remoteAgentProxy:" + remoteAgentProxy); 
  26.             } 
  27.  
  28.             @Override 
  29.             public void onAbilityDisconnectDone(ElementName elementName, int resultCode) { 
  30.                 //发个通知,Service 断开连接了,主动断开不会执行,关闭服务端会执行 
  31.                 eventHandler.sendEvent(EVENT_ABILITY_DISCONNECT_DONE); 
  32.             } 
  33.         }); 
  34.     } 
  35. /** 
  36.  * 获取远端粘贴板服务中心 
  37.  * 
  38.  * @param bundleName 
  39.  * @param serviceName 
  40.  * @return 
  41.  */ 
  42. private Intent getRemoteServiceIntent(String bundleName, String serviceName, String deviceId) { 
  43.     HiLog.debug(LABEL, "%{public}s""getRemoteServiceIntent"); 
  44.     Operation operation = new Intent.OperationBuilder() 
  45.             .withDeviceId(deviceId) 
  46.             .withBundleName(bundleName) 
  47.             .withAbilityName(serviceName) 
  48.             //重要 
  49.             .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE) 
  50.             .build(); 
  51.     Intent intent = new Intent(); 
  52.     intent.setOperation(operation); 
  53.     return intent; 
  54.  
  55. /** 
  56.  * 获取本地粘贴板服务中心 
  57.  * 
  58.  * @param bundleName 
  59.  * @param serviceName 
  60.  * @return 
  61.  */ 
  62. private Intent getLocalServiceIntent(String bundleName, String serviceName) { 
  63.     HiLog.debug(LABEL, "%{public}s""getLocalServiceIntent"); 
  64.     Operation operation = new Intent.OperationBuilder().withDeviceId(""
  65.             .withBundleName(bundleName) 
  66.             .withAbilityName(serviceName) 
  67.             .build(); 
  68.     Intent intent = new Intent(); 
  69.     intent.setOperation(operation); 
  70.     return intent; 

同步数据到服务端

  1. /** 
  2.  * 同步粘贴板记录到粘贴板服务中心 
  3.  * 
  4.  * @param component 
  5.  */ 
  6. private void syncData(Component component) { 
  7.     HiLog.debug(LABEL, "sync_text:" + sync_text); 
  8.     if (!sync_text.isEmpty()) { 
  9.         if (isConnect && remoteAgentProxy != null) { 
  10.             //调用服务端IPC方法 
  11.             try { 
  12.                 remoteAgentProxy.setSystemPaste(sync_text); 
  13.                 //更换文本 
  14.                 syncText.setText(getRandomText()); 
  15.                 sync_text = ""
  16.                 showTips(this, "同步成功"); 
  17.             } catch (RemoteException remoteException) { 
  18.                 remoteException.printStackTrace(); 
  19.             } 
  20.         } else { 
  21.             showTips(this, "正在连接设备"); 
  22.         } 
  23.     } else { 
  24.         showTips(this, "点击复制到粘贴板"); 
  25.     } 

随机生成粘贴文本

  1. /** 
  2.  * 随机文本,模拟数据 
  3.  * 
  4.  * @return 
  5.  */ 
  6. public String getRandomText() { 
  7.     List<String> list = Arrays.asList( 
  8.             "快马加鞭未下鞍,离天三尺三"
  9.             "我自横刀向天笑,去留肝胆两昆仑"
  10.             "飞流直下三千尺,疑是银河落九天"
  11.             "君子求诸己,小人求诸人"
  12.             "吾日三省吾身:为人谋而不忠乎?与朋友交而不信乎?传不习乎?"); 
  13.     int random = new SecureRandom().nextInt(list.size()); 
  14.     return list.get(random); 

服务端(paste)ServiceAbility.java

设置粘贴板服务

idl文件放在ohos.samples.pasteboard.paste目录下,Gradl窗口,执行compileDebugIdl 后,系统生成代理对象,idl提供了setSystemPaste接口供远端调用。

  1. interface ohos.samples.pasteboard.paste.ISharePasteAgent { 
  2.     /* 
  3.      * 设置系统粘贴板 
  4.      */ 
  5.     void setSystemPaste([in] String param); 
  1. //idl的服务端实现, 
  2. SharePasteAgentStub sharePasteAgentStub = new SharePasteAgentStub(DESCRIPTOR) { 
  3.     @Override 
  4.     public void setSystemPaste(String param) { 
  5.         HiLog.info(LABEL, "%{public}s""param:" + param); 
  6.  
  7.         //插入数据库 
  8.         ItemChild itemChild = new ItemChild(); 
  9.         String currentTime = DateUtils.getCurrentDate("yyMMdd HH:mm:ss"); 
  10.         itemChild.setWriteTime(currentTime); 
  11.         itemChild.setWriteContent(param); 
  12.         itemChild.setIndex(String.valueOf(UUID.randomUUID())); 
  13.         //默认添加到未分类 
  14.         itemChild.setTagName(Const.CATEGORY_TAG_UNCATEGOORIZED); 
  15.         //添加粘贴板记录到分布式数据库 
  16.         kvManagerUtils.addItemChild(itemChild); 
  17.  
  18.     } 
  19. }; 
  20.  
  21. @Override 
  22. protected IRemoteObject onConnect(Intent intent) { 
  23.     HiLog.info(LABEL, "%{public}s""ServiceAbility onConnect"); 
  24.     return sharePasteAgentStub; 
  25.  
  26. **初始化数据库** 
  27. ```java 
  28. //初始化数据库工具 
  29. kvManagerUtils = KvManagerUtils.getInstance(this); 
  30.  
  31. //初始化数据库管理对象 
  32. kvManagerUtils.initDbManager(eventHandler); 
  33.  
  34. //初始化数据库数据按钮 
  35. Image initDb = (Image) findComponentById(ResourceTable.Id_init_db); 
  36. initDb.setClickedListener(component -> { 
  37.     //默认选中“未定义”标签 
  38.     current_select_category_index = 0; 
  39.     //初始化数据库数据 
  40.     kvManagerUtils.initDbData(); 
  41.     showTip("初始化完成"); 
  42. }); 

初始化数据列表

  1. /** 
  2.  * 从分布式数据库中查询数据 
  3.  */ 
  4. public void queryData() { 
  5.     HiLog.debug(LABEL, "queryData"); 
  6.     try { 
  7.         //加载选中类别下的数据列表 
  8.         initItemChild(kvManagerUtils.queryDataByTag(CategoryData.tagList.get(current_select_category_index))); 
  9.     } catch (KvStoreException exception) { 
  10.         HiLog.info(LABEL, "the value must be String"); 
  11.     } 
  12.  
  13. /** 
  14.  * 初始化选中标签的子项列表 
  15.  * 
  16.  * @param itemChildList itemChildList, the bean of itemChild 
  17.  */ 
  18. private void initItemChild(List<ItemChild> itemChildList) { 
  19.     HiLog.debug(LABEL, "initItemChild:" + itemChildList); 
  20.     if (itemChildList == null) { 
  21.         return
  22.     } 
  23.     //清空组件 
  24.     itemChildLayout.removeAllComponents(); 
  25.     // Create itemChild 
  26.     for (ItemChild itemChild : itemChildList) { 
  27.         //获取子项类别所在的组件 
  28.         Component childComponent = 
  29.                 LayoutScatter.getInstance(this).parse(ResourceTable.Layout_paste_record_per, nullfalse); 
  30.         //写入时间 
  31.         Text writeTime = (Text) childComponent.findComponentById(ResourceTable.Id_writeTime); 
  32.         writeTime.setText(itemChild.getWriteTime()); 
  33.         //粘贴板内容 
  34.         Text writeContent = (Text) childComponent.findComponentById(ResourceTable.Id_writeContent); 
  35.         writeContent.setText(itemChild.getWriteContent()); 
  36.  
  37.         //复制按钮 
  38.         Text copy = (Text) childComponent.findComponentById(ResourceTable.Id_itemChildPerCopy); 
  39.         //复制按钮的监听事件 
  40.         copy.setClickedListener(component -> { 
  41.             //复制内容到粘贴板 
  42.             pasteboard.setPasteData(PasteData.creatPlainTextData(itemChild.getWriteContent())); 
  43.             showTip("已复制到粘贴板"); 
  44.         }); 
  45.  
  46.         //收藏按钮 
  47.         Text favorite = (Text) childComponent.findComponentById(ResourceTable.Id_itemChildPerFavorite); 
  48.         //收藏按钮的监听事件 
  49.         favorite.setClickedListener(component -> { 
  50.             //修改标签微已收藏 
  51.             itemChild.setTagName(Const.CATEGORY_TAG_FAVORITED); 
  52.             //保存数据 
  53.             kvManagerUtils.addItemChild(itemChild); 
  54.             showTip("已加入到收藏中"); 
  55.         }); 
  56.  
  57.  
  58.         /**************just for test********************/ 
  59.         //复选框 
  60.         Checkbox noteId = (Checkbox) childComponent.findComponentById(ResourceTable.Id_noteId); 
  61.         //子项列表的点击事件 
  62.         childComponent.setClickedListener(component -> { 
  63.             if (noteId.getVisibility() == Component.VISIBLE) { 
  64.                 noteId.setChecked(!noteId.isChecked()); 
  65.             } 
  66.         }); 
  67.         //子项列表的长按事件,长按显示复选框 
  68.         childComponent.setLongClickedListener(component -> { 
  69.             //checkbox显示 
  70.             noteId.setVisibility(Component.VISIBLE); 
  71.             //设置复选框样式,以及其他文本组件的缩进 
  72.             Element element = ElementScatter.getInstance(getContext()).parse(ResourceTable.Graphic_check_box_checked); 
  73.             noteId.setBackground(element); 
  74.             noteId.setChecked(true); 
  75.             writeTime.setMarginLeft(80); 
  76.             writeContent.setMarginLeft(80); 
  77.         }); 
  78.         //复选框的状态变化监听事件,state表示是否被选中 
  79.         noteId.setCheckedStateChangedListener((component, state) -> { 
  80.             // 状态改变的逻辑 
  81.             Element element; 
  82.             if (state) { 
  83.                 //设置选中的样式 
  84.                 element = ElementScatter.getInstance(getContext()) 
  85.                         .parse(ResourceTable.Graphic_check_box_checked); 
  86.             } else { 
  87.                 //设置未选中的样式 
  88.                 element = ElementScatter.getInstance(getContext()) 
  89.                         .parse(ResourceTable.Graphic_check_box_uncheck); 
  90.             } 
  91.             noteId.setBackground(element); 
  92.         }); 
  93.         /**************just for test********************/ 
  94.  
  95.         //添加子项列表组件到布局 
  96.         itemChildLayout.addComponent(childComponent); 
  97.     } 

标签分类显示

  1. //初始化列表列表的点击的监听事件 
  2. categoryList.setItemClickedListener( 
  3.         (listContainer, component, index, l1) -> { 
  4.             //点的就是当前类别 
  5.             if (categoryListProvider.getSelectIndex() == index) { 
  6.                 return
  7.             } 
  8.             //切换类别索引 
  9.             categoryListProvider.setSelectIndex(index); 
  10.             //设置选中的标签索引 
  11.             current_select_category_index = index
  12.             //获取当前选中的标签名称 
  13.             String tagName = CategoryData.tagList.get(index); 
  14.             //从数据库中查询标签子项列表 
  15.             initItemChild(kvManagerUtils.queryDataByTagAndKewWord(searchTextField.getText(), tagName)); 
  16.             //通知数据更新 
  17.             categoryListProvider.notifyDataChanged(); 
  18.             //滚动条到最顶部 
  19.             itemListScroll.fluentScrollYTo(0); 
  20.         }); 

搜索粘贴记录

  1. //搜索key监听事件 
  2. searchTextField.setKeyEventListener( 
  3.         (component, keyEvent) -> { 
  4.             if (keyEvent.isKeyDown() && keyEvent.getKeyCode() == KeyEvent.KEY_ENTER) { 
  5.                 //获取当前选中的标签名称 
  6.                 String tagName = CategoryData.tagList.get(current_select_category_index); 
  7.                 List<ItemChild> itemChildList = kvManagerUtils.queryDataByTagAndKewWord(searchTextField.getText(), tagName); 
  8.                 //从数据库中查询标签子项列表 
  9.                 initItemChild(itemChildList); 
  10.                 //通知数据更新 
  11.                 categoryListProvider.notifyDataChanged(); 
  12.                 //滚动条到最顶部 
  13.                 itemListScroll.fluentScrollYTo(0); 
  14.             } 
  15.             return false
  16.         }); 

分布式数据库工具KvManagerUtils.java

数据变化通知

提供了分布式数据库管理工具KvManagerUtils.java,数据库操作都集中在这里了。

为了在数据库数据发生变化时能及时更新页面显示,页面在初始化数据库时,传递eventHandler对象,这样在数据库变化是可以通知到页面。

  1. /** 
  2.  * 订阅数据库更改通知 
  3.  * @param singleKvStore Data operation 
  4.  */ 
  5. private void subscribeDb(SingleKvStore singleKvStore) { 
  6.     HiLog.info(LABEL, "subscribeDb"); 
  7.     //数据库观察者客户端 
  8.     KvStoreObserver kvStoreObserverClient = new KvStoreObserverClient(); 
  9.     //订阅远程数据更改 
  10.     singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_REMOTE, kvStoreObserverClient); 
  11.  
  12. /** 
  13.  * 自定义分布式数据库观察者客户端 
  14.  * 数据发生变化时触发对应函数 
  15.  * Receive database messages 
  16.  */ 
  17. private class KvStoreObserverClient implements KvStoreObserver { 
  18.     @Override 
  19.     public void onChange(ChangeNotification notification) { 
  20.         HiLog.error(LABEL, "onChange"); 
  21.         eventHandler.sendEvent(Const.DB_CHANGE_MESS); 
  22.     } 

数据自动同步

默认开启自动同步

  1. /** 
  2.  * Initializing Database Management 
  3.  * 初始化数据库管理员 
  4.  */ 
  5. public void initDbManager(EventHandler eventHandler) { 
  6.     this.eventHandler = eventHandler; 
  7.     HiLog.info(LABEL, "initDbManager"); 
  8.     if (singleKvStore == null || kvManager == null) { 
  9.         HiLog.info(LABEL, "initDbData"); 
  10.         //创建数据库管理员 
  11.         kvManager = createManager(); 
  12.         //创建数据库 
  13.         singleKvStore = createDb(kvManager); 
  14.         subscribeDb(singleKvStore); 
  15.  
  16.     } 
  17.  
  18.  
  19.  
  20. /** 
  21.  * Create a distributed database manager instance 
  22.  * 创建数据库管理员 
  23.  * 
  24.  * @return database manager 
  25.  */ 
  26. private KvManager createManager() { 
  27.     HiLog.info(LABEL, "createManager"); 
  28.     KvManager manager = null
  29.     try { 
  30.         // 
  31.         KvManagerConfig config = new KvManagerConfig(context); 
  32.         manager = KvManagerFactory.getInstance().createKvManager(config); 
  33.     } catch (KvStoreException exception) { 
  34.         HiLog.error(LABEL, "some exception happen"); 
  35.     } 
  36.     return manager; 
  37.  
  38. /** 
  39.  * Creating a Single-Version Distributed Database 
  40.  * 创建数据库 
  41.  * 
  42.  * @param kvManager Database management 
  43.  * @return SingleKvStore 
  44.  */ 
  45. private SingleKvStore createDb(KvManager kvManager) { 
  46.     HiLog.info(LABEL, "createDb"); 
  47.     SingleKvStore kvStore = null
  48.     try { 
  49.         Options options = new Options(); 
  50.         //单版本数据库,不加密,没有可用的 KvStore 数据库就创建 
  51.         //单版本分布式数据库,默认开启组网设备间自动同步功能, 
  52.         //如果应用对性能比较敏感建议设置关闭自动同步功能setAutoSync(false),主动调用sync接口同步。 
  53.         options.setCreateIfMissing(true
  54.                 .setEncrypt(false
  55.                 .setKvStoreType(KvStoreType.SINGLE_VERSION); 
  56.         //创建数据库 
  57.         kvStore = kvManager.getKvStore(options, STORE_ID); 
  58.  
  59.     } catch (KvStoreException exception) { 
  60.         HiLog.error(LABEL, "some exception happen"); 
  61.     } 
  62.     return kvStore; 

权限config.json

  1. "reqPermissions": [ 
  2.     { 
  3.       "name""ohos.permission.DISTRIBUTED_DATASYNC"
  4.       "reason""同步粘贴板数据"
  5.       "usedScene": { 
  6.         "when""inuse"
  7.         "ability": [ 
  8.           "ohos.samples.pasteboard.paste.MainAbility"
  9.           "ohos.samples.pasteboard.paste.ServiceAbility" 
  10.         ] 
  11.       } 
  12.     }, 
  13.     { 
  14.       "name""ohos.permission.GET_DISTRIBUTED_DEVICE_INFO" 
  15.     }, 
  16.     { 
  17.       "name""ohos.permission.KEEP_BACKGROUND_RUNNING" 
  18.     } 
  19.   ] 

六、思考总结

1.粘贴板板传递数据可能会存在安全问题,需要注意,要根据具体场景来使用。

设备内每次传输的粘贴数据大小不能超过 800 KB。每次设备间传输的数据不能超过64KB,且数据必须为文本格式。

2.idl的使用,在上述案例中,客户端(copy) 和 服务端(paste) 项目idl下内容完全一致即可。

HarmonyOS Sample 之 Pasteboard 分布式粘贴板-鸿蒙HarmonyOS技术社区
HarmonyOS Sample 之 Pasteboard 分布式粘贴板-鸿蒙HarmonyOS技术社区

七、完整代码

附件可以直接下载

https://harmonyos.51cto.com/resource/1489

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-12-10 15:06:56

鸿蒙HarmonyOS应用

2021-08-24 15:13:06

鸿蒙HarmonyOS应用

2021-10-21 10:03:09

鸿蒙HarmonyOS应用

2021-11-16 09:38:10

鸿蒙HarmonyOS应用

2018-02-08 16:45:22

前端JS粘贴板

2021-07-22 10:20:21

鸿蒙HarmonyOS应用

2021-07-23 08:57:32

鸿蒙HarmonyOS应用

2023-02-06 07:17:22

2020-09-29 19:20:05

鸿蒙

2021-05-28 09:52:00

鸿蒙HarmonyOS应用

2021-12-13 11:07:10

鸿蒙HarmonyOS应用

2020-11-06 12:12:35

HarmonyOS

2018-07-17 08:14:22

分布式分布式锁方位

2021-08-17 10:20:14

鸿蒙HarmonyOS应用

2021-09-15 14:55:49

鸿蒙HarmonyOS应用

2021-09-17 14:43:54

鸿蒙HarmonyOS应用

2021-09-24 09:25:01

鸿蒙HarmonyOS应用

2022-07-15 16:26:58

Java分布式

2022-03-06 21:43:05

Citus架构PostgreSQL

2019-09-26 15:43:52

Hadoop集群防火墙
点赞
收藏

51CTO技术栈公众号