鸿蒙之用户头像上传、下载

用户头像上传工具类

包括本地相册上传以及拍照上传

import { fileIo, picker } from '@kit.CoreFileKit'
import fs from '@ohos.file.fs';
import { Logger } from './LoggerUtils';
import { promptAction } from '@kit.ArkUI';
import request from '@ohos.request';
import { ILoginUserData } from '../../models/LoginModel';
import { camera, cameraPicker } from '@kit.CameraKit';

export default class PickerUtils {
  // 拉起本地相册
  async takeLocalAlbumsPhoto() {
    //   1.0 引导用户选择一张系统相册的照片
    // 1.1 限定让用户只能从系统相册中选择1张图片
    const options = new picker.PhotoSelectOptions()
    options.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE //只能选择图片类型的资源
    options.maxSelectNumber = 1 //只能选择一张系统相册中的照片

    // 1.2 利用PhotoViewPicker对象实例中的select自动获取到用户选择的那张图片的地址
    const pickerView = new picker.PhotoViewPicker()
    let urls = await pickerView.select(options)

    //  判断用户取消了选择图片,则组织下面代码的继续运行
    if (urls.photoUris.length <= 0) {
      promptAction.showToast({
        message: "取消了图片选择"
      })
      return
    }
    // 获取图片
    let imgUri = urls.photoUris[0]
    AlertDialog.show({
      message: '本地相册图片' + imgUri
    })
    return imgUri //返回媒体文件路径,file://media/Photo/1/IMG_1715072681_000/screenshot_20240507_170301.jpg
  }


  // 调用相机拍照
  async CameraPhoto() {
    // 拉起相机
    const pickerResult = await cameraPicker.pick(
      getContext(),
      [cameraPicker.PickerMediaType.PHOTO], // PHOTO 拍照 / VIDEO 录视频
      {
        // 相机选择器的配置信息
        cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK, // 调用后摄像头
        // saveUri: this.avatarUri  // 保存路径,设置 saveUri 只会保存到沙箱,不保存到媒体相册
      }
    )
    let imgUri = pickerResult.resultUri //返回的是媒体文件路径file://media/Photo/···
    AlertDialog.show({
      message: '拍照文件路径' + imgUri
    })
    return imgUri //返回拍照后的媒体文件路径
  }


  //   二:将文件拷贝到沙箱缓存目录
  async CopyFileToCaChe(MediaFilePath: string) {
    // 打开文件,进行读写操作
    const file = fs.openSync(MediaFilePath, fs.OpenMode.READ_ONLY)
    //获取句柄
    let fileFD = file.fd

    //  2、 利用fs.copyFileSync方法,将文件的内存路径拷贝到缓存路径地址,fs.copyFileSync(原文件的内存地址,目标地址)
    // 获取缓存目录地址
    let context = getContext()
    // 上下文中有三个常用目录
    // context.cacheDir
    // context.fileDir
    // context.tempDir
    let filePath = context.cacheDir //沙箱缓存目录前缀----/data/storage/el2/base/haps/entry/cache/
    const fileType = 'jpg' // 固定一个文件的类型
    let fileName = Date.now().toString() + '.' + fileType // 利用时间戳随机生成一个文件名
    // 拼接成为一个完整的缓存文件路径地址
    let CachePath = filePath + '/' + fileName

    // 3、进行拷贝
    fs.copyFileSync(fileFD, CachePath) //data/storage/el2/base/haps/entry/cache/1715080988284.jpg

    return [CachePath, fileName, fileType] //返回沙箱文件的缓存路径,文件名、和文件类型,用于文件上传的参数使用
  }

  //   三:本地相册上传
  async UploadImageUri(MediaFilePath: string) { //FilePath是媒体文件
    // 打开文件,进行读写操作
    const file = fs.openSync(MediaFilePath, fs.OpenMode.READ_ONLY)
    //获取句柄
    let fileFD = file.fd
    //  2、 利用fs.copyFileSync方法,将文件的内存路径拷贝到缓存路径地址,fs.copyFileSync(原文件的内存地址,目标地址)
    // 获取缓存目录地址
    let context = getContext()
    // 上下文中有三个常用目录
    // context.cacheDir
    // context.fileDir
    // context.tempDir
    let filePath = context.cacheDir //沙箱缓存目录前缀----/data/storage/el2/base/haps/entry/cache/
    const fileType = 'jpg' // 固定一个文件的类型
    let fileName = Date.now().toString() + '.' + fileType // 利用时间戳随机生成一个文件名
    // 拼接成为一个完整的缓存文件路径地址
    let CachePath = filePath + '/' + fileName
    // 3、进行拷贝
    fs.copyFileSync(fileFD, CachePath) //data/storage/el2/base/haps/entry/cache/1715080988284.jpg
    AlertDialog.show({
      message: '本地沙箱缓存目录图片' + CachePath
    })

    //利用request.uploadFile实现文件上传
    let uploader = await request.uploadFile(getContext(), {
      method: 'POST', //请求方式
      url: 'https://api-harmony-teach.itheima.net/hm/userInfo/avatar', //请求地址      //todo---根据需要进行修改
      // 请求头
      header: {
        "Content-Type": "multipart/form-data",
        "Authorization": `Bearer ${(AppStorage.get('UserInfo') as ILoginUserData).token}`
      },
      files: [{
        name: 'file',
        uri: `internal://cache/${fileName}`,
        filename: fileName,
        type: fileType
        // name:指的是接口中的body中的参数名称,不能写错一定要和接口保持一致
        // uri:指的是应用程序缓存中文件的完整路径 `internal://cache/${fullFileName}`
        // filename:文件名称(包括后缀)
        // type:文件类型,也就是扩展名
      }],
      data: [] // 因为本接口除了上传文件之外,无需接收其他文本数据,所以空着即可
    })
    //uploader监听事件,有两个,一个progress用来监听上传进度事件,一个监听上传失败的事件//uploadSize代表当前已经下载的进度,total代表进度总和
    //progress用来监听上传进度
    //uploader监听事件,on中有complete,progress,fail等事件
    uploader.on('complete', () => {
      promptAction.showToast({
        message: '上传成功'
      })
    })
    uploader.on('fail', () => {
      promptAction.showToast({
        message: '上传失败'
      })
    })
  }

  /*相册拍照上传*/
  async CameraUploadImage(MediaFilePath: string) { //AvatarPath是媒体文件

    // 拷贝文件到缓存目录
    // -------------------------------------------------------------------
    // 利用fs.openSync方法,获取系统文件的内存路径,是一个数字
    const file = fs.openSync(MediaFilePath, fs.OpenMode.READ_ONLY)
    let fileFD = file.fd //文件的内存路径

    //  2、 利用fs.copyFileSync方法,将文件的内存路径拷贝到缓存路径地址,fs.copyFileSync(原文件的内存地址,目标地址)
    // 获取目标地址,系统缓存路径前缀----/data/storage/el2/base/haps/entry/cache/
    let filePath = getContext().cacheDir
    // 固定一个文件的扩展名
    const fileType = 'jpg'
    // 随机生成一个文件名
    let fileName = Date.now().toString() + '.' + fileType
    // 拼接成为一个完整的缓存文件路径地址
    let CachePath = filePath + '/' + fileName
    // 3、进行拷贝
    fs.copyFileSync(fileFD, CachePath) //data/storage/el2/base/haps/entry/cache/1715080988284.jpg
    AlertDialog.show({
      message: '拷贝后的沙箱缓存路径' + CachePath
    })
    // -----------------------------------------------------------------------------------

    //发送request请求
    // -----------------------------------------------------------------------------------
    let uploader = await request.uploadFile(getContext(), {
      method: 'POST',
      url: 'https://api-harmony-teach.itheima.net/hm/userInfo/avatar',
      header: {
        "Content-Type": "multipart/form-data",
        "Authorization": `Bearer ${(AppStorage.get('UserInfo') as ILoginUserData).token}`
      },
      // name:指的是接口中的body中的参数名称,不能写错一定要和接口保持一致
      // uri:指的是应用程序缓存中文件的完整路径 `internal://cache/${fullFileName}`
      //filename:文件名称
      // type:文件类型,也就是扩展名
      // files: [{ name: 'file', uri: `internal://cache/${fileArr[1]}`, filename: `10086${Randoms.getRandomMath(0,20)}`, type: fileArr[2] }],
      files: [{
        //注意上传的是缓存到沙箱文件中的文件,文件名,文件类型等等
        name: 'file',
        uri: `internal://cache/${fileName}`,
        filename: fileName,
        type: fileType
      }],
      data: [] // 因为本接口除了上传文件之外,无需接收其他文本数据,所以空着即可
    })
    //uploader监听事件,on中有complete,progress,fail等事件
    uploader.on('complete', () => {
      promptAction.showToast({
        message: '上传成功'
      })
    })
    uploader.on('fail', () => {
      promptAction.showToast({
        message: '上传失败'
      })
    })
    // -----------------------------------------------------------------------------------
  }


  //   四:下载图片
  async DownLoadFile(url: string, fileType: string) { //url是资源文件地址,fileType是资源文件格式
    // 获取缓存目录地址
    let context = getContext()
    // 上下文中有三个常用目录
    // context.cacheDir
    // context.fileDir
    // context.tempDir
    let fileDirPath = context.filesDir //沙箱缓存目录前缀----/data/storage/el2/base/haps/entry/file/
    let fileName = Date.now().toString() + '.' + fileType // 利用时间戳随机生成一个文件名
    // 拼接成为一个完整的缓存文件路径地址
    let filePath = fileDirPath + '/' + fileName
    // if (fileIo.listFileSync(context.filesDir).includes(fileName)) {
    //   //此时要备份,如果文件中已经存在
    // }
    // 下载文件
    const Task = await request.downloadFile(context, {
      url: url, //选择要下载的网络资源地址
      filePath//下载需要存放的沙箱目录
    })
    //uploader监听事件,on中有complete,progress,fail等事件
    Task.on('complete', () => {
      promptAction.showToast({
        message: '下载成功'
      })
    })
    Task.on('fail', () => {
      promptAction.showToast({
        message: '下载失败'
      })
    })

    AlertDialog.show({
      message: '下载后的文件目录为' + filePath
    })

    // 下载到系统本地相册
    
    return filePath //返回下载的沙箱文件缓存目录
  }
}

export const PickerManager = new PickerUtils()

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值