鸿蒙Next安全控件深度揭秘:粘贴与保存控件全解析

210 阅读7分钟

本文旨在深入探讨华为鸿蒙HarmonyOS Next系统(截止目前 API12)在开发多语言电商平台方面的技术细节,基于实际开发实践进行总结。主要作为技术分享与交流载体,难免错漏,欢迎各位同仁提出宝贵意见和问题,以便共同进步。本文为原创内容,任何形式的转载必须注明出处及原作者。

在鸿蒙 Next 系统的安全体系中,安全控件扮演着至关重要的角色,为应用提供了便捷且安全的用户交互方式,有效保护用户隐私。今天,我们将聚焦于其中的粘贴控件和保存控件,深入剖析它们的功能与使用方法。

一、粘贴控件:简化剪贴板数据读取

(一)粘贴控件的作用

粘贴控件是一种特殊的系统安全控件,其主要功能是在用户授权的情况下,实现应用无提示地读取剪贴板数据。在日常使用中,我们经常需要在不同应用之间复制和粘贴信息,如复制验证码、文本段落等。粘贴控件的出现,使得这一过程更加流畅和便捷,同时也保障了用户数据的安全性。它就像是一座桥梁,在用户明确授权的前提下,安全地将剪贴板中的数据传递给应用,避免了弹窗提示对用户操作的干扰。

(二)使用粘贴控件读取剪贴板数据的方法

  1. 导入依赖

首先,在应用的代码文件中导入与剪贴板相关的依赖模块。例如:


import { pasteboard } from '@kit.BasicServicesKit';

这一步骤就像是准备好工具,确保应用能够与剪贴板进行交互。

  1. 添加粘贴控件到界面

在应用的用户界面布局中添加粘贴控件。粘贴控件通常以按钮的形式呈现,由图标、文本和背景组成,其中图标和文本至少需要有一个,背景是必选的。例如:


@Entry

@Component

struct Index {

@State message: string = '';

build() {

Row() {

Column({ space: 10 }) {

TextInput({ placeholder: '请输入验证码', text: this.message })

PasteButton()

.padding({ top: 12, bottom: 12, left: 24, right: 24 })

// 后续添加点击事件处理逻辑

}

.width('100%')

}

.height('100%')

}

}

在上述代码中,我们在一个包含输入框的布局中添加了粘贴控件,为后续读取剪贴板数据并填充到输入框做好准备。

  1. 处理粘贴控件点击事件

当用户点击粘贴控件时,应用需要处理相应的点击事件,以获取剪贴板中的数据并进行处理。例如:


.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();

});

}

})

在点击事件处理函数中,通过pasteboard.getSystemPasteboard().getData()方法获取剪贴板数据。如果获取成功,将数据中的主要文本内容设置为输入框的文本,实现了快速粘贴功能。

(三)粘贴控件使用限制和开发步骤表格展示

|使用限制|开发步骤|

|---|---|

|临时授权会持续到灭屏、应用切后台、应用退出情况发生。
应用在授权期间没有调用次数限制。
为保障用户隐私,应用需确保安全控件可见且用户能识别,避免因控件样式问题导致授权失败。|1. 导入剪贴板依赖。
2. 添加输入框和粘贴控件到界面。
3. 处理粘贴控件点击事件,获取并处理剪贴板数据。|

(四)示例代码:使用粘贴控件读取验证码

以下是一个完整的使用粘贴控件读取验证码的示例代码:


import { pasteboard, BusinessError } from '@kit.BasicServicesKit';

import { Component, State, ClickEvent, PasteButtonOnClickResult } from '@ohos.arkui.extension.component';

@Entry

@Component

struct Index {

@State message: string = '';

build() {

Row() {

Column({ space: 10 }) {

TextInput({ placeholder: '请输入验证码', text: this.message })

PasteButton()

.padding({ top: 12, bottom: 12, left: 24, right: 24 })

.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();

});

}

})

}

.width('100%')

}

.height('100%')

}

}

在这个示例中,用户在输入验证码的输入框旁点击粘贴控件,应用将读取剪贴板中的数据并填充到输入框中,方便用户快速输入验证码。

二、保存控件:便捷文件保存到媒体库

(一)保存控件的作用

保存控件为应用提供了一种快速、便捷的方式将文件保存到媒体库中。与传统的保存方式相比,它无需用户手动选择保存路径,而是直接将文件保存到指定的媒体库路径,大大提高了操作效率。无论是保存图片、视频还是其他类型的文件,保存控件都能在用户点击后迅速完成保存操作,同时确保了操作的安全性和权限的合理控制。

(二)使用保存控件保存文件到媒体库的方法

  1. 导入相关依赖

在使用保存控件之前,需要导入与文件操作和媒体库访问相关的依赖模块。例如:


import { photoAccessHelper } from '@kit.MediaLibraryKit';

import { fileIo } from '@kit.CoreFileKit';

这些依赖模块提供了访问媒体库和进行文件读写操作的必要功能。

  1. 设置要保存的文件资源并添加保存控件

首先,确定要保存的文件资源,并在应用界面中添加保存控件。例如,以下代码展示了如何在一个包含图片的界面中添加保存控件:


import { photoAccessHelper } from '@kit.MediaLibraryKit';

import { fileIo } from '@kit.CoreFileKit';

import { common } from '@kit.AbilityKit';

import { promptAction } from '@kit.ArkUI';

import { BusinessError } from '@kit.BasicServicesKit';

@Entry

@Component

struct Index {

build() {

Row() {

Column({ space: 10 }) {

// 假设这里有一个图片资源,实际应用中应替换为真实的图片资源

Image($r('app.media.startIcon'))

.height(400)

.width('100%')

SaveButton()

.padding({ top: 12, bottom: 12, left: 24, right: 24 })

// 后续添加点击事件处理逻辑

}

.width('100%')

}

.height('100%')

.backgroundColor(0xF1F3F5)

}

}

在上述代码中,我们在显示图片的界面中添加了保存控件,以便用户在查看图片后能够方便地保存图片到媒体库。

  1. 处理保存控件点击事件

当用户点击保存控件时,应用需要处理点击事件,执行保存文件到媒体库的操作。例如:


.onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => {

if (result === SaveButtonOnClickResult.SUCCESS) {

const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;

let helper = photoAccessHelper.getPhotoAccessHelper(context);

try {

// 创建图片文件,这里使用默认的图片类型和格式,实际应用中可根据需求调整

let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');

// 打开文件,准备写入内容

let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);

// 假设这里有一个图片资源,实际应用中应替换为真实的图片资源

context.resourceManager.getMediaContent($r('app.media.startIcon').id, 0)

.then(async value => {

let media = value.buffer;

// 将图片数据写入媒体库文件

await fileIo.write(file.fd, media);

await fileIo.close(file.fd);

promptAction.showToast({ message: '已保存至相册!' });

});

} catch (error) {

const err: BusinessError = error as BusinessError;

console.error(`Failed to save photo. Code is ${err.code}, message is ${err.message}`);

}

} else {

promptAction.showToast({ message: '设置权限失败!' });

}

})

在点击事件处理函数中,首先获取应用上下文,然后通过photoAccessHelper创建图片文件的资源路径(uri),接着使用fileIo打开文件并写入图片数据。如果保存成功,显示提示信息告知用户文件已保存到相册;如果保存失败,显示相应的错误信息。

(三)保存控件使用限制和开发步骤表格展示

|使用限制|开发步骤|

|---|---|

|当用户首次点击保存控件,系统将弹窗请求用户授权,若点击“取消”,再次点击会重新弹窗;点击“允许”,应用将被授予临时保存权限,此后点击不再弹窗。
应用在 onClick()触发回调到调用媒体库特权接口的时间间隔不能大于 10 秒。
用户点击一次控件,仅获取一次授权调用。
为保障用户隐私,应用需确保安全控件可见且用户能识别,避免因控件样式问题导致授权失败。|1. 导入文件和媒体库依赖。
2. 设置图片资源(或其他文件资源),并添加保存控件。
3. 处理保存控件点击事件,执行保存文件到媒体库的操作。|

(四)示例代码:使用保存控件保存照片

以下是一个使用保存控件保存照片的完整示例代码:


import { photoAccessHelper } from '@kit.MediaLibraryKit';

import { fileIo } from '@kit.CoreFileKit';

import { common } from '@kit.AbilityKit';

import { promptAction } from '@kit.ArkUI';

import { BusinessError } from '@kit.BasicServicesKit';

@Entry

@Component

struct Index {

build() {

Row() {

Column({ space: 10 }) {

// 假设这里有一个图片资源,实际应用中应替换为真实的图片资源

Image($r('app.media.startIcon'))

.height(400)

.width('100%')

SaveButton()

.padding({ top: 12, bottom: 12, left: 24, right: 24 })

.onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => {

if (result === SaveButtonOnClickResult.SUCCESS) {

const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;

let helper = photoAccessHelper.getPhotoAccessHelper(context);

try {

// 创建图片文件,这里使用默认的图片类型和格式,实际应用中可根据需求调整

let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');

// 打开文件,准备写入内容

let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);

// 假设这里有一个图片资源,实际应用中应替换为真实的图片资源

context.resourceManager.getMediaContent($r('app.media.startIcon').id, 0)

.then(async value => {

let media = value.buffer;

// 将图片数据写入媒体库文件

await fileIo.write(file.fd, media);

await fileIo.close(file.fd);

promptAction.showToast({ message: '已保存至相册!' });

});

} catch (error) {

const err: BusinessError = error as BusinessError;

console.error(`Failed to save photo. Code is ${err.code}, message is ${err.message}`);

}

} else {

promptAction.showToast({ message: '设置权限失败!' });

}

})

}

.width('100%')

}

.height('100%')

.backgroundColor(0xF1F3F5)

}

}

在这个示例中,用户在查看图片时,点击保存控件,应用将图片保存到媒体库(相册)中,并显示相应的提示信息告知用户保存结果。

总之,粘贴控件和保存控件为鸿蒙 Next 应用提供了更加便捷、安全的用户交互功能。我们通过合理运用这些控件,能够提升应用的用户体验,同时遵循系统的安全规范,保护用户隐私。希望本文能够帮助各位同行者深入理解和熟练运用粘贴控件和保存控件,为用户打造更加出色的应用。