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

HarmonyOS 鸿蒙Next应用开发实战 - 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) => {
          if (photoSelectResult && photoSelectResult.photoUris && photoSelectResult.photoUris.length > 0) {

            for (let i = 0; i < photoSelectResult.photoUris.length; i++) {
              imgList.push(photoSelectResult.photoUris[i]);
            }
            return imgList;
          }

        }).catch((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) {
      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) => {
          if (documentSelectResult && documentSelectResult.length > 0) {
            let filePath = documentSelectResult[0];
            return filePath;
          }

        }).catch((err) => {
          return err;
        }).then(async (filePath) => {

          const mediaBean = await this.buildMediaBean(filePath);
          return mediaBean;

        });
    } catch (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) => {
        if (result.resultCode === 0 && result.want && StringUtils.isNotNullOrEmpty(result.want.uri)) {
          return result.want.uri;
        }
      }).catch((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) => {
        if (result.resultCode === 0 && result.want && StringUtils.isNotNullOrEmpty(result.want.uri)) {
          return result.want.uri;
        }
      }).catch((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);
      fileList = await fetchFileResult.getAllObject();
      fetchFileResult.close();
      await media.release();

    } catch (e) {
    }

    if (fileList && fileList.length > 0) {

      let fileInfoObj = fileList[0];
      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;
    }
}

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


更多关于HarmonyOS 鸿蒙Next应用开发实战 - Api9 拍照、拍视频、选择图片、选择视频、选择文件工具类的实战教程也可以访问 https://www.itying.com/category-93-b0.html

23 回复

鸿蒙OS4.0.0的真机,不用申请任何权限,就可以拿照片,拿文件并显示,拍照也可以。

更多关于HarmonyOS 鸿蒙Next应用开发实战 - Api9 拍照、拍视频、选择图片、选择视频、选择文件工具类的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


import { MediaBean } from '../bean/MediaBean';
import { StringUtils } from '../utils/StringUtils';

您好,请问这两个文件代码内容有吗?

由于您提供的HTML内容为空或不完整,我无法进行有效的转换。请提供完整的包含图片的HTML代码段,以便我能根据您的要求将其转换为Markdown格式。

看到了,

大家有没有发现,PhotoSelectOptions设置MIMEType无效,不管是设置为image还是video,打开都是显示全部。api9的模拟器跟4.0.0的真机都存在这个问题。

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:BV1S4411E7LY/?p=17

怎么样才能把选择到的图片的uri,正常pixelmap显示呢?

同样的问题,uri可以显示,但pixelMap没法显示,

请问这个可以自定义相机吗。

比如自定义前置摄像头,或后置摄像头。打开前置或后置摄像头后,在里面添加种按钮交互~

Api 11支持,Api9 暂时不支持,

api9竟然支持拍照?不是说只有系统应用才能调,我也没找到相关的文档

可以拍照的,你可以用这个方法试试。

拍照或者录像完成之后,点右下角的对号,不返回到result的回调里面,麻烦看到帮忙解惑一下,现在还没解决,谢谢!

任何不能用的原因可能是你不是API9,因为版本高于API9可能会遇到未审核通过的问题,也可能与加号有关。

那拍照和录视频的功能就不能正常使用了,只能等官方修改兼容?或者这种写法就不能兼容API9以上呢,

对,可能后续api11等有新的方式实现,

MediaBean和StringUtils内容是什么?

您好,拍照功能需要向华为申请权限吗?

清单文件:“ohos.permission.READ_MEDIA”,并需要在代码中动态申请权限’ohos.permission.READ_MEDIA’,

可以给个git地址吗,谢谢

在HarmonyOS鸿蒙Next应用开发中,Api9提供了丰富的工具类来实现拍照、拍视频、选择图片、选择视频和选择文件的功能。这些功能主要通过CameraKitFilePicker等API来实现。

  1. 拍照:使用CameraKittakePicture方法可以调用系统相机进行拍照。拍照完成后,可以通过回调获取照片文件路径。

  2. 拍视频:通过CameraKitstartVideoRecording方法可以启动视频录制,stopVideoRecording方法停止录制,并通过回调获取视频文件路径。

  3. 选择图片:使用FilePickerselectImage方法可以调用系统图库选择图片。选择完成后,可以通过回调获取图片文件路径。

  4. 选择视频:通过FilePickerselectVideo方法可以调用系统视频库选择视频。选择完成后,可以通过回调获取视频文件路径。

  5. 选择文件:使用FilePickerselectFile方法可以调用系统文件管理器选择文件。选择完成后,可以通过回调获取文件路径。

这些工具类简化了开发者与系统交互的流程,使得在鸿蒙Next应用中实现多媒体文件的选择和操作变得更加便捷。通过合理使用这些API,可以快速构建具备多媒体处理能力的应用。

回到顶部