SaveButton(this.saveButtonOptions) // 创建安全控件按钮 .onClick(async (event, result: SaveButtonOnClickResult) => { if (result == SaveButtonOnClickResult.SUCCESS) { try { // 1、使用安全控件创建文件 let phAccessHelper: photoAccessHelper.PhotoAccessHelper = photoAccessHelper.getPhotoAccessHelper(this.context); let options: photoAccessHelper.CreateOptions = { title: Date.now().toString() }; let photoUri: string = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.VIDEO, 'mp4', options); console.info('CameraDemo createAsset successfully, photoUri: ' + photoUri); // 2.1、方式一:通过文件管理写入文件 let file = fs.openSync(photoUri, fs.OpenMode.WRITE_ONLY); fs.writeSync(file.fd, this.imageBuffer); //图片的buffer数据 fs.closeSync(file); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo savePicture error: ${JSON.stringify(err)}`); } } else { console.error('CameraDemo SaveButtonOnClickResult createAsset failed.'); } });
async dialogSave(imageBuffer: ArrayBuffer) { try { //下载后的数据保存到Cache目录下 const newFileName = util.generateRandomUUID() + '.mp4'; const newFilePath = this.context.cacheDir + '/' + newFileName; const srcFileUri = fileUri.getUriFromPath(newFilePath); let file: fs.File = await fs.open(srcFileUri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); await fs.write(file.fd, imageBuffer); await fs.close(file); console.info('文件路径:' + srcFileUri); let srcFileUris: Array<string> = [ srcFileUri ]; // 指定待保存照片的创建选项,包括文件后缀和照片类型,标题和照片子类型可选 let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [ { title: 'test', fileNameExtension: 'mp4', photoType: photoAccessHelper.PhotoType.VIDEO, subtype: photoAccessHelper.PhotoSubtype.DEFAULT, } ]; // 基于弹窗授权的方式获取媒体库的目标uri let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(this.context); let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs); // 将来源于应用沙箱的照片内容写入媒体库的目标uri let desFile: fileIo.File = await fileIo.open(desFileUris[0], fileIo.OpenMode.WRITE_ONLY); let srcFile: fileIo.File = await fileIo.open(srcFileUri, fileIo.OpenMode.READ_ONLY); await fileIo.copyFile(srcFile.fd, desFile.fd); fileIo.closeSync(srcFile); fileIo.closeSync(desFile); console.info('create asset by dialog successfully'); } catch (err) { console.error(`failed to create asset by dialog successfully errCode is: ${err.code}, ${err.message}`); } }
应用通过相册管理模块photoAccessHelper下的getAssets查询接口,会查询出应用有读权限的图片和视频,也就是查询到应用本身保存到图库的这些资源,从而获取到这些资源的媒体uri。
async getAssetsUri(): Promise<void> { let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(this.context); let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates(); let fetchOption: photoAccessHelper.FetchOptions = { fetchColumns: [photoAccessHelper.PhotoKeys.WIDTH, photoAccessHelper.PhotoKeys.HEIGHT, photoAccessHelper.PhotoKeys.TITLE, photoAccessHelper.PhotoKeys.DURATION], predicates: predicates }; let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOption); // 得到uri对应的PhotoAsset对象,读取文件的部分信息 const asset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject(); // 获取到的媒体uri this.videoSrc = asset.uri; }
完整示例参考如下:
import fs from '@ohos.file.fs'; import common from '@ohos.app.ability.common'; import { BusinessError } from '@ohos.base'; import photoAccessHelper from '@ohos.file.photoAccessHelper'; import http from '@ohos.net.http'; import fileIo from '@ohos.file.fs'; import { util } from '@kit.ArkTS'; import { fileUri } from '@kit.CoreFileKit'; import { dataSharePredicates } from '@kit.ArkData'; @Entry @Component struct Index { private controller: VideoController | undefined; @State videoSrc: string = ''; // url需要替换成应用自己的链接,否则后续无法成功运行 public url: string = 'XXXX'; @State imageBuffer: ArrayBuffer | undefined = undefined; public context = this.getUIContext().getHostContext() as common.UIAbilityContext; @State saveButtonOptions: SaveButtonOptions = { icon: SaveIconStyle.FULL_FILLED, text: SaveDescription.SAVE_FILE, buttonType: ButtonType.Capsule }; aboutToAppear(): void { // 每一个httpRequest对应一个HTTP请求任务,不可复用 let httpRequest = http.createHttp(); let options: http.HttpRequestOptions = { method: http.RequestMethod.GET, readTimeout: 60000, connectTimeout: 60000, maxLimit: 100 * 1024 * 1024, expectDataType: http.HttpDataType.ARRAY_BUFFER }; httpRequest .request(this.url, options, async (error: BusinessError, data: http.HttpResponse) => { if (error) { console.error('httpRequest failed.'); } // 判断网络获取到的资源是否为ArrayBuffer类型 if (data.result instanceof ArrayBuffer) { this.imageBuffer = data.result as ArrayBuffer; } } ); } async dialogSave(imageBuffer: ArrayBuffer) { try { //下载后的数据保存到Cache目录下 const newFileName = util.generateRandomUUID() + '.mp4'; const newFilePath = this.context.cacheDir + '/' + newFileName; const srcFileUri = fileUri.getUriFromPath(newFilePath); let file: fs.File = await fs.open(srcFileUri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); await fs.write(file.fd, imageBuffer); await fs.close(file); console.info('文件路径:' + srcFileUri); let srcFileUris: Array<string> = [ srcFileUri ]; // 指定待保存照片的创建选项,包括文件后缀和照片类型,标题和照片子类型可选 let photoCreationConfigs: Array<photoAccessHelper.PhotoCreationConfig> = [ { title: 'test', fileNameExtension: 'mp4', photoType: photoAccessHelper.PhotoType.VIDEO, subtype: photoAccessHelper.PhotoSubtype.DEFAULT, } ]; // 基于弹窗授权的方式获取媒体库的目标uri let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(this.context); let desFileUris: Array<string> = await phAccessHelper.showAssetsCreationDialog(srcFileUris, photoCreationConfigs); // 将来源于应用沙箱的照片内容写入媒体库的目标uri let desFile: fileIo.File = await fileIo.open(desFileUris[0], fileIo.OpenMode.WRITE_ONLY); let srcFile: fileIo.File = await fileIo.open(srcFileUri, fileIo.OpenMode.READ_ONLY); await fileIo.copyFile(srcFile.fd, desFile.fd); fileIo.closeSync(srcFile); fileIo.closeSync(desFile); console.info('create asset by dialog successfully'); } catch (err) { console.error(`failed to create asset by dialog successfully errCode is: ${err.code}, ${err.message}`); } } /** *通过getAssets接口查询应用自身保存到图库的资源,无需申请受限权限 */ async getAssetsUri(): Promise<void> { let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(this.context); let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates(); let fetchOption: photoAccessHelper.FetchOptions = { fetchColumns: [photoAccessHelper.PhotoKeys.WIDTH, photoAccessHelper.PhotoKeys.HEIGHT, photoAccessHelper.PhotoKeys.TITLE, photoAccessHelper.PhotoKeys.DURATION], predicates: predicates }; let fetchResult: photoAccessHelper.FetchResult<photoAccessHelper.PhotoAsset> = await phAccessHelper.getAssets(fetchOption); // 得到uri对应的PhotoAsset对象,读取文件的部分信息 const asset: photoAccessHelper.PhotoAsset = await fetchResult.getFirstObject(); // 获取到的媒体uri this.videoSrc = asset.uri; } build() { Column() { Text(' ').fontSize(20); Text('方案一:安全控件获取uri'); SaveButton(this.saveButtonOptions) // 创建安全控件按钮 .onClick(async (event, result: SaveButtonOnClickResult) => { if (result == SaveButtonOnClickResult.SUCCESS) { try { // 1、使用安全控件创建文件 let phAccessHelper: photoAccessHelper.PhotoAccessHelper = photoAccessHelper.getPhotoAccessHelper(this.context); let options: photoAccessHelper.CreateOptions = { title: Date.now().toString() }; let photoUri: string = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.VIDEO, 'mp4', options); console.info('CameraDemo createAsset successfully, photoUri: ' + photoUri); // 2.1、方式一:通过文件管理写入文件 let file = fs.openSync(photoUri, fs.OpenMode.WRITE_ONLY); fs.writeSync(file.fd, this.imageBuffer); //图片的buffer数据 fs.closeSync(file); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo savePicture error: ${JSON.stringify(err)}`); } } else { console.error('CameraDemo SaveButtonOnClickResult createAsset failed.'); } }); Text(' ').fontSize(20); Text('方案二:弹窗授权获取uri'); Button('弹窗授权获取uri') .fontSize(20) .fontWeight(FontWeight.Bold) .onClick(() => { if (this.imageBuffer) { this.dialogSave(this.imageBuffer); } }) .height('5%') .width('50%'); Text(' ').fontSize(20); Text('方案三:直接查询媒体uri'); Button('直接查询媒体uri') .fontSize(20) .fontWeight(FontWeight.Bold) .onClick(() => { this.getAssetsUri(); }) .height('5%') .width('50%'); Video({ src: this.videoSrc, controller: this.controller }) .width('100%') .height(300); }; } }