手把手教你用 HarmonyOS 文件选择器 API,轻松实现文件选择与保存功能
·
今天咱们来聊聊 HarmonyOS 里一个非常实用的功能 —— 文件选择器 API。不管你是开发办公软件、文件管理器还是多媒体应用,这套 API 都能帮你实现用户选择和保存文件的功能。我会用最通俗的话来讲,每个知识点都配上代码示例,保证你看完就能上手写!
一、文件选择器 API 能干啥?先搞懂核心能力
文件选择器就像一个 "文件管家",主要帮我们解决两个问题:
- 让用户选择文件:可以打开系统文件界面,让用户选择文档、音频、图片等文件
- 让用户保存文件:支持指定文件名和保存位置,把数据保存到设备上
举个例子:当你在编辑文档时,点击 "打开" 按钮弹出的文件选择界面,或者点击 "保存" 按钮时的文件保存界面,都是通过文件选择器 API 实现的。HarmonyOS 提供了多种选择器,针对不同类型的文件,用起来非常灵活。
重点总结:文件选择器 = 文件选择 + 文件保存 + 类型过滤
// 先导入核心模块,这是所有操作的基础
import { picker } from '@kit.CoreFileKit';
二、文档选择器 DocumentViewPicker:处理各种格式文件
文档选择器是最常用的选择器,支持选择和保存各种文档格式,比如 txt、pdf、doc 等。咱们一步步看怎么用。
1. 创建文档选择器实例
创建选择器实例有三种方法,推荐使用带 context 的构造函数,更稳定:
// 推荐方式:传入应用上下文,最稳定
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct DocumentPickerDemo {
@State message: string = '点击选择文件';
build() {
Column() {
Text(this.message)
.fontSize(18)
.padding(10)
.onClick(async () => {
// 获取应用上下文
const context = this.getUIContext().getHostContext() as common.UIAbilityContext;
// 创建文档选择器实例
const documentPicker = new picker.DocumentViewPicker(context);
// 这里可以调用选择或保存方法
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
// 不推荐方式:无参构造,可能概率性失败
const documentPicker = new picker.DocumentViewPicker();
// 高级方式:传入窗口实例,用于自定义窗口场景
import { window } from '@kit.ArkUI';
const customWindow = window.findWindow('myWindow'); // 先获取窗口实例
const documentPicker = new picker.DocumentViewPicker(context, customWindow);
2. 选择文件功能
选择文件有三种调用方式,Promise 和 callback 两种异步模式:
// Promise方式选择文件
async function selectFileWithPromise(context: common.UIAbilityContext) {
const documentPicker = new picker.DocumentViewPicker(context);
try {
// 创建选择选项
const options = new picker.DocumentSelectOptions();
options.maxSelectNumber = 5; // 最多选5个文件
options.fileSuffixFilters = ['文档|.txt,.doc,.pdf', '图片|.jpg,.png']; // 过滤文件后缀
// 调用选择方法
const uris = await documentPicker.select(options);
console.log('选择的文件URI:', uris);
// 处理选择的文件URI
} catch (error) {
console.error('选择文件失败:', error);
}
}
// callback方式选择文件
function selectFileWithCallback(context: common.UIAbilityContext) {
const documentPicker = new picker.DocumentViewPicker(context);
const options = new picker.DocumentSelectOptions();
options.defaultFilePathUri = '/storage/emulated/0/Documents'; // 设置默认路径
documentPicker.select(options, (err, uris) => {
if (err) {
console.error('选择文件失败:', err);
return;
}
console.log('选择的文件URI:', uris);
});
}
// 简化callback方式,不传入选项
function selectFileSimpleCallback(context: common.UIAbilityContext) {
const documentPicker = new picker.DocumentViewPicker(context);
documentPicker.select((err, uris) => {
if (err) {
console.error('选择文件失败:', err);
return;
}
console.log('选择的文件URI:', uris);
});
}
3. 保存文件功能
保存文件同样支持 Promise 和 callback 方式,可以指定文件名和保存位置:
// Promise方式保存文件
async function saveFileWithPromise(context: common.UIAbilityContext) {
const documentPicker = new picker.DocumentViewPicker(context);
try {
// 创建保存选项
const options = new picker.DocumentSaveOptions();
options.newFileNames = ['报告.docx', '备忘录.txt']; // 设置文件名
options.defaultFilePathUri = '/storage/emulated/0/Documents'; // 默认保存路径
options.fileSuffixChoices = ['文本文件|.txt', '文档文件|.docx', 'PDF文件|.pdf']; // 后缀选择
// 调用保存方法
const uris = await documentPicker.save(options);
console.log('保存的文件URI:', uris);
// 可以在这里写入文件内容
} catch (error) {
console.error('保存文件失败:', error);
}
}
// callback方式保存文件
function saveFileWithCallback(context: common.UIAbilityContext) {
const documentPicker = new picker.DocumentViewPicker(context);
const options = new picker.DocumentSaveOptions();
options.newFileNames = ['图片.jpg'];
documentPicker.save(options, (err, uris) => {
if (err) {
console.error('保存文件失败:', err);
return;
}
console.log('保存的文件URI:', uris);
// 使用URI写入文件内容
});
}
4. 获取保存文件的后缀类型
从 API 14 开始,支持获取用户选择的文件后缀类型下标:
async function getSavedFileSuffixIndex(context: common.UIAbilityContext) {
const documentPicker = new picker.DocumentViewPicker(context);
try {
const options = new picker.DocumentSaveOptions();
options.newFileNames = ['文件'];
options.fileSuffixChoices = ['txt', 'mp4', 'pdf']; // 提供后缀选项
const uris = await documentPicker.save(options);
if (uris && uris.length > 0) {
// 获取后缀下标
const index = documentPicker.getSelectedIndex();
if (index !== -1) {
const suffix = options.fileSuffixChoices[index];
console.log('选择的后缀类型:', suffix);
}
}
} catch (error) {
console.error('操作失败:', error);
}
}
三、音频选择器 AudioViewPicker:专门处理音频文件
音频选择器用于选择和保存音频文件,使用方式和文档选择器类似:
1. 创建音频选择器实例
// 创建音频选择器实例
const audioPicker = new picker.AudioViewPicker(context);
2. 选择音频文件
// 选择音频文件
async function selectAudioFile(context: common.UIAbilityContext) {
const audioPicker = new picker.AudioViewPicker(context);
try {
const options = new picker.AudioSelectOptions();
options.maxSelectNumber = 3; // 最多选3个音频
const uris = await audioPicker.select(options);
console.log('选择的音频URI:', uris);
// 处理音频文件
} catch (error) {
console.error('选择音频失败:', error);
}
}
3. 保存音频文件
// 保存音频文件
async function saveAudioFile(context: common.UIAbilityContext) {
const audioPicker = new picker.AudioViewPicker(context);
try {
const options = new picker.AudioSaveOptions();
options.newFileNames = ['录音.mp3', '背景音乐.wav'];
const uris = await audioPicker.save(options);
console.log('保存的音频URI:', uris);
// 写入音频数据
} catch (error) {
console.error('保存音频失败:', error);
}
}
四、废弃的图库选择器 PhotoViewPicker:及替代方案
旧版的 PhotoViewPicker 已废弃,推荐使用 photoAccessHelper 替代:
// 废弃的图库选择器使用示例(不推荐)
const photoPicker = new picker.PhotoViewPicker(context);
photoPicker.select((err, result) => {
if (err) {
console.error('选择图片失败:', err);
return;
}
console.log('选择的图片URI:', result.photoUris);
});
// 推荐替代方案:使用photoAccessHelper
import { photoAccessHelper } from '@ohos.photos.photoAccessHelper';
async function selectPhotoWithAccessHelper() {
try {
const photoPicker = new photoAccessHelper.PhotoViewPicker(context);
const options = new photoAccessHelper.PhotoSelectOptions();
options.mimeType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
options.maxSelectNumber = 2;
const result = await photoPicker.select(options);
console.log('选择的图片URI:', result.photoUris);
} catch (error) {
console.error('选择图片失败:', error);
}
}
五、选择器选项配置:精细控制选择器行为
1. 文档选择选项 DocumentSelectOptions
// 文档选择选项配置示例
const options = new picker.DocumentSelectOptions();
options.maxSelectNumber = 10; // 最大选择数
options.defaultFilePathUri = '/storage/emulated/0/Downloads'; // 默认路径
options.fileSuffixFilters = ['文本文件|.txt,.md', '所有文件|.*']; // 后缀过滤
options.selectMode = picker.DocumentSelectMode.FOLDER; // 选择模式:文件、文件夹或混合
options.authMode = true; // 授权模式
options.multiAuthMode = true; // 批量授权模式
options.multiUriArray = ['uri1', 'uri2']; // 批量授权URI数组
options.mergeMode = picker.MergeTypeMode.AUDIO; // 聚合视图模式
options.isEncryptionSupported = true; // 支持加密
2. 文档保存选项 DocumentSaveOptions
// 文档保存选项配置示例
const saveOptions = new picker.DocumentSaveOptions();
saveOptions.newFileNames = ['新文件.txt']; // 文件名
saveOptions.defaultFilePathUri = '/storage/emulated/0/Documents'; // 保存路径
saveOptions.fileSuffixChoices = ['txt', 'pdf', 'docx']; // 后缀选项
saveOptions.pickerMode = picker.DocumentPickerMode.DOWNLOAD; // 下载模式
六、实际应用场景:文件选择与保存完整流程
1. 文档选择与处理完整流程
import { common } from '@kit.AbilityKit';
@Entry
@Component
struct FilePickerApp {
@State selectedFiles: string[] = [];
@State isLoading: boolean = false;
private context: common.UIAbilityContext | null = null;
aboutToAppear() {
// 获取应用上下文
this.context = this.getUIContext().getHostContext() as common.UIAbilityContext;
}
// 选择文件方法
async selectDocuments() {
this.isLoading = true;
try {
const documentPicker = new picker.DocumentViewPicker(this.context!);
const options = new picker.DocumentSelectOptions();
options.maxSelectNumber = 5;
options.fileSuffixFilters = ['文档|.txt,.doc,.pdf', '图片|.jpg,.png'];
const uris = await documentPicker.select(options);
this.selectedFiles = uris;
console.log('选择的文件:', uris);
// 这里可以添加文件处理逻辑,比如读取文件内容
this.processSelectedFiles(uris);
} catch (error) {
console.error('选择文件失败:', error);
} finally {
this.isLoading = false;
}
}
// 处理选择的文件
processSelectedFiles(uris: string[]) {
uris.forEach(uri => {
// 使用@ohos.file.fs接口读取文件内容
// 这里只是示例,实际需要处理文件操作
console.log('处理文件:', uri);
});
}
// 保存文件方法
async saveDocument() {
if (this.selectedFiles.length === 0) {
console.log('请先选择文件');
return;
}
this.isLoading = true;
try {
const documentPicker = new picker.DocumentViewPicker(this.context!);
const options = new picker.DocumentSaveOptions();
options.newFileNames = ['处理后的文件.txt'];
options.fileSuffixChoices = ['txt', 'pdf'];
const saveUris = await documentPicker.save(options);
if (saveUris && saveUris.length > 0) {
console.log('保存到:', saveUris[0]);
// 这里可以添加文件写入逻辑
this.writeToFile(saveUris[0], '这是处理后的文件内容');
}
} catch (error) {
console.error('保存文件失败:', error);
} finally {
this.isLoading = false;
}
}
// 写入文件内容
writeToFile(uri: string, content: string) {
// 使用@ohos.file.fs接口写入文件
// 这里只是示例,实际需要处理文件写入
console.log('写入内容到:', uri, '内容:', content);
}
build() {
Column() {
Text('文件选择器应用')
.fontSize(24)
.fontWeight(FontWeight.Bold)
.margin(10)
Button('选择文档')
.onClick(() => this.selectDocuments())
.margin(10)
.disabled(this.isLoading)
Button('保存处理后的文档')
.onClick(() => this.saveDocument())
.margin(10)
.disabled(this.isLoading || this.selectedFiles.length === 0)
if (this.selectedFiles.length > 0) {
List({ space: 5 }) {
ForEach(this.selectedFiles, (uri, index) => {
ListItem() {
Text(`文件 ${index + 1}: ${uri}`)
.fontSize(16)
.ellipsis({ end: true })
}
})
}
.width('90%')
}
if (this.isLoading) {
LoadingProgress()
.color('#007DFF')
.width(50)
.height(50)
.margin(20)
}
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Start)
.padding(10)
}
}
七、错误处理与最佳实践
1. 统一错误处理
function handlePickerError(error: any, operation: string) {
console.error(`[${operation}] 操作失败`, error);
if (error.code) {
switch (error.code) {
case 13900001:
console.log('操作不允许,可能是参数错误或权限问题');
break;
case 401:
console.log('参数错误,检查必填参数和类型');
break;
case 801:
console.log('设备不支持该功能');
break;
default:
console.log(`错误码 ${error.code},信息: ${error.message}`);
}
} else {
console.log('未知错误:', error.message);
}
}
// 使用示例
try {
const uris = await documentPicker.select(options);
} catch (error) {
handlePickerError(error, '选择文件');
}
2. 最佳实践建议
- 优先使用带 context 的构造函数:避免概率性失败问题
- 合理设置文件过滤:通过 fileSuffixFilters 限制显示的文件类型,提升用户体验
- 处理批量选择:maxSelectNumber 设置合适的选择数量上限
- 提供默认路径:defaultFilePathUri 设置常用路径,减少用户操作
- 处理异步回调:同时支持 Promise 和 callback 两种模式,适应不同场景
- 检查 API 版本:注意接口的起始版本,避免在不支持的设备上调用
八、总结:文件选择器 API 的三大优势与应用场景
1. 三大核心优势
- 功能全面:支持文档、音频等多种文件类型,满足不同应用场景
- 灵活配置:通过各种 Options 类可以精细控制选择器的行为
- 安全可靠:返回的 URI 经过编码处理,支持加密和授权模式
2. 典型应用场景
- 办公应用:打开和保存文档、表格、演示文稿
- 媒体应用:选择音频文件进行编辑,保存处理后的音频
- 文件管理器:实现文件浏览、选择、保存的核心功能
- 社交应用:选择图片、视频进行分享
- 备份工具:选择需要备份的文件,指定保存位置
通过 HarmonyOS 文件选择器 API,我们可以轻松实现应用中的文件选择和保存功能,提升用户体验。记住这些常用接口和配置方法,结合实际场景灵活运用,就能开发出强大的文件处理功能啦!
更多推荐

所有评论(0)