鸿蒙APP开发实战:【Api9】拍照、拍视频;选择图片、视频、文件工具类

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

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

2.设计思路

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

更多鸿蒙开发应用知识已更新gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md参考前往。

3.具体代码

cpp 复制代码
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.使用方法

cpp 复制代码
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;
    }
}

工具类已经提供给大家了,希望能帮助到大家!!!

鸿蒙开发岗位需要掌握那些核心要领?

目前还有很多小伙伴不知道要学习哪些鸿蒙技术?不知道重点掌握哪些?为了避免学习时频繁踩坑,最终浪费大量时间的。

自己学习时必须要有一份实用的鸿蒙(Harmony NEXT)资料非常有必要。 这里我推荐,根据鸿蒙开发官网梳理与华为内部人员的分享总结出的开发文档。内容包含了:【ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战】等技术知识点。

废话就不多说了,接下来好好看下这份资料。

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习鸿蒙OpenHarmony知识←前往。下面是鸿蒙开发的学习路线图。

针对鸿蒙成长路线打造的鸿蒙学习文档。鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,帮助大家在技术的道路上更进一步。

其中内容包含:

《鸿蒙开发基础》鸿蒙OpenHarmony知识←前往

  1. ArkTS语言
  2. 安装DevEco Studio
  3. 运用你的第一个ArkTS应用
  4. ArkUI声明式UI开发
  5. .......

《鸿蒙开发进阶》鸿蒙OpenHarmony知识←前往

  1. Stage模型入门
  2. 网络管理
  3. 数据管理
  4. 电话服务
  5. 分布式应用开发
  6. 通知与窗口管理
  7. 多媒体技术
  8. 安全技能
  9. 任务管理
  10. WebGL
  11. 国际化开发
  12. 应用测试
  13. DFX面向未来设计
  14. 鸿蒙系统移植和裁剪定制
  15. ......

《鸿蒙开发实战》鸿蒙OpenHarmony知识←前往

  1. ArkTS实践
  2. UIAbility应用
  3. 网络案例
  4. ......

最后

鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行!

相关推荐
redreamSo1 小时前
中国式好男人的悲歌:200块的饭,一个人怎么就吃不下去了?
程序员
运维咖啡吧2 小时前
给朋友们分享个好消息 7天时间23.5k
前端·程序员·ai编程
AI大模型2 小时前
大模型炼丹术(七):LLM微调实战:训练一个垃圾邮件分类器
程序员·llm·agent
财经三剑客4 小时前
鸿蒙智行6月交付新车52747辆 单日交付量3651辆
华为·harmonyos
睿麒4 小时前
鸿蒙app 开发中的 map 映射方式和用法
华为·harmonyos
陈随易4 小时前
Kimi k2发布,效果比肩Sonnet4,价格与DeepSeek一致
前端·后端·程序员
考虑考虑4 小时前
Redis8新增特性
redis·后端·程序员
大模型开发5 小时前
10分钟构建本地RAG应用
程序员·agent
zhanshuo6 小时前
鸿蒙 Secure Boot 全流程解析:从 BootROM 到内核签名验证的实战指南
harmonyos
zhanshuo6 小时前
鸿蒙系统安全机制全解:安全启动 + 沙箱 + 动态权限实战落地指南
harmonyos