HarmonyOS应用开发实战 - Api9 拍照、拍视频、选择图片、选择视频、选择文件工具类

鸿蒙开发过程中,经常会进行系统调用,拍照、拍视频、选择图库图片、选择图库视频、选择文件。今天就给大家分享一个工具类。

1.话不多说,先展示样式

在这里插入图片描述

2.设计思路

根据官方提供的指南开发工具类,基础的拍照、拍视频、图库选照片、选文件不过多缀述,图库选择这里设计成集合形式,可返回图片和视频,视频展示时不显示内容,所以在工具类多加了一个获取视频缩略图的功能。

3.具体代码

import common from '@ohos.app.ability.common';
import picker from '@ohos.file.picker';
import mediaLibrary from '@ohos.multimedia.mediaLibrary';
import wantConstant from '@ohos.ability.wantConstant';
import { MediaBean } from '../bean/MediaBean';
import { StringUtils } from '../utils/StringUtils';/*** @description 多媒体辅助类* @author Gwei* @time 2024/3/1 15:57*/
export class MediaHelper {private readonly TAG: string = 'MediaHelper';private mContext: common.Context;constructor(context: common.Context) {this.mContext = context;}/*** 图库选择,返回最大数量为9的图片、视频集合*/public selectPicture(count:number): Promise<Array<MediaBean>> {let imgList:Array<string> = [];let mediaList:Array<MediaBean> = [];try {let photoSelectOptions = new picker.PhotoSelectOptions();photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;photoSelectOptions.maxSelectNumber = 9-count;let photoPicker = new picker.PhotoViewPicker();return photoPicker.select(photoSelectOptions).then((photoSelectResult) => {//Log.info(this.TAG, 'PhotoViewPicker.select successfully, PhotoSelectResult uri: ' + JSON.stringify(photoSelectResult));if (photoSelectResult && photoSelectResult.photoUris && photoSelectResult.photoUris.length > 0) {for (let i = 0; i < photoSelectResult.photoUris.length; i++) {imgList.push(photoSelectResult.photoUris[i]);}//Log.info(this.TAG, 'PhotoViewPicker.select successfully, PhotoSelectResult uri: ' + filePath);return imgList;}}).catch((err) => {//Log.error(this.TAG, 'PhotoViewPicker.select failed with err: ' + err);return err;}).then(async (imgList) => {for (let index = 0; index < imgList.length; index++) {const mediaBean = await this.buildMediaBean(imgList[index]);mediaList.push(mediaBean);}return mediaList;});} catch (err) {//Log.error(this.TAG, 'PhotoViewPicker failed with err: ' + err);return Promise.reject(err);}}/*** 选择文件*/public selectFile(): Promise<MediaBean> {try {let documentSelectOptions = new picker.DocumentSelectOptions();let documentPicker = new picker.DocumentViewPicker();return documentPicker.select(documentSelectOptions).then((documentSelectResult) => {//Log.info(this.TAG, 'DocumentViewPicker.select successfully, DocumentSelectResult uri: ' + JSON.stringify(documentSelectResult));if (documentSelectResult && documentSelectResult.length > 0) {let filePath = documentSelectResult[0];//Log.info(this.TAG, 'DocumentViewPicker.select successfully, DocumentSelectResult uri: ' + filePath);return filePath;}}).catch((err) => {//Log.error(this.TAG, 'PhotoViewPicker.select failed with err: ' + err);return err;}).then(async (filePath) => {const mediaBean = await this.buildMediaBean(filePath);return mediaBean;});} catch (err) {//Log.error(this.TAG, 'PhotoViewPicker failed with err: ' + err);return Promise.reject(err);}}/*** 拍照*/public async takePhoto(context: common.UIAbilityContext): Promise<MediaBean> {let want = {'uri': '','action': wantConstant.Action.ACTION_IMAGE_CAPTURE,'parameters': {},};return context.startAbilityForResult(want).then((result) => {//Log.info(this.TAG, `startAbility call back , ${JSON.stringify(result)}`);if (result.resultCode === 0 && result.want && StringUtils.isNotNullOrEmpty(result.want.uri)) {//拍照成功//Log.info(this.TAG, 'takePhoto successfully, takePhotoResult uri: ' + result.want.uri);return result.want.uri;}}).catch((error) => {//Log.info(this.TAG, `startAbility error , ${JSON.stringify(error)}`);return error;}).then(async (uri: string) => {const mediaBean = await this.buildMediaBean(uri);return mediaBean;});}/*** 拍视频*/public async takeVideo(context: common.UIAbilityContext): Promise<MediaBean> {let want = {'uri': '','action': wantConstant.Action.ACTION_VIDEO_CAPTURE,'parameters': {},};return context.startAbilityForResult(want).then((result) => {//Log.info(this.TAG, `startAbility call back , ${JSON.stringify(result)}`);if (result.resultCode === 0 && result.want && StringUtils.isNotNullOrEmpty(result.want.uri)) {//拍照成功//Log.info(this.TAG, 'takePhoto successfully, takePhotoResult uri: ' + result.want.uri);return result.want.uri;}}).catch((error) => {//Log.info(this.TAG, `startAbility error , ${JSON.stringify(error)}`);return error;}).then(async (uri: string) => {const mediaBean = await this.buildMediaBean(uri);return mediaBean;});}/*** 封装多媒体实体类** @param uri 文件路径*/private async buildMediaBean(uri: string): Promise<MediaBean> {if (StringUtils.isNullOrEmpty(uri)) {return null;}const mediaBean: MediaBean = new MediaBean();mediaBean.localUrl = uri;await this.appendFileInfoToMediaBean(mediaBean, uri);return mediaBean;}/*** 通过Uri查找所选文件信息,插入到MediaBean中* @param mediaBean* @param uri*/private async appendFileInfoToMediaBean(mediaBean: MediaBean, uri: string):Promise<MediaBean> {if (StringUtils.isNullOrEmpty(uri)) {return;}let fileList: Array<mediaLibrary.FileAsset> = [];const parts: string[] = uri.split('/');const id: string = parts.length > 0 ? parts[parts.length - 1] : '-1';try {let media = mediaLibrary.getMediaLibrary(this.mContext);let mediaFetchOptions: mediaLibrary.MediaFetchOptions = {selections: mediaLibrary.FileKey.ID + '= ?',selectionArgs: [id],uri: uri};let fetchFileResult = await media.getFileAssets(mediaFetchOptions);//Log.info(this.TAG, `fileList getFileAssetsFromType fetchFileResult.count = ${fetchFileResult.getCount()}`);fileList = await fetchFileResult.getAllObject();fetchFileResult.close();await media.release();} catch (e) {//Log.error(this.TAG, "query: file data  exception ");}if (fileList && fileList.length > 0) {let fileInfoObj = fileList[0];//Log.info(this.TAG, `file id = ${JSON.stringify(fileInfoObj.id)} , uri = ${JSON.stringify(fileInfoObj.uri)}`);//Log.info(this.TAG, `file fileList displayName = ${fileInfoObj.displayName} ,size = ${fileInfoObj.size} ,mimeType = ${fileInfoObj.mimeType}`);mediaBean.fileName = fileInfoObj.displayName;mediaBean.fileSize = fileInfoObj.size;mediaBean.fileType = fileInfoObj.mimeType;mediaBean.pixelmap = await this.getPixelmap(fileInfoObj)}}/*** @description 获取缩略图* @author Gwei* @time 2024/3/1 15:57*/getPixelmap(fileInfoObj) {return new Promise(function (resolve, reject) {fileInfoObj.getThumbnail((err, pixelmap) => {if (!err) {resolve(pixelmap)}else{resolve('');}})})}
}

4.使用方法

async handleClick(option: MediaOption) {let mediaBean: MediaBean;switch (option) {case MediaOption.TakePhoto:mediaBean = await this.mediaHelper.takePhoto(getContext() as common.UIAbilityContext);this.imgList.push(mediaBean)break;case MediaOption.TakeVideo:mediaBean = await this.mediaHelper.takeVideo(getContext() as common.UIAbilityContext);this.imgList.push(mediaBean)break;case MediaOption.Picture:let list: Array<MediaBean> = [];list = await this.mediaHelper.selectPicture(this.imgList.length);for (let i = 0; i < list.length; i++) {this.imgList.push(list[i])}break;case MediaOption.File:mediaBean = await this.mediaHelper.selectFile();this.audioList.push(mediaBean);break;default:break;}
}

工具类已经提供给大家了,喜欢的可以点赞收藏!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/767522.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Python进行自动化测试Selenium与PyTest的结合【第150篇—自动化测试】

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 使用Python进行自动化测试&#xff1a;Selenium与PyTest的结合 在软件开发中&#xff0c;自…

线程与进程的爱恨情仇???

线程与进程的爱恨情仇&#xff1f;&#xff1f;&#xff1f; 一&#xff1a;有了进程&#xff0c;为什么还需要线程&#xff1f;&#xff1f;&#xff1f;二:线程三:线程和进程的区别与联系四:创建线程or创建进程 一&#xff1a;有了进程&#xff0c;为什么还需要线程&#xff…

css盒子模型及浮动

内容(content)、内边距(padding)、边框(border)、外边距(margin) oder:1px solid red; 边框的粗细 边框的样式&#xff08;虚线还是实线&#xff09; 边框的颜色 border中也有一些属性可以直接调某一个方向上的边框的粗细&#xff0c;样式&#xff0c;颜色 border-left\bord…

2024/3/24 LED点阵屏

显示原理&#xff1a; 类似矩阵键盘&#xff0c;逐行or逐列扫描 74HC595是串行 寄存器 感觉就是三转八寄存器 并行&#xff1a;同时输出&#xff1b;串行&#xff1a;一位一位输出 先配置74HC595&#xff0c;重新进行位声明 sbit RCKP3^5; //RCLK sbit SCKP3^6; …

芒果YOLOv8改进116:即插即用:集中特征金字塔Centralized Feature Pyramid 高效涨点改进

💡🚀🚀🚀本博客 改进源代码改进 适用于 YOLOv8 按步骤操作运行改进后的代码即可 该专栏完整目录链接: 芒果YOLOv8深度改进教程 🚀🚀🚀 文章目录 一、Centralized Feature Pyramid论文理论部分 + YOLOv8代码改进论文创新论文贡献论文网络部分实验对比2. YOLOv8 …

淘宝|天猫|京东|1688主流电商平台的实时数据返回接口|附Python实例

导读&#xff1a;随着淘宝/天猫直通车功能升级&#xff0c;很多功能越来越白盒化&#xff0c;越来越简化&#xff0c;更方便用户的操作&#xff0c;只需一键即可看出淘宝/天猫直通车存在的问题。淘宝/天猫直通车千人千面后有了实时数据工具&#xff0c;下面通过一个案例告诉大家…

23. UE5 RPG制作属性面板(一)

随着角色的属性越来越多&#xff0c;我们不能每次都进行showdebug abilitysystem进行查看&#xff0c;而且玩家也需要查看角色属性&#xff0c;所以需要一个查看玩家角色属性的面板。 在前面&#xff0c;我们创建三种类型的属性 Primary Attributes&#xff08;主要属性&#…

Spring-Cloud原理详解

Spring Cloud 是一套基于Spring Boot实现的云应用开发工具集&#xff0c;它为快速构建分布式系统提供了全面的解决方案&#xff0c;大大简化了在分布式系统中常见的诸如服务注册与发现、配置中心、熔断器、服务路由、负载均衡、全链路监控、服务追踪等问题的解决过程。下面是对…

Java面试题:生产者消费者问题与工厂方法模式;线程池与观察者模式;ThreadLocal 与单例模式

Java 并发编程与设计模式综合面试题解析 在软件开发中&#xff0c;Java 并发编程和设计模式是两个非常关键的领域&#xff0c;它们可以提高程序的性能、可维护性和灵活性。本文将详细解析三道综合性的 Java 面试题&#xff0c;这些题目将涵盖 Java 设计模式、内存管理、多线程…

软件测试面试问题总结—CTO面试

有一家公司技术面一面和二面都过了&#xff0c;在CTO三面的时候折掉了&#xff0c;反思了下&#xff0c;确实CTO面试的时候问的问题比较宏观&#xff0c;我的回答都比较浅&#xff0c;现在再总结下答案。 1、除了自动化测试&#xff0c;怎么提高测试效率&#xff1f; &#xff…

常见的OOM 问题的 6 种场景

今天跟大家一起聊聊线上服务出现 OOM 问题的 6 种场景,希望对你会有所帮助。 一、堆内存 OOM 堆内存 OOM 是最常见的 OOM 了。 出现堆内存 OOM 问题的异常信息如下: java.lang.OutOfMemoryError: Java heap space此 OOM 是由于 JVM 中 heap 的最大值,已经不能满足需求了…

资深测试总结,性能测试-常见并发问题+解决总结(最全)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、并发测试的定义…

Spring线程池ThreadPoolTaskExecutor的使用

Spring线程池ThreadPoolTaskExecutor的使用

指针和引用的权限

权限的放大&#xff0c;缩小&#xff0c;平移 适用于指针和引用 1.权限的放大(不允许) const int a 5;//const&#xff0c;对变量声明只读特性&#xff0c;保护变量值以防被修改 int* y &a;//把只读的赋给可改的&#xff0c;会报错 2.权限平移&#xff08;允许&…

lavarel的php程序是顺序执行,用pdo mysql连接池好像没有什么用啊。没有办法挂起等待啊,为什么要用连接池,应用场景是什么

Laravel 的 PHP 程序确实是基于请求-响应模式&#xff0c;每个请求都是顺序执行的。这意味着一旦一个请求开始处理&#xff0c;它会按照代码的顺序执行&#xff0c;直到完成并返回响应。因此&#xff0c;从表面上看&#xff0c;使用 PDO 或 MySQL 连接池在 Laravel 中可能看起来…

vscode用SSH远程开发c语言

vscode配置远程 这里我使用虚拟机进行展示&#xff0c;首先需要你的虚拟机安装好ssh 没安装好就执行下面的命令安装并开启服务 sudo apt-get install ssh sudo service ssh start ps -e | grep sshvscode安装 remote-ssh扩展 点击左下角的远程连接&#xff0c;我这里已经连接…

【Hive】HIVE运行卡死没反应

Hive运行卡死 再次强调 hive&#xff1a;小兄弟&#xff0c;没想到吧&#xff0c;咱可不是随便的人。&#x1f604; 那么&#xff0c;这次又遇见了hadoop问题&#xff0c;问题描述是这样的。 hive> insert into test values(1, nucty, 男); Query ID atguigu_202403241754…

图论基础|695. 岛屿的最大面积、1020. 飞地的数量、130. 被围绕的区域

695. 岛屿的最大面积 力扣题目链接(opens new window) 给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相邻的 1 (代表土地) 构成的组合&#xff0c;这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0&#xff0…

C语言操作符和数据类型的存储详解

CSDN成就一亿技术人 目录​​​​​​​ 一.操作符 一.算数操作符&#xff1a; 二.位移操作符&#xff1a; 三.位操作符&#xff1a; 四.赋值操作符&#xff1a; 五.单目操作符&#xff1a; 六.关系操作符&#xff1a; 七.逻辑操作符&#xff1a; 八.条件操作符&…

蓝桥杯day5刷题日记-分巧克力-天干地支-求和

P8647 [蓝桥杯 2017 省 AB] 分巧克力 思路&#xff1a;二分查找 #include <iostream> using namespace std; int n,k; int h[100010],w[100010];bool check(int x) {int sum0;for(int i0;i<n;i){sum(h[i]/x)*(w[i]/x);if(sum>k) return true;}return false; }int…