图片上传
由于鸿蒙系统的隐私安全保护,应用无法直接从系统相册中获取到图片,所以鸿蒙系统的图片上传流程主要有以下几步:
- 通过鸿蒙官方的API唤起系统相册,让用户将需要上传的图片选中并返回其在内存中的临时路径
- 通过临时路径我们将图片拷贝到应用的沙箱中
- 通过上传文件的API将应用沙箱中的图片文件进行上传
主要API有以下几个
@ohos.file.photoAccessHelper (相册管理模块)
@ohos.file.fs (文件管理)
@ohos.request (上传下载)
步骤:
1.创建PhotoViewPicker实例
let photoPicker = new photoAccessHelper.PhotoViewPicker();
2.使用PhotoViewPicker的Select()方法获取图片路径
const result = await photoPicker.select({
//可选择的媒体文件类型,若无此参数,则默认为图片和视频类型。
MIMEType: photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE,
//选择媒体文件的最大数量
maxSelectNumber: this.maxNumber
})
AlertDialog.show( { message: JSON.stringify(result.photoUris) } )
下面是select()方法的参数信息,我们这里只使用了前两个,其他参数可以去文档中查看
BaseSelectOptions12+
图库选择选项基类。
| 名称 | 类型 | 必填 | 说明 |
|---|---|---|---|
| MIMEType10+ | PhotoViewMIMETypes | 否 | 可选择的媒体文件类型,若无此参数,则默认为图片和视频类型。元服务API: 从API version 11开始,该接口支持在元服务中使用。 |
| maxSelectNumber10+ | number | 否 | 选择媒体文件数量的最大值(最大可设置的值为500,若不设置则默认为50)。元服务API: 从API version 11开始,该接口支持在元服务中使用。 |
3.处理selec()方法的返回值
select()方法的返回值是一个字符串类型的数组,其中的每一项表示一个图片在内存的临时地址,使用一个数组进行接收存储
interface ImageList {
/** 图片url */
url: string;
}
imgList: ImageList[] = []
if (result.photoUris?.length) {
this.imgList = result.photoUris.map(url => {
return { url } as ImageList
})
}
4.将图片拷贝到应用沙箱中
export const UpLoadFile = (list: ImageList[]): Promise<ImageList[]> => {
// 1.获取当前应用文件路径
const saveDir = getContext().cacheDir // cache目录
// 创建一个存储每张图片文件参数的数组
let fileParams: Array<request.File> = []
// 循环遍历图片列表,为每张图片生成文件参数信息,并存储到数组中
list.forEach(item => {
// 生成一个唯一的名字,util.generateRandomUUID() 是一个用于生成随机 UUID (Universally Unique Identifier) 的函数。
// UUID 是一种 128 位的数字,通常用于唯一标识信息。
let filename = util.generateRandomUUID() + ".jpg"
// item.url 相册路径 => 拷贝到cache目录下
const file = fs.openSync(item.url, fs.OpenMode.READ_ONLY)
fs.copyFileSync(file.fd, saveDir + "/" + filename)
// 生成一个参数
fileParams.push({
filename,
name: 'file',
type: 'jpg',
uri: `internal://cache/${filename}`
})
fs.closeSync(file.fd)
})
// 得到了参数,完成了拷贝
//AlertDialog.show({ message: JSON.stringify(fileParams) })
return uploadAPI(getContext(), fileParams)
}
5.通过request这个API的uploadFile()方法进行文件上传
export const uploadAPI = async (context: Context, files: request.File[]) => {
return new Promise<ImageList[]>(async (resolve, reject) => {
try {
let arr: ImageList[] = []
const task = await request.uploadFile(context, {
url: '你需要上传的服务器接口地址',
method: 'POST',
header: {
//根据要求填入请求头参数
"Content-Type": "multipart/form-data",
// 'Authorization': ''
},
files,
data: []
})
task.on('progress', (uploadedSize, totalSize) => {
console.log("upload_progress_:" + uploadedSize + ":" + totalSize)
})
task.on('fail', (event) => {
reject(new Error("上传失败"))
AlertDialog.show({ message: '失败:' + JSON.stringify(event) })
})
// 每次有响应结构都进来
task.on("headerReceive", (header) => {
if (header["body"]) {
// 从响应头中的body对象中取到图片在服务器中的地址,存储到arr数组中
const result = JSON.parse(header["body"]) as iResponse<string>
arr.push({
url: result.data!
})
}
})
task.on("complete", (event) => {
// 彻底成功后,将存储图片在服务器中的地址的arr数组作为promise的成功结果(resolve)返回
resolve(arr)
//AlertDialog.show({ message: '成功:' + JSON.stringify(event) })
})
} catch (error) {
promptAction.showToast({ message: error.message })
}
})
}