鸿蒙应用开发-选择图库照片上传至服务器(request.uploadFile())
创始人
2025-01-21 05:36:12
0次

这篇文章主要介绍如何在鸿蒙应用开发中实现选择本地图库照片并上传至服务器的功能。将通过三个主要步骤:选择图片、拷贝到缓存目录、上传到服务器,来解释l整个过程,在关键步骤中加入必要的注意事项和坑点。

模拟器不能正确显示但截图后第一个位置有图片

第一步:用户选择图片

在鸿蒙系统中,使用PhotoViewPicker对象来实现图片选择功能。代码示例中定义了一个pickerAvatar函数,负责引导用户选择一张图片,并返回该图片的内存地址(URI)。

代码解析:
tsconst options = new picker.PhotoSelectOptions options.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE // 指定只能选择图片类型 options.maxSelectNumber = 1 // 用户只能选择一张图片
  • 注意:设置MIMEType确保用户只能选择图片,防止选择其他文件类型导致程序错误。

tsconst pickerView = new picker.PhotoViewPicker() let urls = await pickerView.select(options) if (urls.photoUris.length <= 0) {   return } let imgUrl = urls.photoUris[0] return imgUrl AlertDialog.show({ message: imgUrl })
  • 注意:务必检查urls.photoUris的长度,确保用户真的选择了图片。若没有选择图片,则函数提前退出。

第二步:拷贝图片到缓存目录

用户选择的图片通常位于只读存储中,需要将其拷贝到应用的缓存目录,以便后续处理。

代码解析:
tsconst file = fs.openSync(photoImgPath, fs.OpenMode.READ_ONLY) // 打开文件为只读模式 let fileFD = file.fd let destPath = getContext().cacheDir // 获取缓存目录路径 let fileName = Date.now().toString() + '.jpg' // 生成新的文件名 let fullPath = destPath + '/' + fileName AlertDialog.show({ message: '完整路径' + fullPath }) fs.copyFileSync(fileFD, fullPath) // 拷贝文件 return [`internal://cache/${fileName}`, fileName]
  • 注意:生成的文件名要确保唯一,避免覆盖已有文件。使用时间戳可以部分解决这个问题,但在高并发场景下仍可能有冲突。

第三步:上传图片到服务器

得到缓存目录中的图片文件后,通过网络请求将其上传至服务器。在上传过程中,我们可以通过日志或者UI来监听上传进度(日志示例)。

代码解析:
tslet user = AppStorage.get('user') as ILoginUsersModel let token = user?.token let uploader = await request.uploadFile(getContext(), {     method: 'POST',     url: 'https://teach.itheima.net/hm/userInfo/avatar',     header: {       'Content-Type': 'multipart/form-data',       'Authorization': `Bearer ${token}`     },     files: [{ filename: arr[1], type: 'jpg', name: 'file', uri: arr[0] }],     data: []   }) ​ uploader.on('progress', (uploadedSize, totalSize) => {     Logger.info('上传大小' + uploadedSize, '总大小:' + totalSize)     if (uploadedSize === totalSize) {       AlertDialog.show({ message: '上传已完成' })     } })
  • 注意:在上传文件时,监听上传进度可以用于调试,还可以增强用户交互体验。通过progress事件,我们能够实时更新用户界面,展示上传进度。

总结

上面案例中在鸿蒙系统开发中实现从选择图片到上传图片,并增加了进度监控功能。在实现时应注意文件类型的正确性、文件命名的唯一性、网络请求的安全性。

完整封装函数代码:

//1.用户选择图片后返回一个内存地址 async pickerAvatar() {   //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) {     return   }   let imgUrl = urls.photoUris[0]   return imgUrl   AlertDialog.show({ message: imgUrl }) }  //2.利用已获得的内存地址将系统相册的图片拷贝到缓存目录 async copyImgToCache(photoImgPath: string) {   //   // 2.1 根据源地址获取文件的磁盘目录,通过openSync()来获得的内存地址   const file = fs.openSync(photoImgPath, fs.OpenMode.READ_ONLY)   let fileFD = file.fd    //2.2利用fs拷贝到目标地址   //获取目标地址文件夹目录   let destPath = getContext().cacheDir   //随机生成一个文件名   let fileName = Date.now().toString()   //固定一个文件扩展名   const ext = 'jpg'   //组合成一个完整的目标文件路径   let fullPath = destPath + '/' + fileName + '.' + ext   AlertDialog.show({ message: '完整路径' + fullPath })   fs.copyFileSync(fileFD, fullPath)   //internal://cache代表fullPath 的文件路径   return [`internal://cache/${fileName + '.' + ext}`, fileName + '.' + ext] }  //3.将获取到的图片上传到服务器 async uploadAvatar(arr: string[]) {   let user = AppStorage.get('user') as ILoginUsersModel   let token = user?.token   let uploader = await request.uploadFile(getContext(), {     method: 'POST',     url: 'https://teach.itheima.net/hm/userInfo/avatar',     header: {       'Content-Type': 'multipart/form-data',       'Authorization': `Bearer ${token}`     },     files: [{ filename: arr[1], type: 'jpg', name: 'file', uri: arr[0] }],     data: []   })   uploader.on('progress', (uploadedSize, totleSize) => {     Logger.info('上传大小' + uploadedSize, '总大小:' + totleSize)     if (uploadedSize === totleSize) {       AlertDialog.show({ message: '上传已完成' })     }   }) } 

相关内容

热门资讯

菠萝智星德州详情!wepoke... 菠萝智星德州详情!wepoker是不是技术越好牌就越好(透视),原本真的是有透视软件主打赛后复盘的 ...
WePoKer有挂!微扑克发牌... WePoKer有挂!微扑克发牌真的很假(辅助),竟然是真的有辅助软件是一款可以让一直输的玩家,快速成...
红龙PoKer必备!wepok... 您好,wepoker开挂透视方法这款游戏可以开挂的,确实是有挂的,需要了解加微【136704302】...
德州扑克科普!德扑之星辅助下载... 您好,德扑之星辅助下载这款游戏可以开挂的,确实是有挂的,需要了解加微【485275054】很多玩家在...
aapoker总结!微扑克辅助... aapoker总结!微扑克辅助封号(辅助器),总是真的有辅助器安装是一款可以让一直输的玩家,快速成为...
微扑克普及!AlphaQ德州辅... 微扑克普及!AlphaQ德州辅助怎么样(辅助器),一向是真的有辅助器安装主打赛后复盘的 AI 游戏攻...
德州扑克必备!德州辅助app官... 您好,德州辅助app官方最新版本介绍大全这款游戏可以开挂的,确实是有挂的,需要了解加微【136704...
智星菠萝德州关于!德扑之星开挂... 智星菠萝德州关于!德扑之星开挂辅助器(辅助器),先前是有辅助器神器是一款可以让一直输的玩家,快速成为...
菠萝智星德州揭露!德扑之星系统... 您好:德扑之星系统规律这款游戏可以开挂的,确实是有挂的,很多玩家在这款游戏中打牌都会发现很多用户的牌...
WOK关于!wepoker辅助... WOK关于!wepoker辅助挂是什么(透视挂),原本是真的有透视挂软件AI 智能体黑科技再上新,自...