用户头像上传工具类
包括本地相册上传以及拍照上传
import { fileIo, picker } from '@kit.CoreFileKit'
import fs from '@ohos.file.fs';
import { Logger } from './LoggerUtils';
import { promptAction } from '@kit.ArkUI';
import request from '@ohos.request';
import { ILoginUserData } from '../../models/LoginModel';
import { camera, cameraPicker } from '@kit.CameraKit';
export default class PickerUtils {
// 拉起本地相册
async takeLocalAlbumsPhoto() {
// 1.0 引导用户选择一张系统相册的照片
// 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) {
promptAction.showToast({
message: "取消了图片选择"
})
return
}
// 获取图片
let imgUri = urls.photoUris[0]
AlertDialog.show({
message: '本地相册图片' + imgUri
})
return imgUri //返回媒体文件路径,file://media/Photo/1/IMG_1715072681_000/screenshot_20240507_170301.jpg
}
// 调用相机拍照
async CameraPhoto() {
// 拉起相机
const pickerResult = await cameraPicker.pick(
getContext(),
[cameraPicker.PickerMediaType.PHOTO], // PHOTO 拍照 / VIDEO 录视频
{
// 相机选择器的配置信息
cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK, // 调用后摄像头
// saveUri: this.avatarUri // 保存路径,设置 saveUri 只会保存到沙箱,不保存到媒体相册
}
)
let imgUri = pickerResult.resultUri //返回的是媒体文件路径file://media/Photo/···
AlertDialog.show({
message: '拍照文件路径' + imgUri
})
return imgUri //返回拍照后的媒体文件路径
}
// 二:将文件拷贝到沙箱缓存目录
async CopyFileToCaChe(MediaFilePath: string) {
// 打开文件,进行读写操作
const file = fs.openSync(MediaFilePath, fs.OpenMode.READ_ONLY)
//获取句柄
let fileFD = file.fd
// 2、 利用fs.copyFileSync方法,将文件的内存路径拷贝到缓存路径地址,fs.copyFileSync(原文件的内存地址,目标地址)
// 获取缓存目录地址
let context = getContext()
// 上下文中有三个常用目录
// context.cacheDir
// context.fileDir
// context.tempDir
let filePath = context.cacheDir //沙箱缓存目录前缀----/data/storage/el2/base/haps/entry/cache/
const fileType = 'jpg' // 固定一个文件的类型
let fileName = Date.now().toString() + '.' + fileType // 利用时间戳随机生成一个文件名
// 拼接成为一个完整的缓存文件路径地址
let CachePath = filePath + '/' + fileName
// 3、进行拷贝
fs.copyFileSync(fileFD, CachePath) //data/storage/el2/base/haps/entry/cache/1715080988284.jpg
return [CachePath, fileName, fileType] //返回沙箱文件的缓存路径,文件名、和文件类型,用于文件上传的参数使用
}
// 三:本地相册上传
async UploadImageUri(MediaFilePath: string) { //FilePath是媒体文件
// 打开文件,进行读写操作
const file = fs.openSync(MediaFilePath, fs.OpenMode.READ_ONLY)
//获取句柄
let fileFD = file.fd
// 2、 利用fs.copyFileSync方法,将文件的内存路径拷贝到缓存路径地址,fs.copyFileSync(原文件的内存地址,目标地址)
// 获取缓存目录地址
let context = getContext()
// 上下文中有三个常用目录
// context.cacheDir
// context.fileDir
// context.tempDir
let filePath = context.cacheDir //沙箱缓存目录前缀----/data/storage/el2/base/haps/entry/cache/
const fileType = 'jpg' // 固定一个文件的类型
let fileName = Date.now().toString() + '.' + fileType // 利用时间戳随机生成一个文件名
// 拼接成为一个完整的缓存文件路径地址
let CachePath = filePath + '/' + fileName
// 3、进行拷贝
fs.copyFileSync(fileFD, CachePath) //data/storage/el2/base/haps/entry/cache/1715080988284.jpg
AlertDialog.show({
message: '本地沙箱缓存目录图片' + CachePath
})
//利用request.uploadFile实现文件上传
let uploader = await request.uploadFile(getContext(), {
method: 'POST', //请求方式
url: 'https://api-harmony-teach.itheima.net/hm/userInfo/avatar', //请求地址 //todo---根据需要进行修改
// 请求头
header: {
"Content-Type": "multipart/form-data",
"Authorization": `Bearer ${(AppStorage.get('UserInfo') as ILoginUserData).token}`
},
files: [{
name: 'file',
uri: `internal://cache/${fileName}`,
filename: fileName,
type: fileType
// name:指的是接口中的body中的参数名称,不能写错一定要和接口保持一致
// uri:指的是应用程序缓存中文件的完整路径 `internal://cache/${fullFileName}`
// filename:文件名称(包括后缀)
// type:文件类型,也就是扩展名
}],
data: [] // 因为本接口除了上传文件之外,无需接收其他文本数据,所以空着即可
})
//uploader监听事件,有两个,一个progress用来监听上传进度事件,一个监听上传失败的事件//uploadSize代表当前已经下载的进度,total代表进度总和
//progress用来监听上传进度
//uploader监听事件,on中有complete,progress,fail等事件
uploader.on('complete', () => {
promptAction.showToast({
message: '上传成功'
})
})
uploader.on('fail', () => {
promptAction.showToast({
message: '上传失败'
})
})
}
/*相册拍照上传*/
async CameraUploadImage(MediaFilePath: string) { //AvatarPath是媒体文件
// 拷贝文件到缓存目录
// -------------------------------------------------------------------
// 利用fs.openSync方法,获取系统文件的内存路径,是一个数字
const file = fs.openSync(MediaFilePath, fs.OpenMode.READ_ONLY)
let fileFD = file.fd //文件的内存路径
// 2、 利用fs.copyFileSync方法,将文件的内存路径拷贝到缓存路径地址,fs.copyFileSync(原文件的内存地址,目标地址)
// 获取目标地址,系统缓存路径前缀----/data/storage/el2/base/haps/entry/cache/
let filePath = getContext().cacheDir
// 固定一个文件的扩展名
const fileType = 'jpg'
// 随机生成一个文件名
let fileName = Date.now().toString() + '.' + fileType
// 拼接成为一个完整的缓存文件路径地址
let CachePath = filePath + '/' + fileName
// 3、进行拷贝
fs.copyFileSync(fileFD, CachePath) //data/storage/el2/base/haps/entry/cache/1715080988284.jpg
AlertDialog.show({
message: '拷贝后的沙箱缓存路径' + CachePath
})
// -----------------------------------------------------------------------------------
//发送request请求
// -----------------------------------------------------------------------------------
let uploader = await request.uploadFile(getContext(), {
method: 'POST',
url: 'https://api-harmony-teach.itheima.net/hm/userInfo/avatar',
header: {
"Content-Type": "multipart/form-data",
"Authorization": `Bearer ${(AppStorage.get('UserInfo') as ILoginUserData).token}`
},
// name:指的是接口中的body中的参数名称,不能写错一定要和接口保持一致
// uri:指的是应用程序缓存中文件的完整路径 `internal://cache/${fullFileName}`
//filename:文件名称
// type:文件类型,也就是扩展名
// files: [{ name: 'file', uri: `internal://cache/${fileArr[1]}`, filename: `10086${Randoms.getRandomMath(0,20)}`, type: fileArr[2] }],
files: [{
//注意上传的是缓存到沙箱文件中的文件,文件名,文件类型等等
name: 'file',
uri: `internal://cache/${fileName}`,
filename: fileName,
type: fileType
}],
data: [] // 因为本接口除了上传文件之外,无需接收其他文本数据,所以空着即可
})
//uploader监听事件,on中有complete,progress,fail等事件
uploader.on('complete', () => {
promptAction.showToast({
message: '上传成功'
})
})
uploader.on('fail', () => {
promptAction.showToast({
message: '上传失败'
})
})
// -----------------------------------------------------------------------------------
}
// 四:下载图片
async DownLoadFile(url: string, fileType: string) { //url是资源文件地址,fileType是资源文件格式
// 获取缓存目录地址
let context = getContext()
// 上下文中有三个常用目录
// context.cacheDir
// context.fileDir
// context.tempDir
let fileDirPath = context.filesDir //沙箱缓存目录前缀----/data/storage/el2/base/haps/entry/file/
let fileName = Date.now().toString() + '.' + fileType // 利用时间戳随机生成一个文件名
// 拼接成为一个完整的缓存文件路径地址
let filePath = fileDirPath + '/' + fileName
// if (fileIo.listFileSync(context.filesDir).includes(fileName)) {
// //此时要备份,如果文件中已经存在
// }
// 下载文件
const Task = await request.downloadFile(context, {
url: url, //选择要下载的网络资源地址
filePath//下载需要存放的沙箱目录
})
//uploader监听事件,on中有complete,progress,fail等事件
Task.on('complete', () => {
promptAction.showToast({
message: '下载成功'
})
})
Task.on('fail', () => {
promptAction.showToast({
message: '下载失败'
})
})
AlertDialog.show({
message: '下载后的文件目录为' + filePath
})
// 下载到系统本地相册
return filePath //返回下载的沙箱文件缓存目录
}
}
export const PickerManager = new PickerUtils()