在 HarmonyOS 应用开发中,剪贴板功能是一项常用且实用的功能。本文将介绍如何使用 @ohos.pasteboard API 来实现基本的剪贴板功能,包括复制和粘贴文本,并演示如何在应用之间传递数据。

场景描述

本模块主要提供管理系统剪贴板的能力,为系统的复制、粘贴功能提供支持。系统剪贴板支持对文本、HTML、URI、Want、PixelMap 等内容的操作。

场景一:手动点击按钮进行复制粘贴

使用场景

在某些场景下,如安全相关的应用,我们需要确保只有在用户明确同意的情况下才能访问剪贴板数据。为此,我们可以设计一个粘贴按钮,在点击该按钮时给业务临时授予 ohos.permission.SECURE_PASTE 权限。

效果图

HarmonyOS开发之剪贴板功能_剪贴板

实现方案
  1. 创建一个粘贴按钮组件 (PasteButton) 并设置点击事件处理函数。
  2. 调用 pasteboard.getSystemPasteboard().getData() 方法,获取系统剪贴板中的数据。
  3. 调用 systemPasteboard.setData() 方法,将指定的文本内容设置到系统剪贴板中。
核心代码
import { pasteboard, BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index {
  @State message: string = '';

  build() {
    Row() {
      Column({ space: 10 }) {
        TextInput({ placeholder: '请输入验证码', text: this.message })
          .onChange((value: string) => {
            this.message = value;
          })
        PasteButton().onClick((event: ClickEvent, result: PasteButtonOnClickResult) => {
          if (PasteButtonOnClickResult.SUCCESS === result) {
            pasteboard.getSystemPasteboard().getData((err: BusinessError, pasteData: pasteboard.PasteData) => {
              if (err) {
                console.error(`Failed to get paste data. Code is ${err.code}, message is ${err.message}`);
                return;
              }
              this.message = pasteData.getPrimaryText();
            });
          }
        })
        Text("复制")
          .onClick(() => {
            let pasteData: pasteboard.PasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, this.message);
            let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard();
            systemPasteboard.setData(pasteData, (err, data) => {
              if (err) {
                console.error('Failed to set PasteData. Cause: ' + err.message);
                return;
              }
              console.info('Succeeded in setting PasteData.');
            });

          })
      }
      .width('100%')
    }
    .height('100%')
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.

场景二:读取系统剪贴板数据并实现页面跳转

使用场景

在应用 A 复制口令(使用按钮复制),打开应用 B 后直接读取到系统剪贴板里面的口令,然后跳转到口令里面的页面。

实现方案
  1. module.json5 文件中声明 ohos.permission.READ_PASTEBOARD 权限以访问剪贴板。
  2. 在进行权限申请之前,需要先检查当前应用程序是否已经被授予权限。可以通过调用 checkAccessToken() 方法来校验当前是否已经授权,如果已经授权,则可以直接访问目标操作,否则需要进行下一步操作,即向用户申请授权。
  3. 当权限被授予时,尝试从系统剪贴板获取数据,如果成功则从 pasteData 中获取主要文本数据。如果权限未被授予,则根据 this.permission_state 的状态来决定是否向用户请求权限或者进行其他处理。
  4. 页面跳转,参考:构建第二个页面。
核心代码
module.json5 配置
{
  "requestPermissions": [
    {
      "name": "ohos.permission.READ_PASTEBOARD",
      "reason": "$string:app_name",
      "usedScene": {
        "abilities": [
          "EntryAbility",
        ],
        "when": "always"
      }
    }
  ]
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
检查当前应用程序是否已经被授予权限
async function checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;

  let tokenId: number = 0;
  try {
    let bundleInfo: bundleManager.BundleInfo =
      await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
    tokenId = appInfo.accessTokenId;
  } catch (error) {
    let err: BusinessError = error as BusinessError;
    console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
  }

  try {
    grantStatus = await atManager.checkAccessToken(tokenId, permission);
  } catch (error) {
    let err: BusinessError = error as BusinessError;
    console.error(`Failed to check access token. Code is ${err.code}, message is ${err.message}`);
  }
  return grantStatus;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
向用户申请授权
reqPermissionsFromUser(permissions: Array<Permissions> = ['ohos.permission.READ_PASTEBOARD']): void {
  let context = getContext(this) as common.UIAbilityContext;
  let atManager = abilityAccessCtrl.createAtManager();
  atManager.requestPermissionsFromUser(context, permissions).then((data) => {
    let grantStatus: Array<number> = data.authResults;
    let length: number = grantStatus.length;
    for (let i = 0; i < length; i++) {
      if (grantStatus[i] === 0) {
        this.permission_state = true;
      } else {
        console.error("user did not grant!")
        this.permission_state = false;
      }
    }
  })
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
获取系统剪贴板的内容
async getPaste(): Promise<string> {
  const permissions: Array<Permissions> = ['ohos.permission.READ_PASTEBOARD'];
  let grantStatus: abilityAccessCtrl.GrantStatus = await checkAccessToken(permissions[0]);

  if(grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
    try {
      let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard();
      let pasteData = await systemPasteboard.getData();
      return pasteData.getPrimaryText();
    } catch (err) {
      console.error(`get oaid by promise catch error: ${err.code} ${err.message}`);
      return '';
    }
  } else {
    if (this.permission_state) {
      this.reqPermissionsFromUser(permissions);
    }
    return '';
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
页面跳转
function onJumpClick(pageJump: string): void {
  router.pushUrl({
    url: pageJump // 目标url
  }, router.RouterMode.Standard, (err) => {
    if (err) {
      console.error(`Invoke pushUrl failed, code is ${err.code}, message is ${err.message}`);
      return;
    }
    console.info('Invoke pushUrl succeeded.');
  });
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
口令识别
let text = await this.getPaste();
if (text.includes('口令')) {
  onJumpClick('pages/Second');
} else {
  onJumpClick('pages/Third');
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

以上就是使用 @ohos.pasteboard API 实现剪贴板功能的基本方法。通过这些示例,你可以开始在自己的 HarmonyOS 应用中集成剪贴板功能了。

如果你有任何疑问或遇到问题,欢迎留言讨论!


请注意,上述代码片段是假设性的示例代码,实际应用中可能需要根据 HarmonyOS SDK 的具体实现进行调整。同时,确保你的开发环境已经安装了必要的 SDK 和工具包。