HarmonyOS Sample 之 Pasteboard 分布式粘貼板
想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
一、介紹
HarmonyOS提供系統(tǒng)剪貼板服務(wù)的操作接口,支持用戶程序從系統(tǒng)剪貼板中讀取、寫入和查詢剪貼板數(shù)據(jù),以及添加、移除系統(tǒng)剪貼板數(shù)據(jù)變化的回調(diào)。
設(shè)備內(nèi):
用戶通過(guò)系統(tǒng)剪貼板服務(wù),可實(shí)現(xiàn)應(yīng)用之間的簡(jiǎn)單數(shù)據(jù)傳遞。例如:在應(yīng)用A中復(fù)制的數(shù)據(jù),可以在應(yīng)用B中粘貼,反之亦可。
設(shè)備間:
在分布式粘貼板場(chǎng)景中,粘貼的數(shù)據(jù)可以跨設(shè)備寫入。例如,設(shè)備A上的應(yīng)用程序使用系統(tǒng)粘貼板接口將從設(shè)備A復(fù)制的數(shù)據(jù)通過(guò)IDL接口存儲(chǔ)到設(shè)備B的系統(tǒng)粘貼板中。如果數(shù)據(jù)允許,設(shè)備B上的應(yīng)用程序可以讀取并粘貼系統(tǒng)粘貼板中的復(fù)制數(shù)據(jù)。實(shí)現(xiàn)設(shè)備之間粘貼板的分布式協(xié)同。
基于以上理解,實(shí)現(xiàn)一個(gè)分布式粘貼板應(yīng)用程序,應(yīng)用程序分為客戶端(copy)和服務(wù)端(paste)兩部分,通過(guò)idl實(shí)現(xiàn)數(shù)據(jù)傳遞。
客戶端負(fù)責(zé)數(shù)據(jù)采集,服務(wù)端負(fù)責(zé)數(shù)據(jù)的展示和應(yīng)用,客戶端和服務(wù)端可以安裝在同一臺(tái)設(shè)備中,也可以安裝在不同的設(shè)備中,服務(wù)端也可以按照在多臺(tái)設(shè)備中,服務(wù)端通過(guò)分布式數(shù)據(jù)庫(kù)實(shí)現(xiàn)粘貼板數(shù)據(jù)的自動(dòng)同步。
二、效果展示


三、搭建環(huán)境
安裝DevEco Studio,詳情請(qǐng)參考DevEco Studio下載。
設(shè)置DevEco Studio開(kāi)發(fā)環(huán)境,DevEco Studio開(kāi)發(fā)環(huán)境需要依賴于網(wǎng)絡(luò)環(huán)境,需要連接上網(wǎng)絡(luò)才能確保工具的正常使用,可以根據(jù)如下兩種情況來(lái)配置開(kāi)發(fā)環(huán)境:
如果可以直接訪問(wèn)Internet,只需進(jìn)行下載HarmonyOS SDK操作。
如果網(wǎng)絡(luò)不能直接訪問(wèn)Internet,需要通過(guò)代理服務(wù)器才可以訪問(wèn),請(qǐng)參考配置開(kāi)發(fā)環(huán)境。
下載源碼后,使用DevEco Studio 打開(kāi)項(xiàng)目,模擬器運(yùn)行即可。
真機(jī)運(yùn)行需要將config.json中的buddleName修改為自己的,如果沒(méi)有請(qǐng)到AGC上進(jìn)行配置,參見(jiàn) 使用模擬器進(jìn)行調(diào)試 。
四、項(xiàng)目結(jié)構(gòu)


五、代碼講解
5.1 系統(tǒng)粘貼板基礎(chǔ)功能介紹
系統(tǒng)粘貼板對(duì)象介紹
1.SystemPasteboard //系統(tǒng)粘貼板對(duì)象,定義系統(tǒng)粘貼板操作,包括復(fù)制、粘貼和設(shè)置粘貼板內(nèi)容更改的偵聽(tīng)器。
2.PasteData//表示粘貼板上的粘貼數(shù)據(jù)。
3.PasteData.DataProperty //該類定義了系統(tǒng)粘貼板上 PasteData 的屬性,包括時(shí)間戳、MIME 類型和其他屬性數(shù)據(jù)。
4.PasteData.Record//該類將單個(gè)粘貼的數(shù)據(jù)定義為 Record,它可以是純文本、HTML 文本、URI 和意圖。 PasteData 對(duì)象包含一個(gè)或多個(gè)記錄。
客戶端(copy)CopyAbilitySlice.java
獲取系統(tǒng)粘貼板,監(jiān)聽(tīng)粘貼板數(shù)據(jù)變化
- /**
- * 獲取系統(tǒng)粘貼板
- * 監(jiān)聽(tīng)粘貼板數(shù)據(jù)變化
- */
- private void initPasteboard() {
- HiLog.debug(LABEL, "initPasteboard");
- //獲取系統(tǒng)粘貼板對(duì)象
- pasteboard = SystemPasteboard.getSystemPasteboard(this);
- //監(jiān)聽(tīng)粘貼板數(shù)據(jù)變化
- pasteboard.addPasteDataChangedListener(() -> {
- if (pasteboard.hasPasteData()) {
- sync_text = getPasteData();
- HiLog.debug(LABEL, "%{public}s", "pasteStr:" + sync_text);
- }
- });
- }
獲取粘貼板內(nèi)容
- /**
- * 獲取粘貼板記錄
- *
- * @return
- */
- private String getPasteData() {
- HiLog.debug(LABEL, "getPasteData");
- String result = "";
- //粘貼板數(shù)據(jù)對(duì)象
- PasteData pasteData = pasteboard.getPasteData();
- if (pasteData == null) {
- return result;
- }
- PasteData.DataProperty dataProperty = pasteData.getProperty();
- //
- boolean hasHtml = dataProperty.hasMimeType(PasteData.MIMETYPE_TEXT_HTML);
- boolean hasText = dataProperty.hasMimeType(PasteData.MIMETYPE_TEXT_PLAIN);
- //數(shù)據(jù)格式類型
- if (hasHtml || hasText) {
- for (int i = 0; i < pasteData.getRecordCount(); i++) {
- //粘貼板數(shù)據(jù)記錄
- PasteData.Record record = pasteData.getRecordAt(i);
- //不同類型獲取方式不同
- String mimeType = record.getMimeType();
- //HTML文本
- if (mimeType.equals(PasteData.MIMETYPE_TEXT_HTML)) {
- result = record.getHtmlText();
- //純文本
- } else if (mimeType.equals(PasteData.MIMETYPE_TEXT_PLAIN)) {
- result = record.getPlainText().toString();
- //
- } else {
- HiLog.info(LABEL, "%{public}s", "getPasteData mimeType :" + mimeType);
- }
- }
- }
- return result;
- }
設(shè)置文本到粘貼板中
- /**
- * 設(shè)置文本到粘貼板
- *
- * @param component
- */
- private void setTextToPaste(Component component) {
- HiLog.info(LABEL, "setTextToPaste");
- if (pasteboard != null) {
- String text = syncText.getText();
- if (text.isEmpty()) {
- showTips(this, "請(qǐng)?zhí)顚憙?nèi)容");
- return;
- }
- //把記錄添加到粘貼板
- PasteData pasteData= PasteData.creatPlainTextData(text);
- //設(shè)置文本到粘貼板
- pasteboard.setPasteData(pasteData);
- showTips(this, "復(fù)制成功");
- HiLog.info(LABEL, "setTextToPaste succeeded");
- }
- }
清空粘貼板
- /**
- * 清空粘貼板
- *
- * @param component
- */
- private void clearPasteboard(Component component) {
- if (pasteboard != null) {
- pasteboard.clear();
- showTips(this, "Clear succeeded");
- }
- }
5.2 分布式粘貼板應(yīng)用構(gòu)建思路介紹

選擇遠(yuǎn)端連接設(shè)備
本實(shí)例是通過(guò)新增加一個(gè)DevicesSelectAbility來(lái)實(shí)現(xiàn)的。
- private void showDevicesDialog() {
- Intent intent = new Intent();
- //打開(kāi)選擇設(shè)備的Ability頁(yè)面DevicesSelectAbility
- Operation operation =
- new Intent.OperationBuilder()
- .withDeviceId("")
- .withBundleName(getBundleName())
- .withAbilityName(DevicesSelectAbility.class)
- .build();
- intent.setOperation(operation);
- //攜帶一個(gè)設(shè)備選擇請(qǐng)求標(biāo)識(shí),打開(kāi)設(shè)備選擇頁(yè)面(DevicesSelectAbility) TODO
- startAbilityForResult(intent, Constants.PRESENT_SELECT_DEVICES_REQUEST_CODE);
- }
- /**
- * 打開(kāi)設(shè)備選擇Ability后,選擇連接的設(shè)備執(zhí)行setResult后觸發(fā)
- *
- * @param requestCode
- * @param resultCode
- * @param resultIntent
- */
- @Override
- protected void onAbilityResult(int requestCode, int resultCode, Intent resultIntent) {
- HiLog.debug(LABEL, "onAbilityResult");
- if (requestCode == Constants.PRESENT_SELECT_DEVICES_REQUEST_CODE && resultIntent != null) {
- //獲取用戶選擇的設(shè)備
- String devicesId = resultIntent.getStringParam(Constants.PARAM_DEVICE_ID);
- //連接粘貼板服務(wù)端
- connectService(devicesId);
- return;
- }
- }
連接粘貼板服務(wù)端ServiceAbility服務(wù)
idl文件放在ohos.samples.pasteboard.paste目錄下,Gradl窗口,執(zhí)行compileDebugIdl 后,系統(tǒng)生成代理對(duì)象。
- interface ohos.samples.pasteboard.paste.ISharePasteAgent {
- /*
- * 設(shè)置系統(tǒng)粘貼板
- */
- void setSystemPaste([in] String param);
- }
連接服務(wù)端ServiceAbility,如果組網(wǎng)中沒(méi)有其他設(shè)備就連接本地的服務(wù)端。
連接成功后,初始化idl的SharePasteAgentProxy代理,用于下一步的同步數(shù)據(jù)。
- //idl共享粘貼板代理
- private SharePasteAgentProxy remoteAgentProxy;
- /**
- * 連接粘貼板服務(wù)中心
- */
- private void connectService(String deviceId) {
- HiLog.debug(LABEL, "%{public}s", "connectService");
- if (!isConnect) {
- boolean isConnectRemote = deviceId != null;
- //三元表達(dá)式,判斷連接本地還是遠(yuǎn)端Service
- Intent intent = isConnectRemote
- ? getRemoteServiceIntent(REMOTE_BUNDLE, REMOTE_SERVICE, deviceId)
- : getLocalServiceIntent(REMOTE_BUNDLE, REMOTE_SERVICE);
- HiLog.debug(LABEL, "%{public}s", "intent:" + intent);
- //連接 Service
- connectAbility(intent, new IAbilityConnection() {
- @Override
- public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int resultCode) {
- //發(fā)個(gè)通知,Service 連接成功了
- eventHandler.sendEvent(EVENT_ABILITY_CONNECT_DONE);
- //初始化代理
- remoteAgentProxy = new SharePasteAgentProxy(iRemoteObject);
- HiLog.debug(LABEL, "%{public}s", "remoteAgentProxy:" + remoteAgentProxy);
- }
- @Override
- public void onAbilityDisconnectDone(ElementName elementName, int resultCode) {
- //發(fā)個(gè)通知,Service 斷開(kāi)連接了,主動(dòng)斷開(kāi)不會(huì)執(zhí)行,關(guān)閉服務(wù)端會(huì)執(zhí)行
- eventHandler.sendEvent(EVENT_ABILITY_DISCONNECT_DONE);
- }
- });
- }
- }
- /**
- * 獲取遠(yuǎn)端粘貼板服務(wù)中心
- *
- * @param bundleName
- * @param serviceName
- * @return
- */
- private Intent getRemoteServiceIntent(String bundleName, String serviceName, String deviceId) {
- HiLog.debug(LABEL, "%{public}s", "getRemoteServiceIntent");
- Operation operation = new Intent.OperationBuilder()
- .withDeviceId(deviceId)
- .withBundleName(bundleName)
- .withAbilityName(serviceName)
- //重要
- .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
- .build();
- Intent intent = new Intent();
- intent.setOperation(operation);
- return intent;
- }
- /**
- * 獲取本地粘貼板服務(wù)中心
- *
- * @param bundleName
- * @param serviceName
- * @return
- */
- private Intent getLocalServiceIntent(String bundleName, String serviceName) {
- HiLog.debug(LABEL, "%{public}s", "getLocalServiceIntent");
- Operation operation = new Intent.OperationBuilder().withDeviceId("")
- .withBundleName(bundleName)
- .withAbilityName(serviceName)
- .build();
- Intent intent = new Intent();
- intent.setOperation(operation);
- return intent;
- }
同步數(shù)據(jù)到服務(wù)端
- /**
- * 同步粘貼板記錄到粘貼板服務(wù)中心
- *
- * @param component
- */
- private void syncData(Component component) {
- HiLog.debug(LABEL, "sync_text:" + sync_text);
- if (!sync_text.isEmpty()) {
- if (isConnect && remoteAgentProxy != null) {
- //調(diào)用服務(wù)端IPC方法
- try {
- remoteAgentProxy.setSystemPaste(sync_text);
- //更換文本
- syncText.setText(getRandomText());
- sync_text = "";
- showTips(this, "同步成功");
- } catch (RemoteException remoteException) {
- remoteException.printStackTrace();
- }
- } else {
- showTips(this, "正在連接設(shè)備");
- }
- } else {
- showTips(this, "點(diǎn)擊復(fù)制到粘貼板");
- }
- }
隨機(jī)生成粘貼文本
- /**
- * 隨機(jī)文本,模擬數(shù)據(jù)
- *
- * @return
- */
- public String getRandomText() {
- List<String> list = Arrays.asList(
- "快馬加鞭未下鞍,離天三尺三",
- "我自橫刀向天笑,去留肝膽兩昆侖",
- "飛流直下三千尺,疑是銀河落九天",
- "君子求諸己,小人求諸人",
- "吾日三省吾身:為人謀而不忠乎?與朋友交而不信乎?傳不習(xí)乎?");
- int random = new SecureRandom().nextInt(list.size());
- return list.get(random);
- }
服務(wù)端(paste)ServiceAbility.java
設(shè)置粘貼板服務(wù)
idl文件放在ohos.samples.pasteboard.paste目錄下,Gradl窗口,執(zhí)行compileDebugIdl 后,系統(tǒng)生成代理對(duì)象,idl提供了setSystemPaste接口供遠(yuǎn)端調(diào)用。
- interface ohos.samples.pasteboard.paste.ISharePasteAgent {
- /*
- * 設(shè)置系統(tǒng)粘貼板
- */
- void setSystemPaste([in] String param);
- }
- //idl的服務(wù)端實(shí)現(xiàn),
- SharePasteAgentStub sharePasteAgentStub = new SharePasteAgentStub(DESCRIPTOR) {
- @Override
- public void setSystemPaste(String param) {
- HiLog.info(LABEL, "%{public}s", "param:" + param);
- //插入數(shù)據(jù)庫(kù)
- ItemChild itemChild = new ItemChild();
- String currentTime = DateUtils.getCurrentDate("yyMMdd HH:mm:ss");
- itemChild.setWriteTime(currentTime);
- itemChild.setWriteContent(param);
- itemChild.setIndex(String.valueOf(UUID.randomUUID()));
- //默認(rèn)添加到未分類
- itemChild.setTagName(Const.CATEGORY_TAG_UNCATEGOORIZED);
- //添加粘貼板記錄到分布式數(shù)據(jù)庫(kù)
- kvManagerUtils.addItemChild(itemChild);
- }
- };
- @Override
- protected IRemoteObject onConnect(Intent intent) {
- HiLog.info(LABEL, "%{public}s", "ServiceAbility onConnect");
- return sharePasteAgentStub;
- }
- **初始化數(shù)據(jù)庫(kù)**
- ```java
- //初始化數(shù)據(jù)庫(kù)工具
- kvManagerUtils = KvManagerUtils.getInstance(this);
- //初始化數(shù)據(jù)庫(kù)管理對(duì)象
- kvManagerUtils.initDbManager(eventHandler);
- //初始化數(shù)據(jù)庫(kù)數(shù)據(jù)按鈕
- Image initDb = (Image) findComponentById(ResourceTable.Id_init_db);
- initDb.setClickedListener(component -> {
- //默認(rèn)選中“未定義”標(biāo)簽
- current_select_category_index = 0;
- //初始化數(shù)據(jù)庫(kù)數(shù)據(jù)
- kvManagerUtils.initDbData();
- showTip("初始化完成");
- });
初始化數(shù)據(jù)列表
- /**
- * 從分布式數(shù)據(jù)庫(kù)中查詢數(shù)據(jù)
- */
- public void queryData() {
- HiLog.debug(LABEL, "queryData");
- try {
- //加載選中類別下的數(shù)據(jù)列表
- initItemChild(kvManagerUtils.queryDataByTag(CategoryData.tagList.get(current_select_category_index)));
- } catch (KvStoreException exception) {
- HiLog.info(LABEL, "the value must be String");
- }
- }
- /**
- * 初始化選中標(biāo)簽的子項(xiàng)列表
- *
- * @param itemChildList itemChildList, the bean of itemChild
- */
- private void initItemChild(List<ItemChild> itemChildList) {
- HiLog.debug(LABEL, "initItemChild:" + itemChildList);
- if (itemChildList == null) {
- return;
- }
- //清空組件
- itemChildLayout.removeAllComponents();
- // Create itemChild
- for (ItemChild itemChild : itemChildList) {
- //獲取子項(xiàng)類別所在的組件
- Component childComponent =
- LayoutScatter.getInstance(this).parse(ResourceTable.Layout_paste_record_per, null, false);
- //寫入時(shí)間
- Text writeTime = (Text) childComponent.findComponentById(ResourceTable.Id_writeTime);
- writeTime.setText(itemChild.getWriteTime());
- //粘貼板內(nèi)容
- Text writeContent = (Text) childComponent.findComponentById(ResourceTable.Id_writeContent);
- writeContent.setText(itemChild.getWriteContent());
- //復(fù)制按鈕
- Text copy = (Text) childComponent.findComponentById(ResourceTable.Id_itemChildPerCopy);
- //復(fù)制按鈕的監(jiān)聽(tīng)事件
- copy.setClickedListener(component -> {
- //復(fù)制內(nèi)容到粘貼板
- pasteboard.setPasteData(PasteData.creatPlainTextData(itemChild.getWriteContent()));
- showTip("已復(fù)制到粘貼板");
- });
- //收藏按鈕
- Text favorite = (Text) childComponent.findComponentById(ResourceTable.Id_itemChildPerFavorite);
- //收藏按鈕的監(jiān)聽(tīng)事件
- favorite.setClickedListener(component -> {
- //修改標(biāo)簽微已收藏
- itemChild.setTagName(Const.CATEGORY_TAG_FAVORITED);
- //保存數(shù)據(jù)
- kvManagerUtils.addItemChild(itemChild);
- showTip("已加入到收藏中");
- });
- /**************just for test********************/
- //復(fù)選框
- Checkbox noteId = (Checkbox) childComponent.findComponentById(ResourceTable.Id_noteId);
- //子項(xiàng)列表的點(diǎn)擊事件
- childComponent.setClickedListener(component -> {
- if (noteId.getVisibility() == Component.VISIBLE) {
- noteId.setChecked(!noteId.isChecked());
- }
- });
- //子項(xiàng)列表的長(zhǎng)按事件,長(zhǎng)按顯示復(fù)選框
- childComponent.setLongClickedListener(component -> {
- //checkbox顯示
- noteId.setVisibility(Component.VISIBLE);
- //設(shè)置復(fù)選框樣式,以及其他文本組件的縮進(jìn)
- Element element = ElementScatter.getInstance(getContext()).parse(ResourceTable.Graphic_check_box_checked);
- noteId.setBackground(element);
- noteId.setChecked(true);
- writeTime.setMarginLeft(80);
- writeContent.setMarginLeft(80);
- });
- //復(fù)選框的狀態(tài)變化監(jiān)聽(tīng)事件,state表示是否被選中
- noteId.setCheckedStateChangedListener((component, state) -> {
- // 狀態(tài)改變的邏輯
- Element element;
- if (state) {
- //設(shè)置選中的樣式
- element = ElementScatter.getInstance(getContext())
- .parse(ResourceTable.Graphic_check_box_checked);
- } else {
- //設(shè)置未選中的樣式
- element = ElementScatter.getInstance(getContext())
- .parse(ResourceTable.Graphic_check_box_uncheck);
- }
- noteId.setBackground(element);
- });
- /**************just for test********************/
- //添加子項(xiàng)列表組件到布局
- itemChildLayout.addComponent(childComponent);
- }
- }
標(biāo)簽分類顯示
- //初始化列表列表的點(diǎn)擊的監(jiān)聽(tīng)事件
- categoryList.setItemClickedListener(
- (listContainer, component, index, l1) -> {
- //點(diǎn)的就是當(dāng)前類別
- if (categoryListProvider.getSelectIndex() == index) {
- return;
- }
- //切換類別索引
- categoryListProvider.setSelectIndex(index);
- //設(shè)置選中的標(biāo)簽索引
- current_select_category_index = index;
- //獲取當(dāng)前選中的標(biāo)簽名稱
- String tagName = CategoryData.tagList.get(index);
- //從數(shù)據(jù)庫(kù)中查詢標(biāo)簽子項(xiàng)列表
- initItemChild(kvManagerUtils.queryDataByTagAndKewWord(searchTextField.getText(), tagName));
- //通知數(shù)據(jù)更新
- categoryListProvider.notifyDataChanged();
- //滾動(dòng)條到最頂部
- itemListScroll.fluentScrollYTo(0);
- });
搜索粘貼記錄
- //搜索key監(jiān)聽(tīng)事件
- searchTextField.setKeyEventListener(
- (component, keyEvent) -> {
- if (keyEvent.isKeyDown() && keyEvent.getKeyCode() == KeyEvent.KEY_ENTER) {
- //獲取當(dāng)前選中的標(biāo)簽名稱
- String tagName = CategoryData.tagList.get(current_select_category_index);
- List<ItemChild> itemChildList = kvManagerUtils.queryDataByTagAndKewWord(searchTextField.getText(), tagName);
- //從數(shù)據(jù)庫(kù)中查詢標(biāo)簽子項(xiàng)列表
- initItemChild(itemChildList);
- //通知數(shù)據(jù)更新
- categoryListProvider.notifyDataChanged();
- //滾動(dòng)條到最頂部
- itemListScroll.fluentScrollYTo(0);
- }
- return false;
- });
分布式數(shù)據(jù)庫(kù)工具KvManagerUtils.java
數(shù)據(jù)變化通知
提供了分布式數(shù)據(jù)庫(kù)管理工具KvManagerUtils.java,數(shù)據(jù)庫(kù)操作都集中在這里了。
為了在數(shù)據(jù)庫(kù)數(shù)據(jù)發(fā)生變化時(shí)能及時(shí)更新頁(yè)面顯示,頁(yè)面在初始化數(shù)據(jù)庫(kù)時(shí),傳遞eventHandler對(duì)象,這樣在數(shù)據(jù)庫(kù)變化是可以通知到頁(yè)面。
- /**
- * 訂閱數(shù)據(jù)庫(kù)更改通知
- * @param singleKvStore Data operation
- */
- private void subscribeDb(SingleKvStore singleKvStore) {
- HiLog.info(LABEL, "subscribeDb");
- //數(shù)據(jù)庫(kù)觀察者客戶端
- KvStoreObserver kvStoreObserverClient = new KvStoreObserverClient();
- //訂閱遠(yuǎn)程數(shù)據(jù)更改
- singleKvStore.subscribe(SubscribeType.SUBSCRIBE_TYPE_REMOTE, kvStoreObserverClient);
- }
- /**
- * 自定義分布式數(shù)據(jù)庫(kù)觀察者客戶端
- * 數(shù)據(jù)發(fā)生變化時(shí)觸發(fā)對(duì)應(yīng)函數(shù)
- * Receive database messages
- */
- private class KvStoreObserverClient implements KvStoreObserver {
- @Override
- public void onChange(ChangeNotification notification) {
- HiLog.error(LABEL, "onChange");
- eventHandler.sendEvent(Const.DB_CHANGE_MESS);
- }
- }
數(shù)據(jù)自動(dòng)同步
默認(rèn)開(kāi)啟自動(dòng)同步
- /**
- * Initializing Database Management
- * 初始化數(shù)據(jù)庫(kù)管理員
- */
- public void initDbManager(EventHandler eventHandler) {
- this.eventHandler = eventHandler;
- HiLog.info(LABEL, "initDbManager");
- if (singleKvStore == null || kvManager == null) {
- HiLog.info(LABEL, "initDbData");
- //創(chuàng)建數(shù)據(jù)庫(kù)管理員
- kvManager = createManager();
- //創(chuàng)建數(shù)據(jù)庫(kù)
- singleKvStore = createDb(kvManager);
- subscribeDb(singleKvStore);
- }
- }
- /**
- * Create a distributed database manager instance
- * 創(chuàng)建數(shù)據(jù)庫(kù)管理員
- *
- * @return database manager
- */
- private KvManager createManager() {
- HiLog.info(LABEL, "createManager");
- KvManager manager = null;
- try {
- //
- KvManagerConfig config = new KvManagerConfig(context);
- manager = KvManagerFactory.getInstance().createKvManager(config);
- } catch (KvStoreException exception) {
- HiLog.error(LABEL, "some exception happen");
- }
- return manager;
- }
- /**
- * Creating a Single-Version Distributed Database
- * 創(chuàng)建數(shù)據(jù)庫(kù)
- *
- * @param kvManager Database management
- * @return SingleKvStore
- */
- private SingleKvStore createDb(KvManager kvManager) {
- HiLog.info(LABEL, "createDb");
- SingleKvStore kvStore = null;
- try {
- Options options = new Options();
- //單版本數(shù)據(jù)庫(kù),不加密,沒(méi)有可用的 KvStore 數(shù)據(jù)庫(kù)就創(chuàng)建
- //單版本分布式數(shù)據(jù)庫(kù),默認(rèn)開(kāi)啟組網(wǎng)設(shè)備間自動(dòng)同步功能,
- //如果應(yīng)用對(duì)性能比較敏感建議設(shè)置關(guān)閉自動(dòng)同步功能setAutoSync(false),主動(dòng)調(diào)用sync接口同步。
- options.setCreateIfMissing(true)
- .setEncrypt(false)
- .setKvStoreType(KvStoreType.SINGLE_VERSION);
- //創(chuàng)建數(shù)據(jù)庫(kù)
- kvStore = kvManager.getKvStore(options, STORE_ID);
- } catch (KvStoreException exception) {
- HiLog.error(LABEL, "some exception happen");
- }
- return kvStore;
- }
權(quán)限config.json
- "reqPermissions": [
- {
- "name": "ohos.permission.DISTRIBUTED_DATASYNC",
- "reason": "同步粘貼板數(shù)據(jù)",
- "usedScene": {
- "when": "inuse",
- "ability": [
- "ohos.samples.pasteboard.paste.MainAbility",
- "ohos.samples.pasteboard.paste.ServiceAbility"
- ]
- }
- },
- {
- "name": "ohos.permission.GET_DISTRIBUTED_DEVICE_INFO"
- },
- {
- "name": "ohos.permission.KEEP_BACKGROUND_RUNNING"
- }
- ]
六、思考總結(jié)
1.粘貼板板傳遞數(shù)據(jù)可能會(huì)存在安全問(wèn)題,需要注意,要根據(jù)具體場(chǎng)景來(lái)使用。
設(shè)備內(nèi)每次傳輸?shù)恼迟N數(shù)據(jù)大小不能超過(guò) 800 KB。每次設(shè)備間傳輸?shù)臄?shù)據(jù)不能超過(guò)64KB,且數(shù)據(jù)必須為文本格式。
2.idl的使用,在上述案例中,客戶端(copy) 和 服務(wù)端(paste) 項(xiàng)目idl下內(nèi)容完全一致即可。


七、完整代碼
附件可以直接下載
https://harmonyos.51cto.com/resource/1489
想了解更多內(nèi)容,請(qǐng)?jiān)L問(wèn):
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)