HarmonyOS 鸿蒙Next应用如何获取用户设备内文件?
HarmonyOS 鸿蒙Next应用如何获取用户设备内文件?
鸿蒙应用如何获取用户设备内文件?
一、结论
应用访问用户设备内的文件(图片,视频,音频,文档文件,xx文件)等用户文件时,我们可以通过系统预置的文件选择器(FilePicker),实现该能力。
通过Picker访问相关文件,将拉起对应的应用,引导用户完成界面操作,接口本身无需申请权限。
但是picker获取的uri只具有临时权限,应用后台关闭后就失去了访问权限。
二、代码实现和详细解释
用户相音频文件选择:
使用系统提供的AudioViewPicker来访问用户的音频资源,当应用选择成功,点击确认后,会通过回调得到文件资源的Uri。
通过文件资源的Uri。进行FS操作,来读写用户音频文件。
import { picker } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
/**
* 访问器管理工具
*/
export class PickerMgr {
private TAG: string = 'PickerMgr';
private static mPickerMgr: PickerMgr | null = null;
public static Ins(): PickerMgr {
if (!PickerMgr.mPickerMgr) {
PickerMgr.mPickerMgr = new PickerMgr();
}
return PickerMgr.mPickerMgr;
}
/**
* 选择用户设备内的所有音频资源
*/
public selectAudio(context: common.Context, selectNum: number): Promise<Array<string>>{
return new Promise((resolve, reject)=>{
// 创建音频选择器
const audioViewPicker = new picker.AudioViewPicker(context);
// 设置音频选择操作参数
const audioSelectOptions = new picker.AudioSelectOptions();
audioSelectOptions.maxSelectNumber = selectNum;
// 向用户唤起系统选择界面
audioViewPicker.select(audioSelectOptions).then((audioSelectResult: Array<string>) => {
// 文件选择成功后,返回被选中音频的uri结果集。
console.info('audioViewPicker.select to file succeed and uri is:' + JSON.stringify(audioSelectResult));
resolve(audioSelectResult);
}).catch((err: BusinessError) => {
// 异常返回
console.error(`Invoke audioViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
reject(err);
})
});
}
}
import { PickerMgr } from '../../mgr/PickerMgr'
import { common } from '@kit.AbilityKit';
import { fileIo as FS } from '@kit.CoreFileKit';
/**
* 用户音频选择
*/
@Entry
@Component
@Preview
struct AudioSelectPage {
/**
* 点击唤起音频选择器
*/
onSelectUserAudioFile = async ()=>{
// 请确保 getContext(this) 返回结果为 UIAbilityContext
let context = getContext(this) as common.Context;
let res = await PickerMgr.Ins().selectAudio(context, 1);
this.optionAudioFile(res);
}
/**
* 对于音频文件进行文件读写操作
* @param uri
*/
private optionAudioFile(uri: string){
// 这里需要注意接口权限参数是 fs.OpenMode.READ_ONLY。只读.
let file = FS.openSync(uri, FS.OpenMode.READ_ONLY);
console.info('file fd: ' + file.fd);
// 读取到系统文件标识符后,就可以针对这个文件进行操作。可以理解为文件在HarmonyOS系统中的ID。
let buffer = new ArrayBuffer(4096);
let readLen = FS.readSync(file.fd, buffer);
console.info('readSync data to file succeed and buffer size is:' + readLen);
//读取完成后关闭fd。
FS.closeSync(file);
}
build() {
RelativeContainer() {
Text("点击唤起音频选择器")
.fontSize(50)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
.onClick(this.onSelectUserAudioFile)
}
.height('100%')
.width('100%')
}
}
使用picker获取的select()返回的uri权限是临时只读权限,待退出应用后台后,获取的临时权限就会失效。 使用picker获取的select()返回的uri权限是临时只读权限,待退出应用后台后,获取的临时权限就会失效。 使用picker获取的select()返回的uri权限是临时只读权限,待退出应用后台后,获取的临时权限就会失效。
用户图片和视频相册选择:
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { BusinessError } from '@kit.BasicServicesKit';
/**
* 相册图片选择
*/
@Entry
@Component
struct AlbumSelectPage {
private TAG: string = "AlbumSelectPage";
onClickSelectPhoto = ()=>{
try {
let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
// 设置筛选过滤条件
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
// 选择用户选择数量
PhotoSelectOptions.maxSelectNumber = 1;
// 实例化图片选择器
let photoPicker = new photoAccessHelper.PhotoViewPicker();
// 唤起安全相册组件
photoPicker.select(PhotoSelectOptions, (err: BusinessError, PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => {
if (err) {
console.error(this.TAG, "onClickSelectPhoto photoPicker.select error:" + JSON.stringify(err));
return;
}
// 用户选择确认后,会回调到这里。
console.info(this.TAG, "onClickSelectPhoto photoPicker.select successfully:" + JSON.stringify(PhotoSelectResult));
});
} catch (error) {
let err: BusinessError = error as BusinessError;
console.error(this.TAG, "onClickSelectPhoto photoPicker.select catch failed:" + JSON.stringify(err));
}
}
build() {
Row(){
Button('点击唤起相册选择')
.onClick(this.onClickSelectPhoto)
}
.justifyContent(FlexAlign.Center)
.size({
width: "100%",
height: "100%"
})
}
}
文件选择示例:
import { picker } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
/**
* 文件选择
*/
@Entry
@Component
struct FileSelectPage {
build() {
RelativeContainer() {
Text("点击唤起文件选择器")
.fontSize(px2fp(42))
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
.onClick(()=>{
const documentSelectOptions = new picker.DocumentSelectOptions();
// 选择文档的最大数目(可选)
documentSelectOptions.maxSelectNumber = 5;
// 指定选择的文件或者目录路径(可选)
documentSelectOptions.defaultFilePathUri = "file://docs/storage/Users/currentUser/test";
// 选择文件的后缀类型['后缀类型描述|后缀类型'](可选) 若选择项存在多个后缀名,则每一个后缀名之间用英文逗号进行分隔(可选),后缀类型名不能超过100,选择所有文件:'所有文件(*.*)|.*';
documentSelectOptions.fileSuffixFilters = ['图片(.png, .jpg)|.png,.jpg', '文档|.txt', '视频|.mp4', '.pdf'];
//选择是否对指定文件或目录授权,true为授权,当为true时,defaultFilePathUri为必选参数,拉起文管授权界面;false为非授权,拉起常规文管界面(可选)
documentSelectOptions.authMode = true;
let uris: Array<string> = [];
let context = getContext(this) as common.Context; // 请确保 getContext(this) 返回结果为 UIAbilityContext
// 创建文件选择器实例
const documentViewPicker = new picker.DocumentViewPicker(context);
documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => {
//文件选择成功后,返回被选中文档的uri结果集。
uris = documentSelectResult;
console.info('documentViewPicker.select to file succeed and uris are:' + uris);
}).catch((err: BusinessError) => {
console.error(`Invoke documentViewPicker.select failed, code is ${err.code}, message is ${err.message}`);
})
})
}
.height('100%')
.width('100%')
}
}
更多关于HarmonyOS 鸿蒙Next应用如何获取用户设备内文件?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
通过 Picker
在HarmonyOS Next中,应用通过FileManager和FileAccessKit框架获取设备内文件。首先需在module.json5中声明ohos.permission.READ_MEDIA权限。使用FileAccessHelper创建实例,通过openFile选择文件或getRoots获取沙箱外目录。通过uri访问文件元数据和内容。
在HarmonyOS Next中,应用获取用户设备内的文件主要通过文件管理接口和用户授权来实现。核心步骤如下:
-
声明权限:在应用的
module.json5配置文件中,声明必要的文件访问权限,例如ohos.permission.READ_MEDIA(读取媒体文件)或ohos.permission.WRITE_MEDIA(写入媒体文件)。 -
动态申请权限:在运行时通过
abilityAccessCtrl接口动态向用户申请权限,确保用户知情并授权。 -
使用文件选择器:推荐使用系统提供的文件选择器(FilePicker),让用户主动选择需要访问的文件。这种方式遵循最小权限原则,无需申请广泛的存储权限。例如:
- 使用
PhotoViewPicker选择图片/视频。 - 使用
DocumentViewPicker选择文档。 - 使用
AudioViewPicker选择音频文件。
- 使用
-
访问公共目录:对于媒体类文件(图片、视频、音频),可以通过
mediaLibrary接口访问公共媒体库,但需要用户授权。 -
安全沙箱访问:应用自身的沙箱目录(
context.filesDir)可直接读写,无需权限。
关键注意事项:
- HarmonyOS Next强化了隐私安全,禁止随意访问设备存储根目录。
- 优先使用文件选择器,而非直接请求存储权限。
- 遵循“一次授权、单次访问”原则,确保用户对文件访问有完全控制。
示例代码(使用文件选择器选择图片):
import { picker } from '@kit.FileKit';
let photoPicker = new picker.PhotoViewPicker();
photoPicker.select()
.then((photoSelectResult) => {
// 处理用户选择的文件
})
.catch((err) => {
console.error('文件选择失败');
});
通过以上方式,可在保障用户隐私的前提下,安全获取设备文件。

