场景描述

在其它应用复制的口令在进入本应用时,会判断剪切板内容是普通文本复制还是口令复制。仅在确认为口令复制时,才会弹出窗口请求用户授权,可有效避免每次用户进入APP,只要剪贴板存有内容,就无差别弹框要求授权。

场景实现

在A应用中粘复制一段文本,然后打开B应用,B应用识别是否为B应用需要的口令,如果是,则进行权限申请等后续操作,如果不是则不进行后续操作。

效果展示

实现方案:

1、获取系统剪贴板对象。

let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard();

2、定义要检测的模式数组。

let patterns: Array<pasteboard.Pattern\> = [pasteboard.Pattern.URL, pasteboard.Pattern.NUMBER];

剪贴板支持检测的模式类型:

<p id="p2060213561771">名称</p> <p id="p1460275615718"></p> <p id="p17603105619713">类型</p>
<p id="p76061752811">URL</p> <p id="p36065515813">0</p> <p id="p56061651086">URL类型</p>
<p id="p137519154810">NUMBER</p> <p id="p12751215588">1</p> <p id="p107615157818">数字类型</p>
<p id="p107607211482">EMAIL_ADDRESS</p> <p id="p137601921286">2</p> <p id="p5760821183">邮箱地址类型</p>

3、先将传入的 patterns 数组和检测得到的 data 数组分别进行排序(使用sort方法),然后将排序后的数组元素连接成字符串(使用 join('') )再进行比较。其目的为看期望检测的所有模式是否都在剪贴板中被找到了,如果两个处理后的字符串相等,意味着所有期望的模式都在剪贴板里被检测到了,就会执行后续获取剪贴板数据的相关操作。只要符合这个格式的剪贴板内容都会触发后续操作。

systemPasteboard.detectPatterns(patterns).then((data: Array<pasteboard.Pattern>) => {
  if (patterns.sort().join('')==data.sort().join('')) {
    console.info('All needed patterns detected, next get data');
    try {
      const permissions: Array<Permissions> = ['ohos.permission.READ_PASTEBOARD'];
      this.reqPermissionsFromUser(permissions);
      let result = this.getPaste();
      console.info('Succeeded in getting PasteData.');
    } catch (err) {
      console.error('Failed to get PasteData. Cause:' + err.message);
    };
  } else {
    console.info("Not all needed patterns detected, no need to get data.");
  }
}

4、在进行权限申请之前,需要在module.json5中按需声明ohos.permission.READ\_PASTEBOARD权限以访问剪贴板。

// 在module.json5中声明ohos.permission.READ_PASTEBOARD权限
"requestPermissions": [
  {
    "name": "ohos.permission.READ_PASTEBOARD",
    "reason": "$string:app_name",
    "usedScene": {
      "abilities": [
        "EntryAbility",
      ],
      "when": "always"
    }
  }
],

5、在进行权限申请之前,需要先检查当前应用程序是否已经被授予权限。可以通过调用checkAccessToken()方法来校验当前是否已经授权。如果已经授权,则可以直接访问目标操作,否则需要进行下一步操作,即向用户申请授权。

//检查当前应用程序是否已经被授予权限
async function checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
//初始化grantStatus 变量,表示权限被拒绝的初始状态
let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
// 获取应用程序的accessTokenID
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}`);
}
return grantStatus;
}

6、通过调用reqPermissionsFromUser( )接口向用户申请授权。

//向用户申请授权
reqPermissionsFromUser(permissions: Array<Permissions> = ['ohos.permission.READ_PASTEBOARD']): void {
let context = getContext(this) as common.UIAbilityContext;
let atManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
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;
    }
  }
 })
}

7、当权限被授予时,尝试从系统剪贴板获取数据,如果成功则从 pasteData 中获取主要文本数据。如果权限未被授予,则根据 this.permission\_state 的状态来决定是否向用户请求权限或者进行其他处理。

//获取系统剪贴板的内容
async getPaste(): Promise < string > {
  const permissions: Array<Permissions> =['ohos.permission.READ_PASTEBOARD'];
  // 调用前面定义的 checkAccessToken 函数来检查是否已授予读取剪贴板的权限
  let grantStatus: abilityAccessCtrl.GrantStatus = await checkAccessToken(permissions[0]);
  //检查 grantStatus 是否为 PERMISSION_GRANTED,即检查是否已授予权限
  if(grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
  try {
  //获取系统剪贴板对象
  let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard();
  let pasteData = await systemPasteboard.getData();
  return pasteData.getPrimaryText();
  } catch (err) {
    hilog.error(0x0000, 'testTag', '%{public}s', `get oaid by promise catch error: ${err.code} ${err.message}`);
    return '';
  }
  } else {
  // 申请权限
  if (this.permission_state) {
    this.reqPermissionsFromUser(permissions);
  }
  return '';
 }
}

HarmonyOS码上奇行
11.5k 声望4.1k 粉丝

欢迎关注 HarmonyOS 开发者社区:[链接]