• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}