1/* 2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 */ 15 16import common from '@ohos.app.ability.common'; 17import fs from '@ohos.file.fs'; // 实现应用文件访问能力 18import router from '@ohos.router'; 19import picker from '@ohos.file.picker'; 20import photoAccessHelper from '@ohos.file.photoAccessHelper'; 21import dataSharePredicates from '@ohos.data.dataSharePredicates'; 22import { BusinessError } from '@ohos.base'; 23import MediaFileUri from '../media/MediaFileUri'; 24import Logger from '../common/Logger'; 25 26const TAG = 'ViewMedia'; 27 28interface myParams extends Object { 29 uris: string[] 30} 31 32@Entry 33@Component 34struct ViewMedia { 35 @State myContext: Context = getContext(this) as common.UIAbilityContext; 36 @State myFileSizes: number[] = []; 37 @State myFileNames: string[] = []; 38 @State myFileTypes: number[] = []; 39 @StorageLink('myFileName') myFileName: string = ''; 40 @StorageLink('myFileSize') myFileSize: number = 0; 41 @State myUris: string[] = (router.getParams() as myParams).uris; 42 @State uri: string = 'Hello World'; 43 @StorageLink('showPauses') showPauses: Array<number> = []; 44 mediaFileUri: MediaFileUri = new MediaFileUri(); 45 scroller: Scroller = new Scroller(); 46 currentUri: string = ''; 47 controllers: Array<VideoController> = []; 48 49 /** 50 * 拉起picker保存图片/视频 51 */ 52 async callFilePickerSaveImageVideo(): Promise<void> { 53 try { 54 let PhotoSaveOptions = new picker.PhotoSaveOptions(); 55 PhotoSaveOptions.newFileNames = ['PhotoViewPicker01.jpg', 'PhotoViewPicker01.mp4']; 56 let photoPicker = new picker.PhotoViewPicker(); 57 photoPicker.save(PhotoSaveOptions).then((PhotoSaveResult) => { 58 Logger.info(TAG, 'PhotoViewPicker.save successfully, PhotoSaveResult uri: ' + JSON.stringify(PhotoSaveResult)); 59 if (PhotoSaveResult !== null && PhotoSaveResult !== undefined) { 60 PhotoSaveResult.forEach((value: string) => { 61 this.uri = value; 62 Logger.info(TAG, `save image/video uri: ${this.uri}`); 63 }) 64 } 65 }).catch((err: BusinessError) => { 66 Logger.error(TAG, 'PhotoViewPicker.save failed with err: ' + JSON.stringify(err)); 67 }); 68 } catch (err) { 69 Logger.error(TAG, 'PhotoViewPicker failed with err: ' + err); 70 } 71 } 72 73 onPageShow() { 74 this.getImagesInfo(); 75 this.myFileName = this.myFileNames[0]; 76 this.myFileSize = this.myFileSizes[0]; 77 78 Logger.info(TAG, 'onPageShow getFilenameByUriForMedia this.myFileName ' + this.myFileName); 79 Logger.info(TAG, 'onPageShow getFilenameByUriForMedia begin' + this.myFileSize); 80 81 AppStorage.SetOrCreate('myFileName', this.myFileName); 82 AppStorage.SetOrCreate('myFileSize', this.myFileSize); 83 } 84 85 getMediaNameByUri(myUri: string, index: number) { 86 Logger.info(TAG, 'getMediaNameByUri getFilenameByUriForMedia begin'); 87 // 创建文件获取选项,此处参数为获取image类型的文件资源 88 let predicates: dataSharePredicates.DataSharePredicates = new dataSharePredicates.DataSharePredicates(); 89 let fetchOptions: photoAccessHelper.FetchOptions = { 90 fetchColumns: [], 91 predicates: predicates.equalTo('uri', myUri) 92 }; 93 let media =photoAccessHelper.getPhotoAccessHelper(getContext(this)); 94 // 获取文件资源,使用callback方式返回异步结果 95 media.getAssets(fetchOptions, async (error, fetchFileResult) => { 96 // 判断获取的文件资源的检索结果集是否为undefined,若为undefined则接口调用失败 97 Logger.info(TAG, 'getFilenameByUriForMedia getMediaLibrary is ok'); 98 99 if (fetchFileResult === undefined) { 100 Logger.error(TAG, 'get fetchFileResult failed with error: ' + error); 101 return; 102 } 103 // 获取文件检索结果集中的总数 104 const count = fetchFileResult.getCount(); 105 Logger.info(TAG, 'getFilenameByUriForMedia count is: ' + count); 106 107 // 判断结果集中的数量是否小于0,小于0时表示接口调用失败 108 if (count < 0) { 109 Logger.error(TAG, 'get count from fetchFileResult failed, count: ' + count); 110 return; 111 } 112 // 判断结果集中的数量是否等于0,等于0时表示接口调用成功,但是检索结果集为空,请检查文件获取选项参数配置是否有误和设备中是否存在相应文件 113 if (count === 0) { 114 Logger.info(TAG, 'The count of fetchFileResult is zero'); 115 return; 116 } 117 Logger.info(TAG, 'Get fetchFileResult successfully, count: ' + count); 118 // 获取文件检索结果集中的第一个资源,使用callback方式返回异步结果,文件数量较多时请使用getAllObject接口 119 fetchFileResult.getFirstObject(async (error, fileAsset) => { 120 // 检查获取的第一个资源是否为undefined,若为undefined则接口调用失败 121 if (fileAsset === undefined) { 122 Logger.error(TAG, 'get first object failed with error: ' + error); 123 return; 124 } 125 Logger.info(TAG, 'fileAsset.displayName ' + '0 : ' + fileAsset.displayName); 126 Logger.info(TAG, 'fileAsset.uri 0:' + fileAsset.uri); 127 Logger.info(TAG, 'myUri: ' + myUri); 128 129 this.myFileTypes[index] = fileAsset.photoType; 130 this.myFileName = fileAsset.displayName; 131 this.myFileNames[index] = this.myFileName; 132 133 134 AppStorage.SetOrCreate('myFileName', this.myFileName); 135 AppStorage.SetOrCreate('myFileTypes', this.myFileTypes); 136 137 if (this.myFileTypes[index] === photoAccessHelper.PhotoType.VIDEO) { 138 Logger.info(TAG, 'getMediaNameByUri set showPauses for VIDEO'); 139 this.showPauses[index] = 1; 140 } 141 142 Logger.info(TAG, 'getFilenameByUriForMedia getImagesInfo this.myFileName ' + this.myFileName); 143 Logger.info(TAG, 'getFilenameByUriForMedia getImagesInfo index ' + index); 144 Logger.info(TAG, 'getFilenameByUriForMedia getImagesInfo this.myFileTypes[index] ' + this.myFileTypes[index]); 145 Logger.info(TAG, 'getFilenameByUriForMedia getImagesInfo this.myFileNames[index] ' + this.myFileNames[index]); 146 fetchFileResult.close(); 147 }); 148 }); 149 } 150 151 getImagesInfo() { 152 for (let index = 0; index < this.myUris.length; index++) { 153 Logger.info(TAG, 'getFilenameByUriForMedia getImagesInfo index: ' + index); 154 this.controllers[index] = new VideoController(); 155 this.getMediaNameByUri(this.myUris[index], index); 156 this.myFileSizes[index] = this.mediaFileUri.myGetFileSize(this.myUris[index], fs.OpenMode.READ_ONLY); 157 Logger.info(TAG, 'getFilenameByUriForMedia getVideosInfo this.myFileNames[index]: ' + this.myFileNames[index] + ' index ' + index); 158 Logger.info(TAG, 'getFilenameByUriForMedia getVideosInfo this.myFileSizes[index]' + this.myFileSizes[index]); 159 Logger.info(TAG, 'getFilenameByUriForMedia getVideosInfo this.myFileTypes[index] cc' + this.myFileTypes[index]); 160 } 161 } 162 163 build() { 164 Column() { 165 // 顶部的行容器 166 Row() { 167 // 后退箭头 168 Row() { 169 Image($r('app.media.ic_back')) 170 .focusable(true) 171 .focusOnTouch(true) 172 .width(25) 173 .height(25) 174 .align(Alignment.Start) 175 .id('back2Index') 176 .onClick(() => { 177 router.back(); 178 }) 179 } 180 .width('12.8%') 181 .padding({ left: '7.2%' }) 182 183 // 文件名及信息 184 Column() { 185 Row() { 186 Text(this.myFileName) 187 .focusable(true) 188 .focusOnTouch(true) 189 .fontSize(20) 190 .fontFamily('HarmonyHeiTi-Bold') 191 .fontColor('#182431') 192 .textAlign(TextAlign.Start) 193 .fontWeight(700) 194 .lineHeight(28) 195 .maxLines(1) 196 .textOverflow({ overflow: TextOverflow.Ellipsis }) 197 } 198 .width('100%') 199 .align(Alignment.Start) 200 .margin({ top: '0.4%', bottom: '0.3%' }) 201 202 Row() { 203 Text('size: ' + JSON.stringify(this.myFileSize) + 'B') 204 .focusable(true) 205 .focusOnTouch(true) 206 .opacity(0.6) 207 .fontFamily('HarmonyHeiTi') 208 .fontSize(14) 209 .fontColor('#182431') 210 .textAlign(TextAlign.Start) 211 .lineHeight(19) 212 .fontWeight(400) 213 } 214 .width('100%') 215 .margin({ top: '0.3%', bottom: '0.5%' }) 216 .align(Alignment.Start) 217 } 218 .width('45%') 219 .margin({ left: '5%' }) 220 221 // 右边一个图标,另存为 222 Row() { 223 Image($r('app.media.ic_saveas')) 224 .focusable(true) 225 .focusOnTouch(true) 226 .width(25) 227 .height(25) 228 .visibility(Visibility.Hidden) 229 } 230 .height('100%') 231 .width('37.2%') 232 .padding({ right: '7.2%' }) 233 .justifyContent(FlexAlign.End) 234 } 235 .height('7.4%') 236 .width('100%') 237 238 Scroll(this.scroller) { 239 // 显示媒体文件的容器 240 Column() { 241 List({ space: 20, initialIndex: 0 }) { 242 ForEach(this.myUris, (uri: string, index?: number) => { 243 ListItem() { 244 Column() { 245 Image(uri) 246 .borderRadius(24) 247 .visibility(index !== undefined && this.myFileTypes[index] === photoAccessHelper.PhotoType.IMAGE ? Visibility.Visible : Visibility.Hidden) 248 .onClick(() => { 249 if (index !== undefined) { 250 this.myFileSize = this.myFileSizes[index]; 251 this.myFileName = this.myFileNames[index]; 252 } 253 AppStorage.SetOrCreate('myFileName', this.myFileName); 254 AppStorage.SetOrCreate('myFileSize', this.myFileSize); 255 Logger.info(TAG, 'Image onClick myFileName is ' + this.myFileName); 256 Logger.info(TAG, 'Image onClick myFileName is ' + this.myFileSize); 257 }) 258 if (index !== undefined) { 259 Stack({ alignContent: Alignment.Center }) { 260 Video({ 261 src: uri, 262 controller: this.controllers[index] 263 }) 264 .autoPlay(false) 265 .controls(true) 266 .borderRadius(24) 267 .visibility(this.myFileTypes[index] === photoAccessHelper.PhotoType.VIDEO ? Visibility.Visible : Visibility.Hidden) 268 269 Image($r('app.media.ic_PAUSE')) 270 .width(25) 271 .height(25) 272 .onClick(() => { 273 this.controllers[index].start(); 274 this.showPauses[index] = 0; 275 }) 276 .visibility(this.showPauses[index] === 0 ? Visibility.Hidden : Visibility.Visible) 277 } 278 .onClick(() => { 279 this.myFileSize = this.myFileSizes[index]; 280 this.myFileName = this.myFileNames[index]; 281 282 AppStorage.SetOrCreate('myFileName', this.myFileName); 283 AppStorage.SetOrCreate('myFileSize', this.myFileSize); 284 }) 285 } 286 } 287 .height('100%') 288 } 289 .height('25%') 290 }, (item: string) => item) 291 } 292 .id('picScroller') 293 .scrollBar(BarState.Auto) 294 } 295 } 296 .padding({ top: '1.5%', left: '6.7%', right: '6.7%' }) 297 } 298 .backgroundColor('#f1f3f5') 299 .height('100%') 300 } 301} 302