场景描述
在其它应用复制的口令在进入本应用时,会判断剪切板内容是普通文本复制还是口令复制。仅在确认为口令复制时,才会弹出窗口请求用户授权,可有效避免每次用户进入APP,只要剪贴板存有内容,就无差别弹框要求授权。
场景实现
在A应用中粘复制一段文本,然后打开B应用,B应用识别是否为B应用需要的口令,如果是,则进行权限申请等后续操作,如果不是则不进行后续操作。
效果展示
实现方案:
1、获取系统剪贴板对象。
let systemPasteboard: pasteboard.SystemPasteboard = pasteboard.getSystemPasteboard();
2、定义要检测的模式数组。
let patterns: Array<pasteboard.Pattern\> = [pasteboard.Pattern.URL, pasteboard.Pattern.NUMBER];
剪贴板支持检测的模式类型:
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 '';
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。