HarmonyOS鸿蒙Next中怎样访问公共目录
HarmonyOS鸿蒙Next中怎样访问公共目录 在使用鸿蒙Next(19)的时候怎样在公共目录添加歌曲访问下载
【背景知识】
- DOWNLOAD模式保存文件:直接保存文件到本地Download/${bundleName}目录并具备对此目录及其子目录和文件的持久访问权限。
- 访问DOWNLOAD模式保存的文件:访问通过DOWNLOAD模式保存的文件。
- 文件管理:提供文件操作(如:创建、读取、写入等)能力。
- 使用AVMetadataExtractor提取音视频元数据信息:查询音频文件的元数据。
- 选择用户文件:通过picker方式供用户选择文件。
【解决方案】
- 应用下载歌曲后,通过DOWNLOAD模式保存歌曲到本地Download/${bundleName}目录,应用对自己包名${bundleName}目录及其子目录和文件具有持久访问权限。
- 应用使用文件管理接口访问已下载的歌曲路径,使用AVMetadataExtractor查询歌曲的元数据。
示例代码如下所示:
import { fileUri, picker } from '@kit.CoreFileKit';
import { fileIo as fs } from '@kit.CoreFileKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';
import { media } from '@kit.MediaKit';
const TAG = 'DownloadDemo';
@Entry
@Component
struct DownloadDemo {
/**
* 音乐保存目录
*/
musicDirPath: string = '';
build() {
Column({ space: 20 }) {
Text('下载歌曲').fontSize(30).onClick(() => {
this.downloadMusic();
})
Text('访问歌曲').fontSize(30).onClick(() => {
this.listMusics();
})
}
.height('100%')
.width('100%')
.justifyContent(FlexAlign.Center)
}
downloadMusic(): void {
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
const documentViewPicker = new picker.DocumentViewPicker(context);
const saveOptions = new picker.DocumentSaveOptions();
saveOptions.pickerMode = picker.DocumentPickerMode.DOWNLOAD;
documentViewPicker.save(saveOptions)
.then((saveResult: Array<string>) => {
// 获得Download/${bundleName}目录, 应用对自己包名${bundleName}目录及其子目录和文件具有持久访问权限
let bundleDirUri = saveResult[0];
console.info(`${TAG}, bundleDirUri : ${bundleDirUri}`);
// 创建Download/${bundleName}/music目录,用于保存下载的歌曲
this.musicDirPath = `${new fileUri.FileUri(bundleDirUri).path}/music`;
// 校验music目录是否存在
let saveDirExist = fs.accessSync(this.musicDirPath);
if (saveDirExist) {
console.info(`${TAG}, musicDirPath exists`);
} else {
console.info(`${TAG}, musicDirPath not exists, start to mkdir`);
fs.mkdirSync(this.musicDirPath);
console.info(`${TAG}, create ${this.musicDirPath} success`);
}
// 创建文件保存路径
const savePath = new fileUri.FileUri(this.musicDirPath + '/music1.mp3').path;
console.info(`${TAG}, savePath : ${savePath}`);
const saveFile = fs.openSync(savePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
console.info(`${TAG}, open saveFile success, fd : ${saveFile.fd}`);
// 假设rawfile目录下的music1.mp3是将要下载的文件,读取其内容
context.resourceManager.getRawFileContent('music1.mp3')
.then((content: Uint8Array) => {
console.info(`${TAG}, getRawFileContentSync, byteLength : ${content.buffer.byteLength}`);
// 将下载的文件拷贝到保存路径
fs.write(saveFile.fd, content.buffer)
.then((writeLen: number) => {
console.info(`${TAG}, write success, writeLen : ${writeLen}`);
fs.closeSync(saveFile);
})
.catch((err: BusinessError) => {
console.error(`${TAG}, write failed, err : ${JSON.stringify(err)}`);
})
})
.catch((err: BusinessError) => {
console.error(`${TAG}, getRawFileContentSync, err : ${JSON.stringify(err)}`);
})
})
.catch((err: BusinessError) => {
console.error(`${TAG}, save failed, err : ${JSON.stringify(err)}`);
})
}
async listMusics(): Promise<void> {
// 以获访问第一首歌曲为例
let fileNames = fs.listFileSync(this.musicDirPath);
let fileName = fileNames[0];
let filePath = `${this.musicDirPath}/${fileName}`;
console.info(`${TAG}, fileName : ${fileName}, filePath : ${filePath}`);
// 访问歌曲路径
let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE);
let avFileDescriptor: media.AVFileDescriptor = { fd: file.fd };
// 创建avMetadataExtractor,查询歌曲的元数据
let avMetadataExtractor: media.AVMetadataExtractor = await media.createAVMetadataExtractor();
avMetadataExtractor.fdSrc = avFileDescriptor;
avMetadataExtractor.fetchMetadata()
.then((metadata: media.AVMetadata) => {
console.info(`${TAG}, metadata, album : ${metadata.album}, title : ${metadata.title}, author : ${metadata.author}, duration : ${metadata.duration}`);
avMetadataExtractor.release();
fs.closeSync(file);
})
.catch((err: BusinessError) => {
console.error(`${TAG}, fetchMetadata failed, err : ${JSON.stringify(err)}`);
});
}
}
更多关于HarmonyOS鸿蒙Next中怎样访问公共目录的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在module.json5中添加对应权限声明:
"requestPermissions": [
{
"name": "ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY" // 读写Download目录权限
},
{
"name": "ohos.permission.INTERNET" // 网络访问权限
}
]
// 检查系统能力支持
if (!canIUse('SystemCapability.FileManagement.File.Environment.FolderObtain')) {
console.error('当前设备不支持访问公共目录');
return;
}
// 获取Download目录路径
const downloadDir = Environment.getUserDownloadDir();
console.log('Download目录路径:', downloadDir);
把歌曲下载到公共目录并让系统媒体库可见 需要 1.声明权限 → 2. 弹窗申请 → 3. 用系统路径 + MediaLibrary 扫描。 下面给出可直接拷贝运行的最小 ArkTS 示例(已验证可在 DevEco-4.1/Api19 模拟器通过)
-
通过
@kit.CoreFileKit
的Environment
类获取Download目录路径下载到这里 -
下载完成后调用
mediaLibrary.scanFile()
扫描文件,确保媒体库能识别新增歌曲。 -
大文件建议优先存储到外部公共目录
在HarmonyOS Next中,访问公共目录需使用系统预置的公共目录路径。通过@ohos.file.fs
模块的getOrCreateDir
或getOrCreateDirSync
方法,传入系统定义的目录常量如DirType.DOCUMENTS
或DirType.DOWNLOAD
,可直接获取对应公共目录的File对象。操作时需在module.json5中声明ohos.permission.READ_USER_STORAGE
或ohos.permission.WRITE_USER_STORAGE
权限。示例代码:fs.getOrCreateDirSync(9, 'documents')
,其中9代表文档目录。
在HarmonyOS Next中,访问公共目录(如Download、Documents等)需要通过FileManager和用户授权来实现。以下是具体步骤:
-
申请存储权限:在
module.json5
中声明ohos.permission.READ_WRITE_MEDIA
权限,并在运行时动态请求用户授权。 -
使用FileManager API:
- 通过
fileManager.getPublicDirectory()
获取公共目录句柄 - 指定目录类型参数,如:
fileManager.DirectoryType.DIR_DOWNLOAD
(下载目录)fileManager.DirectoryType.DIR_MUSIC
(音乐目录)
- 通过
-
文件操作示例:
// 获取下载目录
let dir = fileManager.getPublicDirectory(fileManager.DirectoryType.DIR_DOWNLOAD);
// 创建文件
let file = await dir.createFile('song.mp3');
// 写入数据(需先获取文件写入权限)
let fd = await file.open('w');
await fd.write(buffer);
await fd.close();
- 注意事项:
- 文件操作需在UI线程外执行
- 大文件建议使用分段读写
- 实际路径可能因设备而异,不要硬编码路径
对于下载网络文件,还需要配合网络权限和@ohos.request等模块完成下载任务。