赞
踩
从手机相册中选择一张图片,然后上传至服务器
在从相册或者拍摄获取的图片之前,需要进行权限申请,其权限为媒体内容读写权限
‘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.downloadFile
API完成。
例如存在https://xxxxxxx.com/system/202403/1773228028463067136.jpg
URL图片资源,
为了减少文件名称冗余和唯一性,我们可以只截取最后一部分做为下载之后的图片名称(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}`) } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。