Harmonyos Next——图片上传与下载

Harmonyos Next------图片上传与下载

图片上传至服务器

描述

从手机相册中选择一张图片,然后上传至服务器

选取图片

在从相册或者拍摄获取的图片之前,需要进行权限申请,其权限为媒体内容读写权限

'ohos.permission.READ_MEDIA' //允许应用读取用户外部存储中的媒体文件信息-用户授权

s'ohos.permission.WRITE_MEDIA' //允许应用读写用户外部存储中的媒体文件信息-用户授权

从相册选择图片

通过picker.PhotoViewPicker()选择相册内容,在选择之前可以设置选择数量、资源类型等。

例如选取其中一张图片,返回的URI格式如下:

file://media/Photo/2/IMG_1713776063_001/screenshot_20240422_165243.jpg

但此格式并不能直接上传至服务器,需要对其进行拷贝,格式转换等操作,将在下节进行阐述。

c 复制代码
  private async openGallery(onSuccess: (uri: string)=> void, onFailed: (error: string)=>void) {
    try {
      let PhotoSelectOptions = new picker.PhotoSelectOptions()
      PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE
      PhotoSelectOptions.maxSelectNumber = 1
      let photoPicker = new picker.PhotoViewPicker()
      photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: picker.PhotoSelectResult) => {
        //file://media/Photo/2/IMG_1713776063_001/screenshot_20240422_165243.jpg
        if (PhotoSelectResult.photoUris.length > 0) {
          onSuccess(PhotoSelectResult.photoUris[0])
        }
      }).catch((err: BusinessError) => {
        LoggerJoy.error('PhotoViewPicker.select failed with err: ' + JSON.stringify(err))
        onFailed(err.message)
      })
    } catch (error) {
      let err: BusinessError = error as BusinessError
      LoggerJoy.error('PhotoViewPicker failed with err: ' + JSON.stringify(err))
      onFailed(err.message)
    }
  }

通过拍摄获取图片

通过cameraPicker.pick打开相机页面,如果完成拍照并点击确认,则会返回如上节一样格式的URI

c 复制代码
  private async openCamera(onSuccess: (uri: string)=> void, onFailed: (error: string)=>void){
    try {
      let pickerProfile: cameraPicker.PickerProfile = {
        cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
      }
      let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(
        getContext(this),
        [cameraPicker.PickerMediaType.PHOTO, cameraPicker.PickerMediaType.VIDEO],
        pickerProfile
      )
      if (pickerResult) {
        onSuccess( pickerResult.resultUri)
      }
    } catch (error) {
      let err = error as BusinessError
      LoggerJoy.error(`the pick call failed. error code: ${err.code}`)
      onFailed(err.message)
    }
  }

将获取的图片上传至服务器

由于上述获取的文件为file开头,外部并不能直接进行访问,可以将其拷贝到APP目录下的沙箱文件中。由于本Demo采用的是系统提供的request.uploadFile,其路径前缀指定为internal://cache/,所有还需在拷贝之后的新路径前加上此前缀,此前缀对应的是临时目录cacheDir

拷贝文件

拷贝之后的文件存放于应用目录下的沙箱文件中

c 复制代码
  private async copyFileToCache(path: string, context: Context): Promise<string>{
    try {
      let file = await fs.open(path, fs.OpenMode.READ_WRITE)
      if (file){
        let dir =  context.cacheDir + '/avatar'
        if (!fs.accessSync(dir)) {
          fs.mkdirSync(dir)
        }
        let newpath = context.cacheDir + `/avatar/hohem${new Date().getTime()}.jpg`
        LoggerJoy.info(`newpath:${newpath}`)
        await fs.copyFile(file.fd, newpath)
        return newpath
      }
      return ''
    } catch (err){
      LoggerJoy.info("applog:open file failed with error message: " + err.message + ", error code: " + err.code)
      return ''
    }
  }

上传图片

在使用request前需要导入对应包

import { BusinessError, request } from '@kit.BasicServicesKit'

拷贝之后的路径格式如下

/data/storage/el2/base/haps/entry/cache/avatar/hohem1713924905931.jpg

然后在其前面添加指定前缀internal://cache/,由于此前缀对应的便是cacheDir目录,所以将拷贝之后的路径前面一部分进行省略,最终得到的路径如下

internal://cache/avatar/hohem1713924905931.jpg

若未对路径进行转换,会出现401-the parameters check fails this is fail path异常错误。

在进行上传时,需根据自己云服务器所配置的接受数据格式进行变化request.UploadConfig,例如是PUT还是POST,是否还需其他头参数,例如id、token等

c 复制代码
  private async uploadFileToCloud(context: Context, uploadUrl: string, path: string, avatar: string, onSuccess: (avatar: string)=> void, onFailed: (error: string) => void){
    let newPath = await this.copyFileToCache(path, context)//---/data/storage/el2/base/haps/entry/cache/avatar/hohem1713924905931.jpg
    newPath = `internal://cache/${newPath.split("cache/")[1]}` //internal://cache/avatar/hohem1713924905931.jpg
    LoggerJoy.info(`newpath:${newPath}`)
    let file: Array<request.File> = [
      {
        name: 'avatarName',
        filename: 'avatarFilename',
        uri: newPath,
        type: 'image'
      }
    ]

    let config: request.UploadConfig = {
      url: uploadUrl,
      method: 'PUT',
      files: file,
      header: {
        'Content-Type': 'application/octet-stream'
      },
      data: []
    }

    try {
      request.uploadFile(
        context,
        config
      ).then((result)=>{
        onSuccess(avatar)
      }).catch((err: BusinessError)=>{
        onFailed(err.message)
      })
    } catch (error) {
      //401-the parameters check fails   this is fail path
      onFailed((error as BusinessError).message)
    }
  }

图片下载

下载图片比上传图片简单的多,依旧使用系统提供的request.downloadFileAPI完成。

例如存在https://xxxxxxx.com/system/202403/1773228028463067136.jpgURL图片资源,

为了减少文件名称冗余和唯一性,我们可以只截取最后一部分做为下载之后的图片名称(1773228028463067136.jpg),然后同样保存到应用目录下的沙箱文件下。

最后调用request.downloadFile即可完成对应下载功能

c 复制代码
  private downloadImages(context: Context,url: string){
    let splits = url.split('/')
    let fileName = splits[splits.length - 1]
    let basePath = context.cacheDir + '/banner' //:/data/storage/el2/base/haps/entry/cache/banner/1773228028463067136.jpg
    this.checkBannerDirExist(basePath) //如果目录不存在,则直接创建目录
    let config: request.DownloadConfig = {
      url: url,
      filePath: `${basePath}/${fileName}`
    }
    try {
      request.downloadFile(context, config, (err: BusinessError, data: request.DownloadTask)=>{
        if (err) {
          //下载失败
          LoggerJoy.info(`write local banner failed:${url}`)
          return
        }
        LoggerJoy.info(`download banner successful:${url}`)
        //下载成功
      })
    } catch (error) {
      LoggerJoy.info(`write local banner failed:${(error as BusinessError).message}`)
    }
  }
相关推荐
sanzk28 分钟前
华为鸿蒙应用开发
华为·harmonyos
SoraLuna5 小时前
「Mac畅玩鸿蒙与硬件28」UI互动应用篇5 - 滑动选择器实现
macos·ui·harmonyos
ClkLog-开源埋点用户分析6 小时前
ClkLog企业版(CDP)预售开启,更有鸿蒙SDK前来助力
华为·开源·开源软件·harmonyos
mg6686 小时前
鸿蒙系统的优势 开发 环境搭建 开发小示例
华为·harmonyos
模拟IC攻城狮6 小时前
华为海思招聘-芯片与器件设计工程师-模拟芯片方向- 机试题-真题套题题目——共8套(每套四十题)
嵌入式硬件·华为·硬件架构·芯片
lqj_本人6 小时前
鸿蒙next选择 Flutter 开发跨平台应用的原因
flutter·华为·harmonyos
lqj_本人6 小时前
使用 Flutter 绘制一个棋盘
harmonyos
TangKenny7 小时前
计算网络信号
java·算法·华为
23zhgjx-NanKon7 小时前
华为eNSP:QinQ
网络·安全·华为
23zhgjx-NanKon7 小时前
华为eNSP:mux-vlan
网络·安全·华为