HarmonyOS 鸿蒙Next中三方接入剪贴板开发指导

HarmonyOS 鸿蒙Next中三方接入剪贴板开发指导

1、申请访问剪贴板权限

读取剪贴板权限为ACL受控权限,只有符合条件的应用才可以申请,使用系统控件和安全粘贴控件的应用不需要申请。

添加权限示例:

module.json中添加权限 
"requestPermissions": [ 
      { 
        "name": "ohos.permission.READ_PASTEBOARD", 
        "reason": "$string:module_desc", 
        "usedScene": { 
          "abilities": [ 
            "EntryAbility.ets" 
          ], 
          "when": "always" 
        } 
      } 
    ]
async getPermission(): Promise<boolean> { 
    let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); 
    let bundleInfo: bundleManager.BundleInfo; 
    bundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION); 
    let tokenId: number = bundleInfo.appInfo.accessTokenId; 
    let permissions: Permissions[] = ['ohos.permission.READ_PASTEBOARD']; 
    let grantStatus: abilityAccessCtrl.GrantStatus = atManager.checkAccessTokenSync(tokenId, permissions[0]); 
    if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { 
      return true; 
    } 
    let requestResult: PermissionRequestResult = await atManager.requestPermissionsFromUser(getContext(), permissions); 
    if (requestResult.authResults.length > 0) { 
      return requestResult.authResults[0] === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED; 
    } else { 
      return false; 
    } 
  }

2、使用剪贴板进行复制粘贴

ArkTS以及C/C++开发指导链接参考:

2.1 剪贴板多样式能力介绍

概要

Record对应复制数据的不同内容片段,Entry对应同一份数据的不同格式。

剪贴板多样式指的是一个record中携带多个entry数据,并且剪贴板对PasteData和UDMF两种数据结构都能够支持,以下有这两种数据结构构造多样式的方法:分别对应TS接口多样式以及NDK接口多样式。

由于现在有部分应用没有适配多entry,默认读取record的第一个样式,这里建议应用设置多entry时,将系统提供的样式放在前面,自定义的样式放在最后,提高系统兼容性。

如何复制多样式数据

为了复制应用和粘贴应用对剪贴板数据内容理解一致,更好的实现不同应用间的复制粘贴体验,应用适配剪贴板时需按如下原则处理:

  1. 复制数据内容尽量只使用一个Record携带,对于复制数据内容的不同格式,使用同一Record的不同Entry携带。
  2. 如果存在一个Record无法携带所有数据的场景,比如多文件复制时的多个uri,此时使用多Record携带复制数据内容的不同部分。
  3. 应用将支持的所有剪贴板数据格式都写入剪贴板,以保证复制数据可以在所有可能粘贴的场景被粘贴。
NDK接口

使用UDMF数据结构,在剪贴板的NDK中复制的时候,数据结构示意图如下:

// 创建样式数据 
OH_UdsPlainText *plainText = OH_UdsPlainText_Create(); 
OH_UdsPlainText_SetContent(plainText, "Hello world"); 
 
OH_UdsHtml *html = OH_UdsHtml_Create(); 
OH_UdsHtml_SetContent(html, "<html><h>Hello world</h></html>"); 
 
OH_UdsFileUri *fileUri = OH_UdsFileUri_Create(); 
OH_UdsFileUri_SetFileUri(fileUri, "file://media/Photo/1/IMG_1731465487_001/screenshot_20241113_091535.jpeg"); 
OH_UdsFileUri_SetFileType(fileUri, "general.image"); 
 
// 创建一个record,将样式数据加进去 
OH_UdmfRecord *record = OH_UdmfRecord_Create(); 
OH_UdmfRecord_AddPlainText(record, plainText); 
OH_UdmfRecord_AddHtml(record, html); 
OH_UdmfRecord_AddFileUri(record, fileUri); 
 
// 创建udmfData,将record加进去 
OH_UdmfData *data = OH_UdmfData_Create(); 
OH_UdmfData_AddRecord(data, record); 
 
// 复制数据 
OH_Pasteboard* pasteboard = OH_Pasteboard_Create(); 
OH_Pasteboard_SetData(pasteboard, data);
TS接口

使用TS接口,进行原始数据结构,进行复制粘贴时,使用的剪贴板数据结构示意图如下:

// 创建1个包含单record,多样式数据 
let pasteData: pasteboard.PasteData = pasteboard.createData({ 
    'text/plain': 'hello', 
    'text/uri': 'file://media/Photo/1/IMG_1731465487_001/screenshot_20241113_091535.jpeg', 
    'app/xml': new ArrayBuffer(256), 
}); 
// 粘贴到剪贴板 
pasteboard.getSystemPasteboard().setData(pasteData);
如何粘贴多样式数据

剪贴板数据属于个人数据,读取剪贴板数据需要支持剪贴板读取权限授权,剪贴板提供了安全控件和用户授权ohos.permission.READ_PASTEBOARD权限两种授权方式。

复制应用写入剪贴板的数据可能包含多种格式数据,粘贴应用需根据当前粘贴页面和场景选择最合适的格式进行粘贴显示。

剪贴板同时提供了TS API和NDK API,应用按需选择合适的API支持复制粘贴功能。

NDK接口

首先复制多样式数据,示例如下:

// 方法一:使用record和pasteData的构造函数逐个样式添加的方式构造多样式数据 
// 创建一个html样式的record 
auto record = PasteDataRecord::NewHtmlRecord("<html><h>Hello world</h></html>"); 
 
// 给这个record添加一个uri样式数据 
auto uriUtdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, MIMETYPE_TEXT_URI); 
auto uriEntry = std::make_shared<PasteDataEntry>(uriUtdId, "file://media/Photo/1/IMG_1731465487_001/screenshot_20241113_091535.jpeg"); 
record.AddEntryByMimeType(MIMETYPE_TEXT_URI, uriEntry); 
 
// 给这个record添加一个文本样式数据 
auto textPlainUtdId = CommonUtils::Convert2UtdId(UDMF::UDType::UD_BUTT, MIMETYPE_TEXT_PLAIN); 
auto textPlainEntry = std::make_shared<PasteDataEntry>(textPlainUtdId, "hello world"); 
record.AddEntryByMimeType(MIMETYPE_TEXT_PLAIN, textPlainEntry); 
 
// 复制 
auto pasteData = new PasteData::PasteData(); 
pasteData.addRecord(record); 
PasteboardClient::GetInstance()->SetPasteData(pasteData);
TS接口
// 创建1个包含单record,多样式数据 
let pasteData: pasteboard.PasteData = pasteboard.createData({ 
    'text/plain': 'hello', 
    'text/uri': 'file://media/Photo/1/IMG_1731465487_001/screenshot_20241113_091535.jpeg', 
    'app/xml': new ArrayBuffer(256), 
}); 
// 复制到剪贴板 
pasteboard.getSystemPasteboard().setData(pasteData); 
 
// 粘贴数据 
let gettedData = await pasteboard.getSystemPasteboard().getData(); 
let gettedRecord = gettedData.getRecord(0); 
// 判断这个record中是否有传入的样式数据,此示例中返回的types应该是: [ pasteboard.MIMETYPE_TEXT_PLAIN, pasteboard.MIMETYPE_TEXT_URI, 'app/xml' ] 
let types: string[] = gettedRecord.getValidTypes([ 
    pasteboard.MIMETYPE_TEXT_PLAIN, 
    pasteboard.MIMETYPE_TEXT_HTML, 
    pasteboard.MIMETYPE_TEXT_URI, 
    pasteboard.MIMETYPE_TEXT_WANT, 
    pasteboard.MIMETYPE_PIXELMAP, 
    'app/xml' 
]); 
// 读取其中默认的'text/plain'数据(也可以按照下面uri的读取方式读取) 
let plainTextContent = gettedData.getPrimaryText(); 
 
// 读取其中的uri样式数据(非默认样式,只能用这个函数读取) 
gettedRecord.getData(pasteboard.MIMETYPE_TEXT_URI).then((value: pasteboard.ValueType) => { 
    let uri = value as string; 
    console.info('Success to get text/uri value. value is: ' + uri); 
}).catch((err: BusinessError) => { 
    console.error('Failed to get text/uri value. Cause: ' + err.message); 
});

2.2 跨设备剪贴板能力介绍

如果应用支持跨设备复制、粘贴,如下参数这样设置:

  1. Udmf_ShareOption参数不设置,保持默认。
  2. ShareOption参数不设置,保持默认。
  3. 组件的CopyOptions参数不设置或设置为LocalDevice或设置为CROSS_DEVICE。
  • INAPP:表示仅允许在本设备本应用内粘贴。
  • LocalDevice、CROSS_DEVICE:允许在其他应用粘贴,是否允许跨设备粘贴由设置->多设备协同->跨设备剪贴板开关决定。

更多关于HarmonyOS 鸿蒙Next中三方接入剪贴板开发指导的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

学习打卡

更多关于HarmonyOS 鸿蒙Next中三方接入剪贴板开发指导的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中接入三方应用剪贴板,需使用@ohos.pasteboard模块。首先在module.json5中声明ohos.permission.READ_PASTEBOARDohos.permission.WRITE_PASTEBOARD权限。创建PasteData对象写入数据:

import pasteboard from '@ohos.pasteboard';
let pasteData = pasteboard.createPlainTextData('text content');
pasteboard.getSystemPasteboard().setPasteData(pasteData);

读取剪贴板数据:

let sysPasteboard = pasteboard.getSystemPasteboard();
sysPasteboard.getPasteData().then(data => {
  if (data.hasText()) {
    let text = data.getPrimaryText();
  }
});

注意:数据格式支持文本、URI、像素地图等。

在HarmonyOS Next中接入剪贴板功能需要注意以下几点:

  1. 权限申请:
  • 读取剪贴板需要申请ohos.permission.READ_PASTEBOARD权限
  • module.json中配置权限请求
  • 使用AtManager进行动态权限申请
  1. 数据结构:
  • 使用Record对应不同数据片段
  • 使用Entry对应同一数据的不同格式
  • 建议将系统提供的样式放在前面,自定义样式放最后
  1. 多样式数据处理:
  • TS接口支持createDataaddEntry两种方式构造多样式数据
  • NDK接口使用OH_UdmfRecord_Add*系列函数添加多样式
  1. 跨设备支持:
  • 默认支持跨设备剪贴板
  • 可通过ShareOptionCopyOptions控制数据共享范围

具体实现时,建议参考官方文档中的代码示例,根据实际需求选择合适的API。对于安全性要求高的场景,建议使用系统提供的安全控件。

回到顶部