1/* 2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15import userFileManager from '@ohos.filemanagement.userFileManager' 16import fileAccess from '@ohos.file.fileAccess'; 17import dataSharePredicates from '@ohos.data.dataSharePredicates'; 18import DateTimeUtil from '../model/DateTimeUtil' 19import Logger from '../model/Logger' 20import common from '@ohos.app.ability.common'; 21 22export enum FileType { 23 IMAGE = 1, 24 VIDEO = 2, 25 AUDIO = 3, 26 FILE= 4 27} 28 29export default class MediaUtils { 30 private tag: string = 'MediaUtils' 31 private mediaTest: userFileManager.UserFileManager = undefined 32 private static instance: MediaUtils = undefined 33 34 public static getInstance(context: any) { 35 if (this.instance === undefined) { 36 this.instance = new MediaUtils(context) 37 } 38 return this.instance 39 } 40 41 constructor(context: any) { 42 this.mediaTest = userFileManager.getUserFileMgr(context) 43 } 44 45 async createAndGetUri(mediaType: number): Promise<userFileManager.FileAsset> { 46 let info = this.getInfoFromType(mediaType) 47 let dateTimeUtil = new DateTimeUtil() 48 let name = `${dateTimeUtil.getDate()}_${dateTimeUtil.getTime()}` 49 let displayName = `${info.prefix}${name}${info.suffix}` 50 Logger.info(this.tag, `displayName = ${displayName},mediaType = ${mediaType}`) 51 let fetchFileResult: userFileManager.FileAsset = undefined; 52 // 新建音频资源 53 if (mediaType === FileType.AUDIO) { 54 fetchFileResult = await this.mediaTest.createAudioAsset(displayName); 55 } else { 56 // 新建图片/视频资源 57 fetchFileResult = await this.mediaTest.createPhotoAsset(displayName); 58 } 59 return fetchFileResult; 60 } 61 62 async getFdPath(fileAsset: any) { 63 let fd = await fileAsset.open('Rw') 64 Logger.info(this.tag, `fd = ${fd}`) 65 return fd 66 } 67 68 async createFile(mediaType: number, context: common.UIAbilityContext) { 69 let info = this.getInfoFromType(mediaType) 70 let dateTimeUtil = new DateTimeUtil() 71 let name = `${dateTimeUtil.getDate()}_${dateTimeUtil.getTime()}` 72 let displayName = `${info.prefix}${name}${info.suffix}` 73 Logger.info(this.tag, `displayName = ${displayName},mediaType = ${mediaType}`) 74 let fd: number = -1; 75 76 try { 77 let fileAccessHelper = fileAccess.createFileAccessHelper(context); 78 79 // 获取目录url 80 let rootIterator: fileAccess.RootIterator = await fileAccessHelper.getRoots(); 81 let sourceUri: string = rootIterator.next().value.uri 82 83 // 以异步方法创建文件到指定目录,返回新文件uri 84 let fileUri = await fileAccessHelper.createFile(sourceUri, displayName); 85 Logger.info(this.tag, "createFile success, fileUri: " + JSON.stringify(fileUri)); 86 87 // 以异步方法打开文件,返回文件描述符 88 fd = await fileAccessHelper.openFile(fileUri, fileAccess.OPENFLAGS.WRITE_READ); 89 Logger.info(this.tag, `openFile success, fd = ${fd}`) 90 } catch (err) { 91 Logger.info(this.tag, "createFile failed, err:" + JSON.stringify(err)); 92 } 93 return fd; 94 } 95 96 async getFileAssetsFromType(mediaType: number): Promise<userFileManager.FileAsset[]> { 97 Logger.info(this.tag, `getFileAssetsFromType,mediaType = ${mediaType}`); 98 let fileAssets: Array<userFileManager.FileAsset> = []; 99 100 try { 101 let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates(); 102 let fetchOptions: userFileManager.FetchOptions = { 103 fetchColumns: ['duration', 'date_added'], 104 predicates: predicates 105 } 106 let fetchFileResult: userFileManager.FetchResult<userFileManager.FileAsset> = undefined; 107 // 获取音频资源 108 if (mediaType === FileType.AUDIO) { 109 fetchFileResult = await this.mediaTest.getAudioAssets(fetchOptions); 110 fileAssets = await fetchFileResult.getAllObject(); 111 } else { 112 // 获取图片/视频资源 113 fetchFileResult = await this.mediaTest.getPhotoAssets(fetchOptions); 114 fileAssets = await fetchFileResult.getAllObject(); 115 // 过滤资源 116 fileAssets = fileAssets.filter(item => item.fileType === mediaType) 117 } 118 } catch (err) { 119 Logger.info(this.tag, `err ${JSON.stringify(err)}`); 120 } 121 Logger.info(this.tag, `getFileAssetsFromType = ${mediaType},fileAssets.count = ${fileAssets.length}`); 122 return fileAssets 123 } 124 125 async getFileAssets(context: common.UIAbilityContext): Promise<fileAccess.FileInfo[]> { 126 let isDone: boolean = false; 127 let fileInfos: Array<fileAccess.FileInfo> = []; 128 try { 129 let fileAccessHelper = fileAccess.createFileAccessHelper(context); 130 let rootIterator: fileAccess.RootIterator = await fileAccessHelper.getRoots(); 131 // 获取目录url 132 let catalogueUrl: string = rootIterator.next().value.uri; 133 let fileInfo: fileAccess.FileInfo = await fileAccessHelper.getFileInfoFromUri(catalogueUrl); 134 let fileIterator = fileInfo.scanFile(); 135 while (!isDone) { 136 let result = fileIterator.next(); 137 isDone = result.done; 138 if (!isDone) { 139 fileInfos.push(result.value); 140 } 141 } 142 } catch (error) { 143 Logger.info(this.tag, "getRoots failed, errCode:" + error.code + ", errMessage:" + error.message); 144 } 145 return fileInfos; 146 } 147 148 async getAlbums(context: common.UIAbilityContext) { 149 Logger.info(this.tag, 'getAlbums begin') 150 151 let albums = [] 152 const [ images, videos, audios, fileInfos ] = await Promise.all([ 153 this.getFileAssetsFromType(FileType.IMAGE), 154 this.getFileAssetsFromType(FileType.VIDEO), 155 this.getFileAssetsFromType(FileType.AUDIO), 156 this.getFileAssets(context) 157 ]) 158 albums.push({ 159 albumName: 'Documents', count: fileInfos.length, mediaType: FileType.FILE 160 }) 161 albums.push({ 162 albumName: 'Pictures', count: images.length, mediaType: FileType.IMAGE 163 }) 164 albums.push({ 165 albumName: 'Videos', count: videos.length, mediaType: FileType.VIDEO 166 }) 167 albums.push({ 168 albumName: 'Audios', count: audios.length, mediaType: FileType.AUDIO 169 }) 170 return albums 171 } 172 173 async deleteFile(mediaType: number, uri: string, context?: common.UIAbilityContext): Promise<void> { 174 // 删除文件资源 175 if (mediaType === 4 && context !== undefined) { 176 try { 177 let fileAccessHelper = fileAccess.createFileAccessHelper(context); 178 let code = await fileAccessHelper.delete(uri); 179 if (code != 0) 180 Logger.info(this.tag, `delete failed, code: ${code}`); 181 } catch (err) { 182 Logger.info(this.tag, `delete failed, err: ${err}`); 183 } 184 } else { 185 // 删除图片/视频/音频资源 186 return this.mediaTest.delete(uri); 187 } 188 } 189 190 getInfoFromType(mediaType: number) { 191 let result = { 192 prefix: '', suffix: '' 193 } 194 switch (mediaType) { 195 case FileType.IMAGE: 196 result.prefix = 'IMG_' 197 result.suffix = '.jpg' 198 break 199 case FileType.VIDEO: 200 result.prefix = 'VID_' 201 result.suffix = '.mp4' 202 break 203 case FileType.AUDIO: 204 result.prefix = 'AUD_' 205 result.suffix = '.mp3' 206 break 207 default: 208 result.prefix = 'FILE_' 209 result.suffix = '.txt' 210 break 211 } 212 return result 213 } 214}