【关键字】
openPicker / 13900002 / lstatSync / fileio
【问题描述】
打开相机或者相册获取图片后路径,获取文件上传,设置路径打开文件时候报错 openPicker {"code":13900002}。
以下是调用关键代码:
const permissions: Array<Permissions> = [ 'ohos.permission.READ_MEDIA'
];
const context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
//查看是否有权限
reqPermissionsFromUser(permissions, context,getContext(this)).then((res)=>{
let jurisdictionStatus = res
if(jurisdictionStatus){//有权限
//可以选择的张数
let length = this.maxLength - this.fileList.length
openPicker(getContext(this),length).then((res)=>{
//图片上传处理
this.images(res)
})
}else{
console.log('无权限=====')
}
});
下边是工具类关键代码:
//获取权限
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { picker } from '@kit.CoreFileKit';
import fs from '@ohos.file.fs';
import { uploadModels } from '../Models/myModel';
import { camera, cameraPicker } from '@kit.CameraKit';
import { MyLog } from '@ohos/BaseComponentLibrary/Index';
import { ToastUtil } from '@ohos/BaseComponentLibrary/src/main/ets/utils/ToastUtil';
export async function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext,content:Context):Promise<boolean>{
let jurisdictionStatus:boolean = false
let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
// requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
await atManager.requestPermissionsFromUser(context, permissions).then((data) => {
let grantStatus: Array<number> = data.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
if (grantStatus[i] === 0) {
console.log('用户已授权')// 用户授权,可以继续访问目标操作
//chooseAlbum(content)
// openPicker(content)
jurisdictionStatus = true
} else {
jurisdictionStatus = false
ToastUtil.showToast('用户拒绝授权')
console.log('用户拒绝授权')// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
return;
}
}
// 授权成功
}).catch((err: BusinessError) => {
console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
})
return jurisdictionStatus
}
// 弹出图片选择器方法
export async function openPicker(content:Context,maxLength:number) {
let photoUriList:uploadModels[] = []
try {
// 设置图片选择器选项
const photoSelectOptions = new picker.PhotoSelectOptions();
photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
photoSelectOptions.maxSelectNumber = maxLength;//最大张数
// 创建并实例化图片选择器
const photoViewPicker = new picker.PhotoViewPicker();
// 选择图片并获取图片URI
let uris: picker.PhotoSelectResult = await photoViewPicker.select(photoSelectOptions);
let newUrlList:uploadModels[] = []
if (!uris || uris.photoUris.length === 0){
photoUriList = []
}else{
uris.photoUris.forEach((item)=>{
MyLog.error("item---"+item)
let itemlList = item.split('.')
const fileType = itemlList[itemlList.length-1]
let list = itemlList[0].split('/')
// const fileName = list[list.length-1] + '.' + fileType
// 生成一个新的文件名 对名字格式有要求在此更改
const fileName = new Date().getTime() + '.' + fileType
// 打开文件读取流
// let file = fs.openSync(item, fs.OpenMode.READ_WRITE|fs.OpenMode.CREATE);
let file = fs.openSync(item, fs.OpenMode.READ_ONLY);
console.error('file fd: ' + file.fd);
let stat = fs.lstatSync(item);
MyLog.error("state---------"+stat.size+"----------")
// 获取当前上下文
let context = getContext(content) as common.UIAbilityContext;
// 新建一个保存裁剪后图片的路径
let newUrl = context.cacheDir + '/' + fileName;
console.log(context.cacheDir,newUrl,'是个什么路径')
// 复制图片到新的路径
fs.copyFileSync(file.fd, newUrl);
// 关闭文件读取流
fs.closeSync(file);
newUrlList.push({
fileName:fileName,
fileType:fileType,
filePath:item
})
})
photoUriList = newUrlList
}
// 更新状态变量:设置显示图片的URI
// content.imgUri = newUrl;
// 更新状态变量:保存原始图片的URI
// content.imgOriginal = uri;
// 图片更改时触发的方法
// this.imgChange();
} catch (e) {
console.error('openPicker', JSON.stringify(e));
}
return photoUriList
}
export async function chooseCamera(context:common.Context){
let photoUriList:uploadModels[] = []
try {
let pickerProfile: cameraPicker.PickerProfile = {
cameraPosition:camera.CameraPosition.CAMERA_POSITION_BACK
};
let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(context,[cameraPicker.PickerMediaType.PHOTO],pickerProfile)
console.log("成功获取图片"+ pickerResult.resultUri)
let itemlList = pickerResult.resultUri.split('.')
const fileType = itemlList[itemlList.length-1]
let list = itemlList[0].split('/')
const fileName = list[list.length-1] + '.' + fileType
photoUriList.push({
fileName:fileName,
fileType:fileType,
filePath:pickerResult.resultUri
})
} catch (error){
let err = error as BusinessError
console.log('失败 code' + err.code)
}
return photoUriList
}
【解决方案】
报错原因是因为lstatSync接口传入的路径必须是文件的应用沙箱路径。
相关参考: