HarmonyOS剪切板开发代码演示
目录
- 说些废话
- 环境
- Setter
-
- ability_main.xml
- MainAbilitySlice.java
- Getter
-
- ability_main.xml
- MainAbilitySlice.java
- SystemPasteboard的clear()方法
- 测试
-
- intent
- intent + html
- text + html
说些废话
官方文档:剪切板开发指导(基于java开发)
因为我的平板使用的是百度输入法华为版,我在输入法里看剪切板的话,如果是重复的数据(Record)增加,它是只会有一条。个人理解:如果是一条原本已经存在过的数据(Record),它就是把一样的原来的删去,再在首行增加上。
然后为了体现系统的剪切板是全局存在的,这里建立了两个工程(也就是两个应用),一个是Getter获取剪切板的内容,一个是Setter在剪切板里加内容。
环境
HUAWEI MatePad Pro 10.8英寸 2019款
DevEco Studio 3.0.0.993 Release
SDK 6(使用java)
我看的《公共事件开发指导》更新于2022-10-28 18:02
Setter
ability_main.xml
<DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="vertical"> <Text ohos:id="$+id:text_copy" ohos:height="match_content" ohos:width="match_content" ohos:layout_alignment="horizontal_center" ohos:text="点击复制内容" ohos:text_size="40vp" /></DirectionalLayout>
MainAbilitySlice.java
结合我前面的废话,我觉得系统剪切板或者输入法替我们判断了重复数据的问题,所以我偷懒不想写了。
未测试设置Uri类型的数据对象,其余三种可以根据需要解开注释,最后会简单展示一下。
package com.openvalley.cyj.parse.setter.slice;import com.openvalley.cyj.parse.setter.ResourceTable;import ohos.aafwk.ability.AbilitySlice;import ohos.aafwk.content.Intent;import ohos.aafwk.content.Operation;import ohos.agp.components.Text;import ohos.hiviewdfx.HiLog;import ohos.hiviewdfx.HiLogLabel;import ohos.miscservices.pasteboard.IPasteDataChangedListener;import ohos.miscservices.pasteboard.PasteData;import ohos.miscservices.pasteboard.SystemPasteboard;import ohos.utils.IntentConstants;import ohos.utils.net.Uri;public class MainAbilitySlice extends AbilitySlice { //拿到系统的剪切板操作接口 SystemPasteboard systemPasteboard = null; private static final HiLogLabel LOG_MAIN = new HiLogLabel(HiLog.LOG_APP, 0x00001, MainAbilitySlice.class.getSimpleName()); Text text_copy = null; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main); text_copy = (Text)findComponentById(ResourceTable.Id_text_copy); text_copy.setClickedListener(listen -> doCopy()); systemPasteboard = SystemPasteboard.getSystemPasteboard(getContext()); } private void doCopy() { //如果存在系统剪切板操作接口 if(systemPasteboard != null){ //监听,但是只针对此应用程序 systemPasteboard.addPasteDataChangedListener(new IPasteDataChangedListener() { @Override public void onChanged() { HiLog.info(LOG_MAIN, "系统剪切板数据已经改变"); } }); //创建一个包含纯文本内容条目的数据对象。 PasteData pasteData = PasteData.creatPlainTextData("abcdefg"); //构建一个包含Intent内容条目的数据对象。// Intent intent = new Intent();// intent.setParam("action", "拨号");// Operation operation = new Intent.OperationBuilder()// .withDeviceId("")// .withUri(Uri.parse("tel:12345"))// .withAction(IntentConstants.ACTION_DIAL)// .build();// intent.setOperation(operation);// PasteData pasteData = PasteData.creatIntentData(intent); //获得数据对象上的内容条目(record)数量// int count = pasteData.getRecordCount(); //获得数据对象的第一条内容条目的文本// String primaryText = (String) pasteData.getPrimaryText(); //获得数据对象的第一条内容条目的类型// String primaryMimeType = pasteData.getPrimaryMimeType(); //构建一个包含HTML内容条目的数据对象。// PasteData.Record record = PasteData.Record.createHtmlTextRecord("www.baidu.com");// pasteData.addRecord(record); //将数据对象(pasteData)添加到剪切板操作接口中 systemPasteboard.setPasteData(pasteData); } } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); }}
Getter
ability_main.xml
<DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:alignment="center" ohos:orientation="vertical"> <Text ohos:id="$+id:text_paste" ohos:height="match_content" ohos:width="match_content" ohos:layout_alignment="horizontal_center" ohos:text="粘贴剪切板中的数据" ohos:text_size="40vp" /> <Text ohos:id="$+id:text_show" ohos:height="match_content" ohos:width="match_content" ohos:layout_alignment="horizontal_center" ohos:text="等待粘贴" ohos:text_size="40vp" /> <Text ohos:id="$+id:text_clear" ohos:height="match_content" ohos:width="match_content" ohos:layout_alignment="horizontal_center" ohos:text="清除剪切板操作接口中的数据对象" ohos:text_size="30vp" /></DirectionalLayout>
MainAbilitySlice.java
package com.openvalley.cyj.parse.getter.slice;import com.openvalley.cyj.parse.getter.ResourceTable;import ohos.aafwk.ability.AbilitySlice;import ohos.aafwk.content.Intent;import ohos.agp.components.Text;import ohos.agp.window.dialog.ToastDialog;import ohos.hiviewdfx.HiLog;import ohos.hiviewdfx.HiLogLabel;import ohos.miscservices.pasteboard.PasteData;import ohos.miscservices.pasteboard.SystemPasteboard;public class MainAbilitySlice extends AbilitySlice { private static final HiLogLabel LOG_MAIN = new HiLogLabel(HiLog.LOG_APP, 0x00001, MainAbilitySlice.class.getSimpleName()); //拿到系统的剪切板操作接口 SystemPasteboard systemPasteboard = null; Text text_paste = null; Text text_show = null; Text text_clear = null; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main); text_show = (Text)findComponentById(ResourceTable.Id_text_show); text_paste = (Text)findComponentById(ResourceTable.Id_text_paste); text_paste.setClickedListener(listen -> doPaste()); text_clear = (Text)findComponentById(ResourceTable.Id_text_clear); text_clear.setClickedListener(listen -> doClear()); systemPasteboard = SystemPasteboard.getSystemPasteboard(getContext()); } /** * 清空剪切板所有内容 */ private void doClear() { if(systemPasteboard != null){ //Clears the pasteboard. <- 官方文档解释 //从日志推断,把systemPasteboard中的数据对象(通俗点就是平时我们长按粘贴的内容)清除了 systemPasteboard.clear(); //顺便界面也清了 text_show.setText("等待粘贴"); } } /** * 获得系统剪切板的内容 */ private void doPaste() { if(systemPasteboard != null){ //如果系统的剪切板操作接口不为空才能拿数据对象 HiLog.info(LOG_MAIN, "systemPasteboard.hasPasteData() = " + systemPasteboard.hasPasteData()); if(systemPasteboard.hasPasteData()){ //判断剪切板操作接口中是否有数据对象再创建数据对象 //快捷粘贴都是粘贴的剪切板中的最近的一条数据对象,这里同理。 StringBuilder stringBuilder = new StringBuilder(); PasteData pasteData = systemPasteboard.getPasteData(); //获得数据对象中有多少个内容条目 int count = pasteData.getRecordCount(); //循环遍历内容条目 for(int i = 0; i < count; i++){ PasteData.Record record = pasteData.getRecordAt(i); String mimeType = record.getMimeType(); if(PasteData.MIMETYPE_TEXT_PLAIN.equals(mimeType)){ HiLog.info(LOG_MAIN, "mimeType = MIMETYPE_TEXT_PLAIN"); //文本类型 stringBuilder.append(record.getPlainText()); if(i != count - 1){stringBuilder.append("\n"); } }else if(PasteData.MIMETYPE_TEXT_HTML.equals(mimeType)){ HiLog.info(LOG_MAIN, "mimeType = MIMETYPE_TEXT_HTML"); //html类型 stringBuilder.append(record.getHtmlText()); if(i != count - 1){stringBuilder.append("\n"); } }else if(PasteData.MIMETYPE_TEXT_INTENT.equals(mimeType)){ HiLog.info(LOG_MAIN, "mimeType = MIMETYPE_TEXT_INTENT"); //意图模式 Intent intentResult = record.getIntent(); String action = intentResult.getStringParam("action"); stringBuilder.append("点击跳转至" + action); if(i != count - 1){stringBuilder.append("\n"); } text_show.setClickedListener(listen -> {startAbility(intentResult); }); } } if(stringBuilder.length() != 0){ HiLog.info(LOG_MAIN, "stringBuilder.length() = " + stringBuilder.length()); text_show.setText(stringBuilder.toString()); text_show.setMultipleLine(true); } } }else { new ToastDialog(getContext()) .setText("systemPasteboard is null") .show(); } } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); }}
SystemPasteboard的clear()方法
官方文档给这个方法的解释是:Clears the pasteboard.
我的推断是我们获得的SystemPasteboard操作接口与手机的快捷粘贴(长按粘贴)是同步的,我们能长按粘贴出什么,那么我们就能通过SystemPasteboard操作接口获得PasteData数据对象进而自己写代码来实现粘贴过程。
而clear()方法就是把这个PasteData数据对象给清除了,而我在实际操作时,用输入法自带的清空剪切板或者删除剪切板第一条数据,会导致粘贴一个空格,是mimeType = MIMETYPE_TEXT_PLAIN
下的一个空格,暂时我还不知道到底是什么情况。
接下来这个gif有01:03,从我输入你好开始。