鸿蒙应用框架开发【选择并查看文档与媒体文件】 本地数据与文件

选择并查看文档与媒体文件

介绍

应用使用@ohos.file.picker、@ohos.file.fs等接口,实现了picker拉起文档编辑保存、拉起系统相册图片查看、拉起视频并播放的功能。

效果预览

1

使用说明:

  1. 在首页,应用显示查看最近打开文件功能的跳转按钮,点击后进入文件管理页面,可以通过最近页面,查看最近打开的文件。通过点击右上方的三个按钮,可以分别实现新建文档、选择图片或视频并打开预览、选择文档并打开的功能。
  2. 在查看文档界面,点击右上方左一按钮,可以实现当前文档另存为的功能;点击右上方中间的按钮,开启文档的编辑功能,textArea变成可编辑状态,用户输入数据后点击右上方第三个按钮,可以将当前文档内容进行保存操作(系统文档没有保存权限)。
  3. 在查看图片界面,picker拉起系统相册的图片,用户至多可选择三张图片查看,点击图片可以切换所显示的图片名及大小信息。
  4. 在查看视频界面,picker拉起系统相册的视频,用户至多可选择三个视频查看,点击视频播放并且可以显示的视频名及大小信息。

具体实现

  • 拉起picker选择文件、拉起picker保存文件、拉起picker选择图片或视频的功能封装在Index.ets,源码参考:[Index.ets]
/** Copyright (c) 2024 Huawei Device Co., Ltd.* Licensed under the Apache License, Version 2.0 (the 'License');* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an 'AS IS' BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/import { router } from '@kit.ArkUI';
import { picker } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
import Logger from '../common/Logger';
import MediaFileUri from '../media/MediaFileUri';
import { Constants } from '../common/Constants';const MAX_SELECT_NUM = 3; // 选择媒体文件的最大数目
const TAG = 'pickerIndex';@Entry
@Component
struct Index {@State uri: string = 'Hello World';@State filename: string = '';@State sizeFile: number = 0;@State log: string = '';@State imageFlagCur: number = 0;@StorageLink('fileSizeList') fileSizeList: Array<number> = [];@StorageLink('fileNameList') fileNameList: Array<string> = [];@StorageLink('fileUriList') fileUriList: Array<string> = [];@StorageLink('imageNames') imageNames: Array<string> = [];mediaFileUri: MediaFileUri = new MediaFileUri();scroller: Scroller = new Scroller();authorizeBundleName: string = 'com.open.file.uri.demo';// 拉起picker选择文件async callFilePickerSelectFile(): Promise<void> {try {let DocumentSelectOptions = new picker.DocumentSelectOptions();let documentPicker = new picker.DocumentViewPicker();documentPicker.select(DocumentSelectOptions).then((DocumentSelectResult) => {Logger.info(TAG,'DocumentViewPicker.select successfully, DocumentSelectResult uri: ' + JSON.stringify(DocumentSelectResult));let editFlag = false;if (DocumentSelectResult !== null && DocumentSelectResult !== undefined) {DocumentSelectResult.forEach((value) => {this.uri = value;editFlag = true;Logger.info(TAG, `select file uri: ${this.uri}`);})}if (editFlag) {this.getFilenameByUri(this.uri);}}).catch((err: BusinessError) => {Logger.error(TAG, 'DocumentViewPicker.select failed with err: ' + JSON.stringify(err));});} catch (err) {Logger.error(TAG, 'DocumentViewPicker failed with err: ' + JSON.stringify(err));}}// 拉起picker保存文件async callFilePickerSaveFile(): Promise<void> {try {let DocumentSaveOptions = new picker.DocumentSaveOptions();DocumentSaveOptions.newFileNames = ['MyDocument_01.txt'];let documentPicker = new picker.DocumentViewPicker();documentPicker.save(DocumentSaveOptions).then((DocumentSaveResult) => {Logger.info(TAG,'DocumentViewPicker.save successfully, DocumentSaveResult uri: ' + JSON.stringify(DocumentSaveResult));if (DocumentSaveResult !== null && DocumentSaveResult !== undefined) {this.uri = DocumentSaveResult[0];Logger.info(TAG, `save file uri: ${this.uri}`);}this.getFilenameByUri(this.uri);}).catch((err: BusinessError) => {Logger.error(TAG, 'DocumentViewPicker.save failed with err: ' + JSON.stringify(err));});} catch (err) {Logger.error(TAG, 'DocumentViewPicker failed with err: ' + err);}}async getFilenameByUriForMedia(myUris: string[]) {router.pushUrl({url: 'pages/ViewMedia',params: {uris: myUris}}, router.RouterMode.Standard);}async getFilenameByUri(myUri: string): Promise<void> {// 获取文件名称this.filename = (myUri.split('/').pop()) as string;router.pushUrl({url: 'pages/EditFile',params: {fileName: this.filename,myUri: myUri}}, router.RouterMode.Standard);}// 拉起picker选择图片/视频async callFilePickerSelectImage(): Promise<void> {let array: string[];try {// 设置photoPicker的参数let PhotoSelectOptions = new picker.PhotoSelectOptions();// 过滤选择媒体文件类型PhotoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE;// 选择媒体文件的最大数目PhotoSelectOptions.maxSelectNumber = MAX_SELECT_NUM;let mediaFlag = false;// 使用图库选择器对象前,需要先创建PhotoViewPicker实例let photoPicker = new picker.PhotoViewPicker();photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult) => {// 日志中记录成功信息Logger.info(TAG,'PhotoViewPicker.select successfully, PhotoSelectResult uri: ' + JSON.stringify(PhotoSelectResult));// 接口采用callback异步返回形式,返回PhotoSelectResult对象,故进行下一步操作前要先判断是否已经成功返回PhotoSelectResult对象了if (PhotoSelectResult !== null && PhotoSelectResult !== undefined) {// PhotoSelectResult为返回的结果集。// 其中包含Array<string>类型的photoUris,为返回图库选择后的媒体文件的uri数组;还包含boolean类型的isOriginalPhoto,指示返回图库选择后的媒体文件是否为原图。// 声明变量array,其取值为PhotoSelectResult中的数组。array = PhotoSelectResult['photoUris'];array.forEach((value) => {this.uri = value;mediaFlag = true;Logger.info(TAG, `select image/video uri: ${this.uri}`);})}if (mediaFlag) {this.getFilenameByUriForMedia(array);}}).catch((err: BusinessError) => {Logger.error(TAG, 'PhotoViewPicker.select failed with err: ' + JSON.stringify(err));});} catch (err) {Logger.error(TAG, 'PhotoViewPicker failed with err: ' + err);}}aboutToDisappear(): void {this.fileNameList = [];this.fileSizeList = [];this.fileUriList = [];}onPageShow(): void {this.mediaFileUri.getAllFiles();}build() {Scroll(this.scroller) {Row() {Column() {Row() {Column() {Text($r('app.string.last_open')).fontFamily('HarmonyHeiTi-Bold').fontSize($r('app.float.text_font_size_30')).fontWeight(Constants.TEXT_FONT_WIGHT).textAlign(TextAlign.Start).fontColor($r('app.color.text_font_color')).lineHeight($r('app.float.first_line_height')).width(Constants.SEVENTY_PERCENT).height($r('app.float.first_line_height'))}.width(Constants.FIFTY_PERCENT).margin({ left: Constants.PADDING_LEFT_RIGHT }).alignItems(HorizontalAlign.Start)Row() {Image($r('app.media.ic_saveas')).width($r('app.float.image_size')).height($r('app.float.image_size')).margin({ right: Constants.IMAGE_MARGIN_RIGHT }).id('newFile').onClick(() => {this.callFilePickerSaveFile();})Image($r('app.media.ic_picture')).width($r('app.float.image_size')).height($r('app.float.image_size')).id('picture').margin({ right: Constants.IMAGE_MARGIN_RIGHT }).onClick(() => {this.callFilePickerSelectImage();})Image($r('app.media.ic_folder')).width($r('app.float.image_size')).height($r('app.float.image_size')).id('folder').opacity(1).margin({ right: Constants.MARGIN_RIGHT }).onClick(() => {this.callFilePickerSelectFile();})}.justifyContent(FlexAlign.End).padding({ right: Constants.PADDING_RIGHT }).width(Constants.FIFTY_PERCENT)}// 第一行结束.width(Constants.FULL_PERCENT).height($r('app.float.first_line_height')).margin({top: $r('app.float.first_line_margin_top'),left: $r('app.float.first_line_margin_left'),right: $r('app.float.first_line_margin_right'),bottom: $r('app.float.first_line_margin_bottom')})Row() {Text($r('app.string.view_last_open')).fontSize($r('app.float.text_area_font_size')).textAlign(TextAlign.Start).lineHeight($r('app.float.line_height')).margin({ left: $r('app.float.image_margin_left') })Blank()Image($r('app.media.right_arrow')).height($r('app.float.text_height_19')).width($r('app.float.image_width')).margin({left: $r('app.float.image_margin_left'),right: $r('app.float.image_margin_left'),top: $r('app.float.image_margin_top'),bottom: $r('app.float.image_margin_top')})}.backgroundColor($r('app.color.start_window_background')).width(Constants.FULL_PERCENT).height($r('app.float.row_height')).padding({top: $r('app.float.row_padding'),left: $r('app.float.margin_padding_12'),right: $r('app.float.margin_padding_12')}).onClick(() => {this.callFilePickerSelectFile();})Column() {List({ space: Constants.LIST_SPACE, initialIndex: 0 }) {ForEach(this.fileNameList, (item: string, index?: number) => {ListItem() {Row() {Image($r('app.media.ic_docs')).width(Constants.IMAGE_WIDTH).height($r('app.float.line_height')).margin({left: $r('app.float.margin_left'),right: $r('app.float.margin_right')})Text(item).fontSize($r('app.float.text_area_font_size')).fontFamily('HarmonyHeiTi-Medium').fontColor($r('app.color.text_font_color')).lineHeight($r('app.float.line_height')).textAlign(TextAlign.Start).margin({ right: $r('app.float.padding_left_right') }).width(Constants.SIXTY_FOUR_PERCENT)if (index !== undefined) {Text('Size: ' + JSON.stringify(this.fileSizeList[index]) + 'B').fontSize($r('app.float.text_font_size_14')).fontFamily('HarmonyHeiTi-Medium').lineHeight($r('app.float.text_height_19')).fontColor($r('app.color.text_font_color')).textAlign(TextAlign.End).opacity(Constants.TEXT_OPACITY).width(Constants.TEXT_WIDTH).margin({ right: $r('app.float.margin_padding_12') })}}.id('fileItem' + (index !== undefined ? index : "")).borderRadius(Constants.BORDER_RADIUS).width(Constants.FULL_PERCENT).height($r('app.float.row_height_64')).padding({ right: $r('app.float.margin_padding_12') }).backgroundColor($r('app.color.start_window_background'))}.onClick(() => {Logger.info(TAG, 'fileAsset.displayName fileName item: ' + item);if (index !== undefined) {router.pushUrl({url: 'pages/EditFile',params: {fileName: item,myUri: this.fileUriList[index]}}, router.RouterMode.Standard);}})}, (item: string) => item)}.listDirection(Axis.Vertical) // 排列方向.id('indexList').edgeEffect(EdgeEffect.Spring) // 滑动到边缘无效果.scrollBar(BarState.Auto).alignListItem(ListItemAlign.Center).margin({top: Constants.LIST_MARGIN_TOP,left: $r('app.float.margin_padding_12'),right: $r('app.float.margin_padding_12')})}.height(Constants.FULL_PERCENT).width(Constants.FULL_PERCENT)}.alignItems(HorizontalAlign.Center).width(Constants.FULL_PERCENT).height(Constants.FULL_PERCENT).backgroundColor($r('app.color.common_background'))}.height(Constants.FULL_PERCENT)}}
}
  • 使用new picker.DocumentViewPicker来创建文件picker实例,使用documentPicker.select来拉起picker选择文件,使用documentPicker.save来拉起picker保存文件,接口参考:@ohos.file.picker

  • 使用new picker.PhotoViewPicker来创建图库picker实例,使用photoPicker.select来拉起picker选择图片或视频,接口参考:@ohos.file.picker

  • 编辑文件并保存的功能封装在EditFile.ets,源码参考:[EditFile.ets]

/** Copyright (c) 2024 Huawei Device Co., Ltd.* Licensed under the Apache License, Version 2.0 (the 'License');* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an 'AS IS' BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/import { promptAction, router } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';
import { fileIo, picker } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
import MediaFileUri from '../media/MediaFileUri';
import Logger from '../common/Logger';
import { terminateSelf } from '../utils/utils';
import { Constants } from '../common/Constants';const TAG = 'EditFile: ';
let storage = LocalStorage.getShared();
const OPACITY_VALUE = 0.6; // 透明度interface myParams extends Object {myUri: string,fileName: string
};@Entry(storage)
@Component
struct EditFile {@LocalStorageLink('loadFlag') loadFlag: Boolean = false;@LocalStorageLink('loadFileSize') loadFileSize: number = 0;@LocalStorageLink('loadFileName') loadFileName: string = '';@LocalStorageLink('loadFileContent') loadFileContent: string = '';@LocalStorageLink('loadUri') loadUri: string = '';@LocalStorageLink('fd') loadFd: number = 0;@StorageLink('editable') editable: Boolean = false;@StorageLink('myFileSize') myFileSize: number = 0;@StorageLink('myFileContent') myFileContent: string = '';@State myContext: Context = getContext(this) as common.UIAbilityContext;@State myUri: string = '';@State opacityValue: number = OPACITY_VALUE;@State uriSave: string = '';@State myFileName: string = '';public fileContentFlag: boolean = false;newFileContent: string = '';scroller: Scroller = new Scroller();controller: TextAreaController = new TextAreaController();mediaFileUri: MediaFileUri = new MediaFileUri();getFileInfo(): void {if (this.loadFlag) {this.myFileName = this.loadFileName;this.myFileContent = this.loadFileContent;this.myFileSize = this.loadFileSize;this.myUri = this.loadUri;Logger.info(TAG, 'The count of getFileInfo is myFileContent ' + this.myFileContent);} else {this.myUri = (router.getParams() as myParams).myUri;this.myFileName = (router.getParams() as myParams).fileName;this.myFileContent = this.mediaFileUri.readFileContent(this.myUri);this.myFileSize = this.mediaFileUri.myGetFileSize(this.myUri, fileIo.OpenMode.READ_ONLY);Logger.info(TAG, 'The count of getFileInfo is myFileName is: ' + this.myFileName);Logger.info(TAG, 'The count of getFileInfo is myFileContent ' + this.myFileContent);Logger.info(TAG, 'The count of getFileInfo is myFileSize ' + this.myFileSize);}AppStorage.setOrCreate('myFileContent', this.myFileContent);AppStorage.setOrCreate('myFileSize', this.myFileSize);}async writeContentForSaveAsFile(myUri: string, wrFlag: Boolean = false): Promise<void> {if (wrFlag) {Logger.info(TAG, 'fileAsset.displayName wrFlag is true');Logger.info(TAG, 'fileAsset.displayName wrFlag myFileContent :' + this.myFileContent);this.mediaFileUri.writeFileContent(myUri, this.myFileContent);}}// 拉起picker保存文件async callFilePickerSaveFile(): Promise<void> {try {let DocumentSaveOptions = new picker.DocumentSaveOptions();DocumentSaveOptions.newFileNames = ['MyDocument_01.txt'];let documentPicker = new picker.DocumentViewPicker();documentPicker.save(DocumentSaveOptions).then((DocumentSaveResult) => {Logger.info(TAG,'DocumentViewPicker.save successfully, DocumentSaveResult uri: ' + JSON.stringify(DocumentSaveResult));if (DocumentSaveResult !== null && DocumentSaveResult !== undefined) {this.uriSave = DocumentSaveResult[0];Logger.info(TAG, `save callFilePickerSaveFile file this.uriSave: ${this.uriSave}`);}Logger.info(TAG, 'fileAsset.displayName wrFlag myFileContent :' + this.myFileContent);// 用 medialibrary 重新获取uri,进行写入操作this.writeContentForSaveAsFile(this.uriSave, true);}).catch((err: BusinessError) => {Logger.error(TAG, 'DocumentViewPicker.save failed with err: ' + JSON.stringify(err));});} catch (err) {Logger.error(TAG, 'DocumentViewPicker failed with err: ' + err);}}onPageShow(): void {this.getFileInfo();this.editable = false;}build() {Column() {// 顶部的行容器Row() {// 后退箭头Row() {Image($r('app.media.ic_back')).focusable(true).focusOnTouch(true).id('backIndex').width($r('app.float.image_size')).height($r('app.float.image_size')).align(Alignment.Start).onClick(() => {if (this.loadFlag) {Logger.info(TAG, 'end page');let context = getContext(this);terminateSelf(context);} else {router.back();}})}.margin({ left: Constants.MARGIN_LEFT })// 文件名及信息Column() {Row() {Text(this.myFileName).focusable(true).focusOnTouch(true).fontSize($r('app.float.text_font_size')).fontFamily('HarmonyHeiTi-Bold').fontColor($r('app.color.text_font_color')).textAlign(TextAlign.Start).fontWeight(Constants.TEXT_FONT_WIGHT).lineHeight(Constants.TEXT_LINE_HEIGHT).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })}.width(Constants.FULL_PERCENT).align(Alignment.Start).margin({left: Constants.MARGIN_LEFT,top: Constants.MARGIN_TOP,bottom: Constants.MARGIN_ZERO_POINT_THREE_PERCENT})Row() {Text('size: ' + JSON.stringify(this.myFileSize) + 'B').focusable(true).focusOnTouch(true).opacity(Constants.TEXT_OPACITY).fontFamily('HarmonyHeiTi').fontSize($r('app.float.text_font_size_14')).fontColor($r('app.color.text_font_color')).textAlign(TextAlign.Start).lineHeight(Constants.TEXT_LINE_HEIGHT_19).fontWeight(Constants.TEXT_FONT_WIGHT_400)}.width(Constants.FULL_PERCENT).margin({left: Constants.MARGIN_LEFT,top: Constants.MARGIN_ZERO_POINT_THREE_PERCENT,bottom: Constants.MARGIN_ZERO_POINT_FIVE_PERCENT}).align(Alignment.Start)}.width(Constants.FORTY_FIVE_PERCENT).margin({ left: Constants.MARGIN_LEFT })// 右边三个图标Row() {Image($r('app.media.ic_saveas')).focusable(true).focusOnTouch(true).width($r('app.float.image_size')).height($r('app.float.image_size')).id('saveAs').margin({ right: Constants.IMAGE_MARGIN_RIGHT }).onClick(() => {this.callFilePickerSaveFile();}).visibility(this.loadFlag ? Visibility.Hidden : Visibility.Visible)Image($r('app.media.ic_writting')).focusable(true).focusOnTouch(true).width($r('app.float.image_size')).height($r('app.float.image_size')).id('editable').margin({ right: Constants.IMAGE_MARGIN_RIGHT }).onClick(() => {this.editable = true;AppStorage.setOrCreate('editable', this.editable);Logger.info(TAG, 'EditFile caretPosition length = ' + this.myFileContent.length);this.controller.caretPosition(this.myFileContent.length);promptAction.showToast({ message: $r('app.string.editable') });})Image($r('app.media.ic_save')).focusable(true).focusOnTouch(true).width($r('app.float.image_size')).height($r('app.float.image_size')).id('save').margin({ right: Constants.MARGIN_LEFT }).onClick(() => {if (this.fileContentFlag) {let flage: boolean = true;this.myFileContent = this.newFileContent;AppStorage.setOrCreate('myFileContent', this.myFileContent);Logger.info(TAG, 'save onClick myFileContent is: ' + this.myFileContent);Logger.info(TAG, 'save onClick this.loadUri: ' + this.loadUri);if (this.loadFlag) {let file = fileIo.openSync(this.loadUri,fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.TRUNC);Logger.info(TAG, 'save onClick file.fd is: ' + file.fd);fileIo.write(file.fd, this.myFileContent).then((writeLen) => {Logger.info(TAG, 'write data to file succeed and size is:' + writeLen);this.myFileSize = fileIo.statSync(file.fd).size;AppStorage.setOrCreate('myFileSize', this.myFileSize);Logger.info(TAG, 'save onClick this.myFileSize ' + this.myFileSize);}).catch((err: BusinessError) => {Logger.info(TAG, 'write data to file failed with error:' + JSON.stringify(err));});fileIo.closeSync(file);} else {try {let file = fileIo.openSync(this.myUri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.TRUNC);let writeLen = fileIo.writeSync(file.fd, this.myFileContent);this.myFileSize = fileIo.statSync(file.fd).size;AppStorage.setOrCreate('myFileSize', this.myFileSize);Logger.info(TAG, 'write data to file succeed and size is:' + writeLen);fileIo.closeSync(file);} catch (err) {flage = false;Logger.info(`save data to file failed with error:${JSON.stringify(err)}: ${JSON.stringify(err?.message)}`);promptAction.showToast({message: Constants.SHOW_TOAST_MESSAGE,duration: 6500})}}if (flage) {this.editable = false;AppStorage.setOrCreate('editable', this.editable);promptAction.showToast({ message: $r('app.string.saved') });}}})}.height(Constants.FIFTY_PERCENT).width(Constants.THIRTY_SEVEN_POINT_TWO).padding({ right: Constants.MARGIN_ZERO_POINT_FIVE_PERCENT }).justifyContent(FlexAlign.End)}.height(Constants.SEVEN_POINT_FOUR).width(Constants.FULL_PERCENT)Scroll(this.scroller) {// TextArea的行容器Row() {TextArea({text: this.newFileContent ? this.newFileContent : this.myFileContent,placeholder: Constants.TEXT_AREA_PLACEHOLDER,controller: this.controller}).id('textArea').fontSize($r('app.float.text_area_font_size')).fontColor($r('app.color.text_font_color')).opacity(this.opacityValue).fontWeight(Constants.TEXT_FONT_WIGHT_400).align(Alignment.TopStart).textAlign(TextAlign.Start).backgroundColor($r('app.color.common_background')).fontFamily('HarmonyHeiTi').padding({top: $r('app.float.padding_top_bottom'),right: $r('app.float.padding_left_right'),left: $r('app.float.padding_left_right'),bottom: $r('app.float.padding_top_bottom')}).focusable(this.editable ? true : false).focusOnTouch(true).defaultFocus(false).onFocus(() => {this.opacityValue = 1;}).onBlur(() => {this.opacityValue = OPACITY_VALUE;}).onChange((value: string) => {this.newFileContent = value;this.fileContentFlag = true;})}.padding({top: Constants.PADDING_TOP,left: Constants.PADDING_LEFT_RIGHT,right: Constants.PADDING_LEFT_RIGHT})}}.backgroundColor($r('app.color.common_background')).height(Constants.FULL_PERCENT)}
}
  • 使用fs.openSync、fs.writeSync、fs.readSync、fs.closeSync分别用来打开文件、写文件、读文件、关闭文件,接口参考:@ohos.file.fs

  • 拉起图片或视频并查看的功能封装在ViewMedia.ets,源码参考:[ViewMedia.ets]

/** Copyright (c) 2024 Huawei Device Co., Ltd.* Licensed under the Apache License, Version 2.0 (the 'License');* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**     http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an 'AS IS' BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/import { router } from '@kit.ArkUI';
import { common } from '@kit.AbilityKit';
import { fileIo, picker } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
import MediaFileUri from '../media/MediaFileUri';
import Logger from '../common/Logger';
import { Constants } from '../common/Constants';const TAG = 'ViewMedia';interface myParams extends Object {uris: string[]
};@Entry
@Component
struct ViewMedia {@State myContext: Context = getContext(this) as common.UIAbilityContext;@State myFileSizes: number[] = [];@State myFileNames: string[] = [];@State myFileTypes: number[] = [];@StorageLink('myFileName') myFileName: string = '';@StorageLink('myFileSize') myFileSize: number = 0;@State myUris: string[] = (router.getParams() as myParams).uris;@State uri: string = 'Hello World';@StorageLink('showPauses') showPauses: Array<number> = [];mediaFileUri: MediaFileUri = new MediaFileUri();scroller: Scroller = new Scroller();currentUri: string = '';controllers: Array<VideoController> = [];// 拉起picker保存图片/视频async callFilePickerSaveImageVideo(): Promise<void> {try {let PhotoSaveOptions = new picker.PhotoSaveOptions();PhotoSaveOptions.newFileNames = ['PhotoViewPicker01.jpg', 'PhotoViewPicker01.mp4'];let photoPicker = new picker.PhotoViewPicker();photoPicker.save(PhotoSaveOptions).then((PhotoSaveResult) => {Logger.info(TAG, 'PhotoViewPicker.save successfully, PhotoSaveResult uri: ' + JSON.stringify(PhotoSaveResult));if (PhotoSaveResult !== null && PhotoSaveResult !== undefined) {PhotoSaveResult.forEach((value: string) => {this.uri = valueLogger.info(TAG, `save image/video uri: ${this.uri}`);})}}).catch((err: BusinessError) => {Logger.error(TAG, 'PhotoViewPicker.save failed with err: ' + JSON.stringify(err));});} catch (err) {Logger.error(TAG, 'PhotoViewPicker failed with err: ' + err);}}onPageShow() {this.getImagesInfo();this.myFileName = this.myFileNames[0];this.myFileSize = this.myFileSizes[0];Logger.info(TAG, 'onPageShow getFilenameByUriForMedia this.myFileName ' + this.myFileName);Logger.info(TAG, 'onPageShow getFilenameByUriForMedia begin ' + this.myFileSize);AppStorage.setOrCreate('myFileName', this.myFileName);AppStorage.setOrCreate('myFileSize', this.myFileSize);}async getMediaNameByUri(myUri: string, index: number) {Logger.info(TAG, 'getMediaNameByUri getFilenameByUriForMedia begin');this.myFileName = (myUri.split('/').pop()) as string;this.myFileNames[index] = this.myFileName;}getImagesInfo() {for (let index = 0; index < this.myUris.length; index++) {Logger.info(TAG, 'getFilenameByUriForMedia  getImagesInfo  index: ' + index);this.controllers[index] = new VideoController();this.getMediaNameByUri(this.myUris[index], index);this.myFileSizes[index] = this.mediaFileUri.myGetFileSize(this.myUris[index], fileIo.OpenMode.READ_ONLY);Logger.info(TAG, 'getFilenameByUriForMedia  getVideosInfo  this.myFileNames[index]: '+ this.myFileNames[index] + ' index ' + index);Logger.info(TAG, 'getFilenameByUriForMedia getVideosInfo this.myFileSizes[index]' + this.myFileSizes[index]);Logger.info(TAG, 'getFilenameByUriForMedia getVideosInfo this.myFileTypes[index] cc' + this.myFileTypes[index]);}}build() {Column() {// 顶部的行容器Row() {// 后退箭头Row() {Image($r('app.media.ic_back')).focusable(true).focusOnTouch(true).width($r('app.float.image_size')).height($r('app.float.image_size')).align(Alignment.Start).id('back2Index').onClick(() => {router.back();})}.width(Constants.BACK_WIDTH).padding({ left: Constants.BACK_PADDING_LEFT })// 文件名及信息Column() {Row() {Text(this.myFileName).focusable(true).focusOnTouch(true).fontSize($r('app.float.text_font_size')).fontFamily('HarmonyHeiTi-Bold').fontColor($r('app.color.text_font_color')).textAlign(TextAlign.Start).fontWeight(Constants.TEXT_FONT_WIGHT).lineHeight($r('app.float.text_height')).maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })}.width(Constants.FULL_PERCENT).align(Alignment.Start).margin({top: Constants.MARGIN_TOP,bottom: Constants.MARGIN_ZERO_POINT_THREE_PERCENT})Row() {Text('size: ' + JSON.stringify(this.myFileSize) + 'B').focusable(true).focusOnTouch(true).opacity(Constants.TEXT_OPACITY).fontFamily('HarmonyHeiTi').fontSize($r('app.float.text_font_size_14')).fontColor($r('app.color.text_font_color')).textAlign(TextAlign.Start).lineHeight($r('app.float.text_height_19')).fontWeight(Constants.TEXT_FONT_WIGHT_400)}.width(Constants.FULL_PERCENT).margin({top: Constants.MARGIN_ZERO_POINT_THREE_PERCENT,bottom: Constants.MARGIN_ZERO_POINT_FIVE_PERCENT}).align(Alignment.Start)}.width(Constants.FORTY_FIVE_PERCENT).margin({ left: Constants.MARGIN_LEFT })// 右边一个图标,另存为Row() {Image($r('app.media.ic_saveas')).focusable(true).focusOnTouch(true).width($r('app.float.image_size')).height($r('app.float.image_size')).visibility(Visibility.Hidden)}.height(Constants.FULL_PERCENT).width(Constants.THIRTY_SEVEN_POINT_TWO).padding({ right: Constants.BACK_PADDING_LEFT }).justifyContent(FlexAlign.End)}.height(Constants.SEVEN_POINT_FOUR).width(Constants.FULL_PERCENT)Scroll(this.scroller) {// 显示媒体文件的容器Column() {List({ space: Constants.LIST_SPACE_20, initialIndex: 0 }) {ForEach(this.myUris, (uri: string, index?: number) => {ListItem() {Column() {Image(uri).borderRadius(Constants.BORDER_RADIUS).onClick(() => {if (index !== undefined) {this.myFileSize = this.myFileSizes[index];this.myFileName = this.myFileNames[index];}AppStorage.setOrCreate('myFileName', this.myFileName);AppStorage.setOrCreate('myFileSize', this.myFileSize);Logger.info(TAG, 'Image onClick myFileName is ' + this.myFileName);Logger.info(TAG, 'Image onClick myFileName is ' + this.myFileSize);})if (index !== undefined) {Stack({ alignContent: Alignment.Center }) {Video({src: uri,controller: this.controllers[index]}).autoPlay(false).controls(true).borderRadius(Constants.BORDER_RADIUS)Image($r('app.media.ic_PAUSE')).width($r('app.float.image_size')).height($r('app.float.image_size')).onClick(() => {this.controllers[index].start();this.showPauses[index] = 0;})}.onClick(() => {this.myFileSize = this.myFileSizes[index];this.myFileName = this.myFileNames[index];AppStorage.setOrCreate('myFileName', this.myFileName);AppStorage.setOrCreate('myFileSize', this.myFileSize);})}}.height(Constants.FULL_PERCENT)}.height(Constants.TWENTY_FIVE_PERCENT)}, (item: string) => item)}.id('picScroller').scrollBar(BarState.Auto)}}.padding({top: Constants.ONE_POINT_FIVE_PERCENT,left: Constants.PADDING_LEFT_RIGHT,right: Constants.PADDING_LEFT_RIGHT})}.backgroundColor($r('app.color.common_background')).height(Constants.FULL_PERCENT)}
}

以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
1

除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

鸿蒙【北向应用开发+南向系统层开发】文档

鸿蒙【基础+实战项目】视频

鸿蒙面经

在这里插入图片描述

为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3279816.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

APP自动化测试 ------ 滑动和拖拽事件操作!

前言 Appium自动化测试中的常见模拟操作涵盖了多种用户交互行为&#xff0c;这些操作对于自动化测试框架来说至关重要&#xff0c;因为它们能够模拟真实用户的使用场景&#xff0c;从而验证应用程序的功能和稳定性。 今天讲解滑动和拖拽事件操作&#xff1a; 1、swipe滑动事…

java-数据结构与算法-02-数据结构-07-优先队列

1. 概念 队列是一种先进先出的结构&#xff0c;但是有些时候&#xff0c;要操作的数据带有优先级&#xff0c;一般出队时&#xff0c;优先级较高的元素先出队&#xff0c;这种数据结构就叫做优先级队列。 比如&#xff1a;你在打音游的时候&#xff0c;你的朋友给你打了个电话…

springboot短视频推荐系统-计算机毕业设计源码21503

摘 要 本论文基于协同过滤算法&#xff0c;旨在设计并实现一种基于SpringBoot框架的短视频推荐系统。该系统主要分为平台用户和管理员两类角色&#xff0c;用户可以注册、登录、浏览短视频内容&#xff0c;并根据个人兴趣收藏喜爱的视频。管理员则可以管理系统数据、用户和内容…

nginx反向代理和负载均衡+安装jdk-22.0.2

ps -aux|grep nginx //查看进程 nginx 代理 nginx代理是负载均衡的基础 主机&#xff1a;192.168.118.60 这台主机只发布了web服务&#xff0c;没有做代理的任何操作 修改一下index.html中的内容 echo "this is java web server" > /usr/local/nginx/htm…

JVM性能调优全指南:高流量电商系统的最佳实践

1.G1(Garbage-First) 官网: G1 Garbage Collection G1收集器是Java 7中引入的垃圾收集器,用于替代CMS(Concurrent Mark-Sweep)收集器。它主要针对大内存、多核CPU环境下的应用场景,具有以下特点: 分代收集:G1仍然保留了分代的概念,但新生代和老年代不再是物理隔离的,…

线程的同步互斥

互斥 互斥保证了在一个时间内只有一个线程访问一个资源。 先看一段代码&#xff1a;三个线程同时对全局变量val进行--&#xff0c;同时val每自减一次其线程局部存储的全局变量 #include <iostream> #include <thread> #include <vector> #include <uni…

Java之Java基础十六(反射)

一、什么是反射 一般情况下&#xff0c;我们在使用某个类之前已经确定它到底是个什么类了&#xff0c;拿到手就直接可以使用 new 关键字来调用构造方法进行初始化&#xff0c;之后使用这个类的对象来进行操作。 Writer writer new Writer(); writer.setName("aaa"…

WPF的MVVM架构:如何通过数据绑定简化UI逻辑

WPF的MVVM架构&#xff1a;如何通过数据绑定简化UI逻辑 目录 MVVM模式概述数据绑定在MVVM中的作用实现MVVM模式的步骤MVVM模式中的常见问题与解决方案实践示例总结 MVVM模式概述 MVVM&#xff08;Model-View-ViewModel&#xff09;是一种设计模式&#xff0c;用于WPF应用程序…

超声波传感器 - 从零开始认识各种传感器【第十九期】

超声波传感器|从零开始认识各种传感器 1、什么是超声波传感器 超声波传感器是一种利用超声波来进行距离测量和目标检测的传感器。它通过发送&#xff0c;超声波脉冲&#xff0c;并测量超声波从传感器发射到目标物体并返回的时间来计算目标物体与传感器之间的距离。 超声波传感…

echarts无数据的展示内容,用graphic属性配置

echarts无数据的展示内容&#xff0c;用graphic属性配置 当echarts无数据的时候&#xff0c;图表展示的是个空白部分&#xff0c;感觉会有点丑&#xff0c;影响页面美观&#xff0c;这时候翻阅了echarts的官网&#xff0c;让我找到个配置项&#xff0c;试试发现还可以&#xf…

Notion支持直接绑定自己的域名,有何工具可替代为公开网站自定义域名?

Notion最近大招频出&#xff0c;推出新功能——自定义域名。只需简单几步&#xff0c;xxx.notion.site秒变你的专属域名&#xff08;月费仅需10美金&#xff09;。推特上的独立内容创作者/初创公司&#xff0c;用它来打造品牌、分享资料模板&#xff0c;甚至实现盈利。 Notion的…

你还在为PDF转Word烦恼?试试这四款免费工具吧!

悄咪咪问一句&#xff0c;大家在平时上班时最头疼的事情有哪些&#xff1f;我想会有很多朋友也有pdf如何在线转换word文档的免费方式&#xff0c;毕竟这些办公文档是非常常见的问题了&#xff0c;所以今天就专门准备这么一篇文章来分享我个人喜欢的四款好用工具&#xff1a; 第…

做知识付费项目还能做吗?知识付费副业项目如何做?能挣多少钱?

hello,我是阿磊&#xff0c;一个20年的码农&#xff0c;6年前代码写不动了&#xff0c;转型专职做副业项目研究&#xff0c;为劳苦大众深度挖掘互联网副业项目&#xff0c;共同富裕。 现在做知识付费项目还能做吗&#xff1f; 互联网虚拟资源项目我一直在做&#xff0c;做了有…

【单片机毕业设计选题24088】-基于STM32的智能家居控制系统

系统功能: 系统操作说明&#xff1a; 上电后OLED显示 “欢迎使用智能家居系统请稍后”&#xff0c;两秒后显示Connecting...表示 正在连接阿里云&#xff0c;正常连接阿里云后显示第一页面&#xff0c;如长时间显示Connecting...请 检查WiFi网络是否正确。 第一页面第一行…

使用runlink通过容器打印出容器的启动命令

1、Runlike简介 Runlike:通过容器打印出容器的启动命令&#xff0c;然后发现自己需要手动重新运行一些容器的人来说&#xff0c;这是一个真正的节省时间。 2、Docker镜像安装 2.1 构建Runlike容器 [rootlocalhost ~]# docker run --rm -v /var/run/docker.sock:/var/run/do…

嵌入式Linux:符号链接(软链接)和硬链接

目录 1、符号链接&#xff08;软链接&#xff09; 2、硬链接 3、link()函数 4、symlink()函数 5、readlink()函数 在 Linux 系统中&#xff0c;符号链接&#xff08;软链接&#xff09;和硬链接是两种创建文件链接的方法。理解它们的区别和使用场景对于文件系统的管理非常…

Spring核心机制Ioc和Aop

Spring全家桶 WEB&#xff1a;SpringMvc、Spring Web Flux 持久层&#xff1a;Spring Data、Spring Data Redis、Spring Data MongoDB 安全校验&#xff1a;spring Security 构建工程脚手架&#xff1a;SpringBoot 微服务&#xff1a;SpringCloud 所有的Spring框架集成&#xf…

轻松入门Linux—CentOS,直接拿捏 —/— <1>

一、什么是Linux Linux是一个开源的操作系统&#xff0c;目前是市面上占有率极高的服务器操作系统&#xff0c;目前其分支有很多。是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统 Linux能运行主要的UNIX工具软件、应用程序和网络协议 Linux支持 32…

每日OJ_牛客CM26 二进制插入

目录 牛客CM26 二进制插入 解析代码 牛客CM26 二进制插入 二进制插入_牛客题霸_牛客网 解析代码 m:1024&#xff1a;100000000 00 n:19 &#xff1a; 10011 要把n的二进制值插入m的第j位到第i位&#xff0c;只需要把n先左移j位&#xff0c;然后再进行或运算&#xff08;|&am…

ctfshow 权限维持 web670--web679

web670 <?php// 题目说明&#xff1a; // 想办法维持权限&#xff0c;确定无误后提交check&#xff0c;通过check后&#xff0c;才会生成flag&#xff0c;此前flag不存在error_reporting(0); highlight_file(__FILE__);$a$_GET[action];switch($a){case cmd:eval($_POST[c…