【HarmonyOS】应用实现读取剪切板内容(安全控件和自读取)

【HarmonyOS】应用实现读取粘贴板内容(安全控件和自读取)

前言

三方应用 读取系统剪切板是比较常见的功能。可以实现功能入口的快捷激活跳转,以及用户粘贴操作的简化,增强用户的体验感。

但是在用户日渐注重隐私的今天,系统对于剪切板权限的开放也在收紧。

在鸿蒙中实现剪切板很简单,目前有两种方式,分别为:1.使用粘贴安全控件 2.申请用户授权,应用自己读取

解决方案

1.使用粘贴安全控件

鸿蒙系统提供了PasteButton 安全组件,通过该按钮组件,用户点击即认为授权,不需要三方应用再自己申请权限。通过点击后的回调,再通过剪切板读取其中的内容pasteboard.getSystemPasteboard().getData。需要注意的时候,该按钮点击授权为临时授权,再app关闭,切到后台后授权就没有了,需要用户重新点击按钮。

所以一般该操作的设计都是,点击按钮后马上去读取剪切板内容,减少逻辑读取的链路。目前看读取虽然是异步,但是读取速度还是很快,影响不大

dart 复制代码
        PasteButton()
          .padding({top: 12, bottom: 12, left: 24, right: 24})
          .onClick((event: ClickEvent, result: PasteButtonOnClickResult) => {
            console.log(this.TAG, " PasteboardPage PasteButton result: " + JSON.stringify(result) + " event: " + JSON.stringify(event));
            if (PasteButtonOnClickResult.SUCCESS === result) {
              pasteboard.getSystemPasteboard().getData((err: BusinessError, pasteData: pasteboard.PasteData) => {
                console.log(this.TAG, " PasteboardPage getData err: " + JSON.stringify(err) + " pasteData: " + JSON.stringify(pasteData));
                if (err) {
                  return;
                }
                this.message = pasteData.getPrimaryText();
              });
            }
          })

----按钮样式需要显著,并且没有故意遮挡,透明度,UI叠加,误导用户等因素会导致按钮回调授权失败。原则是让用户能清晰感知此按钮是粘贴按钮。

2.申请用户授权,应用自读取

需要申请"ohos.permission.READ_PASTEBOARD"权限。该权限是管制权限,需要你的应用去通过场景申请,比如你有口令的场景,就可以申请该权限。【申请使用受限权限

------如果应用涉及获取受限权限,在应用发布上架时,应用市场(AGC)将根据应用的使用场景审核是否可以使用对应的受限权限。如不符合,应用的上架申请将被驳回,审核方式请见发布HarmonyOS应用。

当你申请了该权限后,就不需要安全控件,直接通过系统剪切板可以读取到其中的内容。

需要注意的是,申请的是对应场景,比如口令场景。但是系统并不会对你读取的内容做出过滤,你能读取到用户复制的所有内容,并不只是口令。

DEMO示例:

PasteboardPage.ets

dart 复制代码
import { hilog } from '@kit.PerformanceAnalysisKit';
import { abilityAccessCtrl, bundleManager, common } from '@kit.AbilityKit';
import { pasteboard, BusinessError } from '@kit.BasicServicesKit';

/**
 * 剪切板
 */
@Entry
@Component
struct PasteboardPage {

  private TAG: string = "PasteboardPage";

  @State message: string = '';

  private requestPermissions(context: common.Context): void {
    // 进入页面时,向用户请求授权广告跨应用关联访问权限
    const atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
    try {
      atManager.requestPermissionsFromUser(context, ["ohos.permission.READ_PASTEBOARD"]).then((data) => {
        if (data.authResults[0] === 0) {
          this.readPasteBoardData();
        } else {
          hilog.error(0x0000, 'testTag', '%{public}s', 'user rejected');
        }
      }).catch((err: BusinessError) => {
        hilog.error(0x0000, 'testTag', '%{public}s', `request permission failed, error: ${err.code} ${err.message}`);
      })
    } catch (err) {
      hilog.error(0x0000, 'testTag', '%{public}s', `catch err->${err.code}, ${err.message}`);
    }
  }


  onClickReadPasteboard = ()=>{
    this.requestPermissions(getContext());
  }

  private readPasteBoardData(){
    let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard();
    systemPasteboard.getData((err: BusinessError, pasteData: pasteboard.PasteData) => {
      if (err) {
        console.error('Failed to get PasteData. Cause: ' + err.message);
        return;
      }
      let text: string = pasteData.getPrimaryText();
      this.message = text;
    });
  }


  build() {
    Column({ space: 10 }) {
      Text("点击启用授权读取剪切板")
        .onClick(this.onClickReadPasteboard)

        TextInput({ placeholder: '请输入验证码', text: this.message })
          .onChange((value: string, previewText?: PreviewText)=>{
            console.log(this.TAG, " TextInput onChange value: " + JSON.stringify(value) + " previewText: " + JSON.stringify(previewText));
            this.message = value;
          })
        PasteButton()
          .padding({top: 12, bottom: 12, left: 24, right: 24})
          .onClick((event: ClickEvent, result: PasteButtonOnClickResult) => {
            console.log(this.TAG, " PasteboardPage PasteButton result: " + JSON.stringify(result) + " event: " + JSON.stringify(event));
            if (PasteButtonOnClickResult.SUCCESS === result) {
              pasteboard.getSystemPasteboard().getData((err: BusinessError, pasteData: pasteboard.PasteData) => {
                console.log(this.TAG, " PasteboardPage getData err: " + JSON.stringify(err) + " pasteData: " + JSON.stringify(pasteData));
                if (err) {
                  return;
                }
                this.message = pasteData.getPrimaryText();
              });
            }
          })
    }
    .justifyContent(FlexAlign.Center)
    .width('100%')
    .height('100%')
  }
}

module.json5

dart 复制代码
  "requestPermissions": [
  
      {
        "name": "ohos.permission.READ_PASTEBOARD",
        "usedScene": {
          "abilities": [
            "FormAbility"
          ],
          "when": "inuse"
        },
        "reason": "$string:module_desc",
      },

    ]
相关推荐
遇到困难睡大觉哈哈16 分钟前
HarmonyOS 公共事件机制介绍以及多进程之间的通信实现(9000字详解)
华为·harmonyos
hanniuniu133 小时前
AI时代API挑战加剧,API安全厂商F5护航企业数字未来
人工智能·安全
zhulangfly3 小时前
API接口安全-1:身份认证之传统Token VS JWT
安全
幽蓝计划3 小时前
HarmonyOS NEXT仓颉开发语言实战案例:外卖App
开发语言·harmonyos
伍哥的传说4 小时前
鸿蒙系统(HarmonyOS)应用开发之实现电子签名效果
开发语言·前端·华为·harmonyos·鸿蒙·鸿蒙系统
时时三省4 小时前
【时时三省】vectorcast使用教程
安全·安全架构
galaxylove5 小时前
Gartner发布最新指南:企业要构建防御性强且敏捷的网络安全计划以平衡安全保障与业务运营
网络·安全·web安全
PeterJXL5 小时前
Chrome 下载文件时总是提示“已阻止不安全的下载”的解决方案
前端·chrome·安全
Georgewu6 小时前
【HarmonyOS】应用开发拖拽功能详解
harmonyos
塞尔维亚大汉6 小时前
鸿蒙内核源码分析(构建工具篇) | 顺瓜摸藤调试鸿蒙构建过程
源码·harmonyos