【鸿蒙】- HarmonyOS Next中实现图片上传

打印 上一主题 下一主题

主题 657|帖子 657|积分 1971

媒介

在手机APP中,图片上传功能为用户提供了便捷的方式来分享和通报视觉信息。无论是在社交媒体上分享旅行照片、美食体验,还是在工作场合中提交项目进展报告、展示设计结果,用户都能通过图片上传功能轻松实现。这一功能的实现,不仅满意了用户对于信息分享和通报的需求,还使用户可以更加直观地表达自己的想法和感受,与他人举行更加丰富的交流。

实现步调

在鸿蒙系统中,图片上传功能通过简朴三步即可完成:首先选择图片,随后将图片拷贝至缓存目次,最后实行上传操作。接下来就让我们一起来看看详细如何实现的吧。

选择相册图片

因为选择图片需要用到 picker,接下来让简朴先容一下Picker。
选择器(Picker)是一个封装PhotoViewPicker、DocumentViewPicker、AudioViewPicker等API模块,具有选择与生存的本领。应用可以自行选择使用哪种API实现文件选择和文件生存的功能。此中我们主要使用的是PhotoViewPicker。
PhotoViewPicker(图库选择器对象),用来支持选择图片/视频和生存图片/视频等用户场景。
更多的详情请参考选择用户文件 (openharmony.cn)
详细的实现逻辑如下:
  1. import picker from '@ohos.file.picker';
  2. // 一、定义图片选择 Picker 的配置
  3. // 实例化 选项对象
  4. const photoSelectOptions = new picker.PhotoSelectOptions();
  5. // 过滤选择媒体文件类型为IMAGE
  6. photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
  7. // 选择媒体文件的最大数目
  8. photoSelectOptions.maxSelectNumber = 1;
  9. // 二、创建 图片选择对象并选择图片
  10. const photoViewPicker = new picker.PhotoViewPicker();
  11. // 调用 select 方法,传入选项对象
  12. photoViewPicker.select(photoSelectOptions).then(res=>{
  13.     const uri = res.photoUris[0]
  14.     // 因为只选了一张
  15.     AlertDialog.show({ message: '图片路径为:' + uri })
  16. })
复制代码


拷贝图片到缓存目次

当前上传应用文件功能,不支持直接上传当地相册的文件,仅支持上传应用缓存文件路径(cacheDir)下的文件。
在使用上传功能前,需要先申请权限,即在module.json5设置文件的requestPermissionsrequestPermissions标签中声明权限。
  1. "requestPermissions":[
  2.       {
  3.         "name" : "ohos.permission.INTERNET",
  4.         "reason": "$string:reason",
  5.         "usedScene": {
  6.           "abilities": [
  7.             "FormAbility"
  8.           ],
  9.           "when":"inuse"
  10.         }
  11.       }
  12. ]
复制代码
接下来使用 fs 模块将上一步的文件,拷贝到 cacheDir 目次下。
fs模块为基础文件操作API,提供基础文件操作本领,包括文件基本管理、文件目次管理、文件信息统计、文件流式读写等常用功能。
更多的详情请参考@ohos.file.fs (文件管理) (openharmony.cn)
  1. import fs from '@ohos.file.fs';
  2. // 三.将文件保存到缓存目录(只能上传在缓存目录中的文件)
  3. const context = getContext(this)
  4. const fileType = 'jpg'
  5. // 生成一个新的文件名
  6. const fileName = Date.now() + '.' + fileType
  7. // 通过缓存路径+文件名 拼接出完整的路径
  8. const copyFilePath = context.cacheDir + '/' + fileName
  9. // 将文件 拷贝到 临时目录
  10. const file = fs.openSync(uri, fs.OpenMode.READ_ONLY)
  11. fs.copyFileSync(file.fd, copyFilePath)
复制代码


上传文件

预备好参数调用request.uploadFile()得到上传对象 uploader
给uploader对象注册progress事件,监听上传进度 requestRes.on("progress", (uploadedSize: number, totalSize: number)=>{})
  1. import request from '@ohos.request';
  2. import http from '@ohos.net.http';
  3.   // 四、上传图片
  4.   // 上传文件
  5.   let files: Array<request.File> = [
  6.   // internal://cache/ 固定的
  7.     { filename: fileName, type: fileType, name: 'img', uri: `internal://cache/${fileName}` }
  8.   ]
  9.   request.uploadFile(context, {
  10.     url: '接口地址', // url 地址
  11.     method: 请求方法, // 请求方法
  12.     header: {
  13.       // 和接口文档的要求的格式对象
  14.       contentType: '',
  15.     },
  16.     files, // 文件信息
  17.     data: [] // 额外提交的数据,不能省略
  18.   })
  19.     .then((res => {
  20.       //获取到响应的内容
  21.       res.on('headerReceive', (value) => {
  22.         // 根据接口文档 转为对应的类型即可
  23.         const uploadRes = (value as UploadResponse)
  24.         const response = JSON.parse(uploadRes.body) as Response
  25.         AlertDialog.show({
  26.           message: response.data.url
  27.         })
  28.         console.log('上传的地址为:', response.data.url)
  29.       })
  30.     }))
复制代码


完备代码

  1. import picker from '@ohos.file.picker';
  2. import fs from '@ohos.file.fs';
  3. import request from '@ohos.request';
  4. import http from '@ohos.net.http';
  5. // 定义类型
  6. interface UploadResponse {
  7.   body: string
  8. }
  9. export interface Response {
  10.   /**
  11.    * 业务状态码
  12.    */
  13.   code: number;
  14.   /**
  15.    * 响应数据
  16.    */
  17.   data: Data;
  18.   /**
  19.    * 响应消息
  20.    */
  21.   message: string;
  22. }
  23. /**
  24. * 响应数据
  25. */
  26. export interface Data {
  27.   /**
  28.    * 上传成功的图片-在线地址
  29.    */
  30.   url: string;
  31. }
  32. // 实例化 选项对象
  33. const photoSelectOptions = new picker.PhotoSelectOptions();
  34. // 过滤选择媒体文件类型为IMAGE
  35. photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
  36. // 选择媒体文件的最大数目
  37. photoSelectOptions.maxSelectNumber = 1;
  38. @Entry
  39. @Component
  40. struct Page03_uploadImg {
  41.   
  42.   @State img :string =''
  43.   
  44.   build() {
  45.     Navigation() {
  46.       Column() {
  47.         Image(this.img)
  48.         Button('选择并上传图片')
  49.           .onClick(() => {
  50.             // 创建 图片选择对象
  51.             const photoViewPicker = new picker.PhotoViewPicker();
  52.             // 调用 select 方法,传入选项对象
  53.             photoViewPicker.select(photoSelectOptions)
  54.               .then(res => {
  55.                 const uri = res.photoUris[0]
  56.                 // 因为只选了一张
  57.                 // AlertDialog.show({ message: '图片路径为:' + uri })
  58.                 // 三、拷贝文件到缓存目录
  59.                 // 将文件保存到缓存目录(只能上传在缓存目录中的文件)
  60.                 const context = getContext(this)
  61.                 const fileType = 'jpg'
  62.                 // 生成一个新的文件名
  63.                 const fileName = Date.now() + '.' + fileType
  64.                 // 通过缓存路径+文件名 拼接出完整的路径
  65.                 const copyFilePath = context.cacheDir + '/' + fileName
  66.                 // 将文件 拷贝到 临时目录
  67.                 const file = fs.openSync(uri, fs.OpenMode.READ_ONLY)
  68.                 fs.copyFileSync(file.fd, copyFilePath)
  69.                 // 四、上传图片
  70.                 // 上传文件
  71.                 let files: Array<request.File> = [
  72.                 // internal://cache/ 固定的
  73.                 // name 和接口文档的要求对上
  74.                   { filename: fileName, type: fileType, name: 'img', uri: `internal://cache/${fileName}` }
  75.                 ]
  76.                 request.uploadFile(context, {
  77.                   
  78.                   url: '你的url 地址', // url 地址
  79.                   
  80.                   method: http.RequestMethod.POST, // 请求方法
  81.                   header: {
  82.                     // 和接口文档的要求的格式对象
  83.                     contentType: 'multipart/form-data',
  84.                   },
  85.                   files, // 文件信息
  86.                   data: [] // 额外提交的数据,不能省略
  87.                 })
  88.                   .then((res => {
  89.                     // 获取响应的内容
  90.                     res.on('headerReceive', (value) => {
  91.                       const uploadRes = (value as UploadResponse)
  92.                       const response = JSON.parse(uploadRes.body) as Response
  93.                       AlertDialog.show({
  94.                         message: response.data.url
  95.                       })
  96.                       this.img = response.data.url
  97.                     })
  98.                   }))
  99.               })
  100.           })
  101.       }
  102.     }
  103.     .titleMode(NavigationTitleMode.Mini)
  104.     .title('上传图片')
  105.   }
  106. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

欢乐狗

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表