当前位置: 首页 > news >正文

HarmonyOS(52) 使用安全控件SaveButton保存图片

SaveButton使用简介

  • 前言
  • SaveButton简介
    • 约束与限制
  • 实现点击事件
    • 全部源码
  • 参考资料:

前言

在HarmonyOS(50) 截图保存功能实现一文中简单介绍了截图保存功能,本篇博文介绍一个更简单的保存图片控件SaveButton.

SaveButton简介

SaveButton允许用户通过点击按钮临时获取存储权限,无需额外的编写权限申请代码。当用户点击该控件时,应用会获得10秒内单次访问媒体库特权接口的授权。这适用于任何需要将文件保存到媒体库的应用场景,例如保存图片或视频等

约束与限制

  • 当用户首次点击应用中的保存控件,系统将弹窗请求用户授权。如果用户点击“取消”,弹窗消失,应用无授权,用户再次点击保存控件时,将会重新弹窗;如果用户点击“允许”,弹窗消失,应用将被授予临时保存权限,此后点击该应用的保存控件将不会弹窗。(弹授权弹框如图所示),默认样式是一个图标+下载字样
    在这里插入图片描述

  • 应用在onClick()触发回调到调用媒体库特权接口的时间间隔不能大于10秒。

  • 用户点击一次控件,仅获取一次授权调用。

  • 为了保障用户的隐私不被恶意应用获取,应用需确保安全控件是可见的且用户能够识别的。开发者需要合理的配置控件的尺寸、颜色等属性,避免视觉混淆的情况,如果发生因控件的样式不合法导致授权失败的情况,请检查设备错误日志。

  • 不支持自定义图标和文字,SaveButton自定义了下载图标和9中类型的文字枚举。效果如下图:
    在这里插入图片描述

相关代码如下:

 SaveButton()//默认样式SaveButton({icon:SaveIconStyle.FULL_FILLED,text:SaveDescription.SAVE})SaveButton({text:SaveDescription.SAVE_IMAGE})SaveButton({text:SaveDescription.SAVE_FILE})SaveButton({text:SaveDescription.DOWNLOAD})SaveButton({text:SaveDescription.DOWNLOAD_FILE})SaveButton({text:SaveDescription.DOWNLOAD_AND_SHARE})SaveButton({text:SaveDescription.RECEIVE})SaveButton({text:SaveDescription.CONTINUE_TO_RECEIVE})SaveButton({text:SaveDescription.SAVE_TO_GALLERY})

实现点击事件

点击保存的时候需要设置相应的点击事件,代码如下:

 SaveButton().onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => {if (result === SaveButtonOnClickResult.SUCCESS) {const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;// 免去权限申请和权限请求等环节,获得临时授权,保存对应图片savePhotoToGallery(context);} else {promptAction.showToast({ message: '设置权限失败!' })}})//注意该方法为异步方法
async function savePhotoToGallery(context: common.UIAbilityContext) {let helper = photoAccessHelper.getPhotoAccessHelper(context);// onClick触发后5秒内通过createAsset接口创建图片文件,5秒后createAsset权限收回。let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');// 使用uri打开文件,可以持续写入内容,写入过程不受时间限制let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);// $r('app.media.startIcon')需要替换为开发者所需的图像资源文件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: '已保存至相册!' });});
}}

全部源码

相关官方demo源码如下:

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';async function savePhotoToGallery(context: common.UIAbilityContext) {let helper = photoAccessHelper.getPhotoAccessHelper(context);try {// onClick触发后5秒内通过createAsset接口创建图片文件,5秒后createAsset权限收回。let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');// 使用uri打开文件,可以持续写入内容,写入过程不受时间限制let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);// $r('app.media.startIcon')需要替换为开发者所需的图像资源文件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}`);}
}

struct Index {build() {Row() {Column({ space: 10 }) {// $r('app.media.startIcon')需要替换为开发者所需的图像资源文件Image($r('app.media.startIcon')).height(400).width('100%')SaveButton().onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) => {if (result === SaveButtonOnClickResult.SUCCESS) {const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;// 免去权限申请和权限请求等环节,获得临时授权,保存对应图片savePhotoToGallery(context);} else {promptAction.showToast({ message: '设置权限失败!' })}})}.width('100%')}.height('100%').backgroundColor(0xF1F3F5)}
}

参考资料:

使用保存控件
SaveButton
HarmonyOS(50) 截图保存功能实现

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • G722.1.C简单介绍
  • 恢复丢失的数据:iPhone 恢复指南
  • R语言股价跳跃点识别:隐马尔可夫hmm和 GARCH-Jump对sp500金融时间序列分析
  • vue.js项目实战案例源码
  • 信息打点-红队工具篇FofaQuakeKunyuSuize水泽Arl灯塔
  • Windows 10远程桌面连接设置
  • -bash: ./log.sh: /bin/bash^M: 坏的解释器: 没有那个文件或目录
  • MySQL集群 主从复制 和 高可用 配置详解
  • 虚拟化设置和虚拟机相关的环境搭建
  • 备战2024年全国大学生数学建模竞赛:多波束测线问题的解题与优化
  • [排序和二分] 绝对差值和
  • 联华证券--开盘如何捕捉涨停股?解析哪些股票容易涨停
  • 监控平台之上报(未完成)
  • OpenCV绘图函数(1)绘制带箭头的直线函数arrowedLine()的使用
  • 【电脑小白】告别蓝屏恐慌:一步步教你排查和解决蓝屏问题,从此告别蓝屏烦恼!
  • [ JavaScript ] 数据结构与算法 —— 链表
  • 【399天】跃迁之路——程序员高效学习方法论探索系列(实验阶段156-2018.03.11)...
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • const let
  • ECMAScript6(0):ES6简明参考手册
  • Git学习与使用心得(1)—— 初始化
  • iOS编译提示和导航提示
  • Java比较器对数组,集合排序
  • JS 面试题总结
  • JS学习笔记——闭包
  • leetcode46 Permutation 排列组合
  • Lsb图片隐写
  • scrapy学习之路4(itemloder的使用)
  • Vue.js-Day01
  • vue2.0项目引入element-ui
  • Webpack 4 学习01(基础配置)
  • 程序员最讨厌的9句话,你可有补充?
  • 删除表内多余的重复数据
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 提醒我喝水chrome插件开发指南
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • 栈实现走出迷宫(C++)
  • 自定义函数
  • 《天龙八部3D》Unity技术方案揭秘
  • hi-nginx-1.3.4编译安装
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • $.ajax中的eval及dataType
  • (1)(1.13) SiK无线电高级配置(五)
  • (20)docke容器
  • (3)(3.5) 遥测无线电区域条例
  • (7)摄像机和云台
  • (C11) 泛型表达式
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (SpringBoot)第七章:SpringBoot日志文件
  • (差分)胡桃爱原石
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (亲测有效)推荐2024最新的免费漫画软件app,无广告,聚合全网资源!
  • (三)Honghu Cloud云架构一定时调度平台