首页 > 其他分享 >Harmonyos Next——图片上传与下载

Harmonyos Next——图片上传与下载

时间:2024-06-02 14:33:41浏览次数:16  
标签:string err request Next Harmonyos let error 上传 图片

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

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

  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

  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

拷贝文件

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

  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等

  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即可完成对应下载功能

  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}`)
    }
  }

标签:string,err,request,Next,Harmonyos,let,error,上传,图片
From: https://blog.csdn.net/News53231323/article/details/139389123

相关文章

  • [干货]在纯血鸿蒙星河版next中组件封装方法--看我就够了
    首先组件封装一般是为了解决两个问题,复用和一定程度上提高维护性,组件的本质就是一个接受参数返回UI的函数容器,所以封装的重点和难点就是抽象合适的参数类型返回合适的UI,接下来我来给家人们说说封装组件的一般方法封装组件的一般方法呢有两种,思想家人们掌握之后往上套就行了,我......
  • [干货]鸿蒙next适用于api11,12,鸿蒙+支付宝支付整体流程以及坑点
         我在做这个功能支付的时候,一共是涉及到三个主体之间的通信,现在分享给家人们,分别是我们的客户端,我们自己的服务器,以及三方的支付宝服务器;我们前端做的就是头和尾两个部分,在头上呢我会跟我们自己的服务器进行交付,我会发起一个请求,我用的是一个web组件模拟了一个ge......
  • 鸿蒙HarmonyOS实战-Web组件(请求响应和页面调试)
    ......
  • 权限管理,鸿蒙Next版
      一、应用权限概述注意事项在鸿蒙开发中,调用部分API时需要申请权限后,才能调用,如:网络请求,获取网络信息等。部分API权限调用的时候还会弹窗,如:麦克风、位置、摄像头、相册、传感器(sensor)、日历等。申请应用权限时,需要注意两个关键信息:权限级别授权方式权限文档截图......
  • 【JavaScript脚本宇宙】从i18next到Date-fns:国际化和本地化库
    跨越JavaScript新境界:六大库全面评测前言本文将详细介绍六种具有不同功能的JavaScript库,包括处理多语言支持、全球化和本地化、格式化日期、数字和字符串,解析、验证、操作、显示日期和时间,格式化和操作数字,以及最全面、最简单和一致的工具集用于处理JavaScript中的日期等......
  • 企业微信接入系列-上传临时素材
    企业微信接入系列-上传临时素材文档介绍上传临时素材写在最后文档介绍创建企业群发的文档地址:https://developer.work.weixin.qq.com/document/path/92135,在创建企业群发消息或者群发群消息接口中涉及到上传临时素材的操作,具体文档地址:https://developer.work.weixin......
  • uniapp实现图片上传——支持APP、微信小程序
    uniapp实现图片、视频上传文章目录uniapp实现图片、视频上传效果图组件templatejs使用相关文档:结合uView插件+uni.uploadFile实现u-uploaduploadfile效果图组件简单封装,还有很多属性…,自定义样式等…根据个人所需调整template<template> <view>......
  • 鸿蒙HarmonyOS实战-Web组件(Cookie及数据存储)
    ......
  • idea将代码上传到gitee上
    先将代码上传到git本地仓库中操作流程:如图注意项目介绍不能为空,随便写写就行这样就上传到了本地仓库之后在上传到gitee远程仓库中    gitee官网地址:Gitee-基于Git的代码托管和研发协作平台面向企业提供一站式研发管理解决方案,包括代码管理、项目管理、文......
  • 文件上传时各配置目录优先级详解
    Tomcat配置目录有以下两个1.spring.servlet.multipart.location:文件上传路径2.server.tomcat.basedir:配置Tomcat运行日志和临时文件的目录。如果生产中配置了这两个目录,当上传文件时,他们的优先级是?    当上传文件时,代码执行到Request类,在发现使用时spring.servlet.mult......