• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 开发用户文件管理器(仅对系统应用开放)
2<!--Kit: Core File Kit-->
3<!--Subsystem: FileManagement-->
4<!--Owner: @wang_zhangjun; @zhuangzhuang-->
5<!--Designer: @wang_zhangjun; @zhuangzhuang; @renguang1116-->
6<!--Tester: @liuhonggang123; @yue-ye2; @juxiaopang-->
7<!--Adviser: @foryourself-->
8
9OpenHarmony预置了FileManager文件管理器。系统应用开发者也可以根据需要,按以下指导自行开发文件管理器。
10
11## 开发步骤
12开发用户文件管理器的相关API详细介绍请参见[API参考](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md)。
13
141. 权限配置和导入模块。
15   申请ohos.permission.FILE_ACCESS_MANAGERohos.permission.GET_BUNDLE_INFO_PRIVILEGED权限,配置方式请参见[申请应用权限](../security/AccessToken/determine-application-mode.md#system_basic等级应用申请权限的方式)。
16
17   > **说明:**
18   >
19   > ohos.permission.FILE_ACCESS_MANAGER是使用文件访问框架接口的基础权限。
20   >
21   > ohos.permission.GET_BUNDLE_INFO_PRIVILEGED权限可以用于查询系统内当前支持的文件管理服务端应用信息。
22
232. 导入依赖模块。
24
25   ```ts
26   import { fileAccess } from '@kit.CoreFileKit';
27   import { fileExtensionInfo } from '@kit.CoreFileKit';
28   ```
29
30   其中fileAccess提供了文件基础操作的API,fileExtensionInfo提供了应用开发的关键结构体。
31
323. 查询设备列表。
33   开发者可以获取当前系统所有文件管理服务端管理的设备属性,也可以获取某个文件管理服务端管理的设备属性。应用开发者可以按需过滤设备。
34
35   在文件访问框架中,使用RootInfo用于表示设备的属性信息。以下示例可以获取所有设备的RootInfo。
36
37   ```ts
38   import { common } from '@kit.AbilityKit';
39   import { BusinessError } from '@kit.BasicServicesKit';
40   import { Filter } from '@kit.CoreFileKit';
41
42   // context是EntryAbility传过来的context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext
43   let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
44
45   // 创建连接系统内所有文件管理服务端的helper对象
46   let fileAccessHelperAllServer: fileAccess.FileAccessHelper;
47   function createFileAccessHelper(context: common.UIAbilityContext): void {
48     try {
49       fileAccessHelperAllServer = fileAccess.createFileAccessHelper(context);
50       if (!fileAccessHelperAllServer) {
51         console.error("createFileAccessHelper interface returns an undefined object");
52       }
53     } catch (err) {
54         let error: BusinessError = err as BusinessError;
55         console.error("createFileAccessHelper failed, errCode:" + error.code + ", errMessage:" + error.message);
56     }
57   }
58   let rootInfos: Array<fileAccess.RootInfo> = [];
59   async function getRoots(): Promise<void>{
60     let rootIterator: fileAccess.RootIterator;
61     let isDone: boolean = false;
62     try {
63       rootIterator = await fileAccessHelperAllServer.getRoots();
64       if (!rootIterator) {
65         console.error("getRoots interface returns an undefined object");
66         return;
67       }
68       while (!isDone) {
69         let result = rootIterator.next();
70         console.info("next result = " + JSON.stringify(result));
71         isDone = result.done;
72         if (!isDone)
73           rootInfos.push(result.value);
74       }
75     } catch (err) {
76       let error: BusinessError = err as BusinessError;
77       console.error("getRoots failed, errCode:" + error.code + ", errMessage:" + error.message);
78     }
79   }
80   ```
81
824. 浏览目录。
83   在文件访问框架中,使用FileInfo表示一个文件(目录)的基础信息。开发者可以使用listfile接口遍历下一级所有文件(目录)的迭代器对象;也可以通过scanfile过滤指定目录,获取满足条件的迭代器对象。
84
85    listfile和scanfile接口当前支持RootInfo对象调用,可用于支撑遍历下一级文件或过滤整个目录树。同时,接口也支持FileInfo对象调用,用于支撑遍历下一级文件或过滤指定目录。
86
87   ```ts
88   import { BusinessError } from '@kit.BasicServicesKit';
89   import { Filter } from '@kit.CoreFileKit';
90
91   // 从根目录开始
92   let rootInfos = [];
93   //rootInfos 从getRoots()获取
94   let rootInfo: fileAccess.RootInfo = rootInfos[0];
95   let fileInfos: Array<fileAccess.FileInfo> = [];
96   let isDone: boolean = false;
97   let filter: Filter = {suffix : [".txt", ".jpg", ".xlsx"]}; // 设定过滤条件
98   try {
99     let fileIterator = rootInfo.listFile();          // 遍历设备rootinfos[0]的根目录,返回迭代器对象
100     // let fileIterator = rootInfo.scanFile(filter); // 过滤设备rootinfos[0]满足指定条件的文件信息,返回迭代对象
101     if (!fileIterator) {
102       console.error("listFile interface returns an undefined object");
103     }
104     while (!isDone) {
105       let result = fileIterator.next();
106       console.info("next result = " + JSON.stringify(result));
107       isDone = result.done;
108       if (!isDone)
109         fileInfos.push(result.value);
110     }
111   } catch (err) {
112    let error: BusinessError = err as BusinessError;
113     console.error("listFile failed, errCode:" + error.code + ", errMessage:" + error.message);
114   }
115
116   // 从指定的目录开始
117   let fileInfoDir: fileAccess.FileInfo = fileInfos[0]; // fileInfoDir 表示某个目录信息
118   let subFileInfos: Array<fileAccess.FileInfo> = [];
119   let isDone02: boolean = false;
120   let filter02: Filter = {suffix : [".txt", ".jpg", ".xlsx"]}; // 设定过滤条件
121   try {
122     let fileIterator = fileInfoDir.listFile(); // 遍历特定的目录fileinfo,返回迭代器对象
123     // let fileIterator = rootInfo.scanFile(filter02); // 过滤特定的目录fileinfo,返回迭代器对象
124     if (!fileIterator) {
125       console.error("listFile interface returns an undefined object");
126     }
127     while (!isDone02) {
128       let result = fileIterator.next();
129       console.info("next result = " + JSON.stringify(result));
130       isDone02 = result.done;
131       if (!isDone02)
132         subFileInfos.push(result.value);
133     }
134   } catch (err) {
135    let error: BusinessError = err as BusinessError;
136     console.error("listFile failed, errCode:" + error.code + ", errMessage:" + error.message);
137   }
138   ```
139
1405. 操作文件或目录。
141   开发者可以集成文件访问框架的接口,完成一些用户行为,比如删除文件(目录)、重命名文件(目录)、新建文件(目录)、移动文件(目录)等。以下示例展示了如何创建一个文件,其他接口请参见[API参考](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md)。
142
143   ```ts
144   import { BusinessError } from '@kit.BasicServicesKit';
145
146   // 以本地设备为例
147   // 创建文件
148   // 示例代码sourceUri是Download目录的fileinfo中的URI
149   // 开发者应根据自己实际获取fileinfo的URI进行开发
150   async function createFile(): Promise<void> {
151     let sourceUri: string = "file://docs/storage/Users/currentUser/Download";
152     let displayName: string = "file1";
153     let fileUri: string = '';
154     try {
155       // fileAccessHelperAllServer 参考 fileAccess.createFileAccessHelper 示例代码获取
156       fileUri = await fileAccessHelperAllServer.createFile(sourceUri, displayName);
157       if (!fileUri) {
158         console.error("createFile return undefined object");
159       }
160       console.info("createFile sucess, fileUri: " + JSON.stringify(fileUri));
161     } catch (err) {
162      let error: BusinessError = err as BusinessError;
163      console.error("createFile failed, errCode:" + error.code + ", errMessage:" + error.message);
164     };
165   }
166   ```
167
168## 监听设备上下线
169
170开发设备上下线的相关API详细介绍请参见[API参考](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md)。
171
172notify接口不仅可以用来监听目录的变化,还能监听设备上线,下线功能。
173
174
1751. 权限配置和导入模块。
176
177   申请ohos.permission.FILE_ACCESS_MANAGERohos.permission.GET_BUNDLE_INFO_PRIVILEGED权限,配置方式请参见[访问控制授权申请](../security/AccessToken/declare-permissions.md)。
178
179   > **说明:**
180   >
181   > ohos.permission.FILE_ACCESS_MANAGER是使用文件访问框架接口的基础权限。
182   >
183   > ohos.permission.GET_BUNDLE_INFO_PRIVILEGED权限可以用于查询系统内当前支持的文件管理服务端应用信息。
184
1852. 导入依赖模块。
186
187   ```ts
188   import { fileAccess } from '@kit.CoreFileKit';
189   import { fileExtensionInfo } from '@kit.CoreFileKit';
190   ```
191
192 其中fileAccess提供了文件基础操作的API,fileExtensionInfo提供了应用开发的关键结构体。
193
1943. 提供监听回调方法。
195
196   ```ts
197   const callbackDir1 = (NotifyMessageDir: fileAccess.NotifyMessage) => {
198     if (NotifyMessageDir != undefined) {
199       console.log('NotifyType: ' + NotifyMessageDir.type + 'NotifyUri:' + NotifyMessageDir.uris[0]);
200     } else {
201      console.error("NotifyMessageDir is undefined");
202     }
203   }
204   ```
205
2064. 注册监听设备和取消设备监听。
207
208  开发者可以根据提供的[DEVICES_URI](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md#常量),传入方法registerObserver()中,就能监听设备上下线状态。传入方法unregisterObserver()中,就能取消设备上线,下线状态。
209
210   ```ts
211   import { BusinessError } from '@kit.BasicServicesKit';
212   import { common } from '@kit.AbilityKit';
213
214   //提供监听回调方法
215   const callbackDir1 = (NotifyMessageDir: fileAccess.NotifyMessage) => {
216     if (NotifyMessageDir != undefined) {
217       console.log('NotifyType: ' + NotifyMessageDir.type + 'NotifyUri:' + NotifyMessageDir.uris[0]);
218     } else {
219      console.error("NotifyMessageDir is undefined");
220     }
221   }
222
223   // context是EntryAbility传过来的context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext
224   let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
225   // 创建连接系统内所有文件管理服务端的helper对象
226   let fileAccessHelperAllServer: fileAccess.FileAccessHelper;
227   function createFileAccessHelper(context: common.UIAbilityContext): void {
228     try {
229       fileAccessHelperAllServer = fileAccess.createFileAccessHelper(context);
230       if (!fileAccessHelperAllServer) {
231         console.error("createFileAccessHelper interface returns an undefined object");
232       }
233     } catch (err) {
234         let error: BusinessError = err as BusinessError;
235         console.error("createFileAccessHelper failed, errCode:" + error.code + ", errMessage:" + error.message);
236     }
237   }
238   //注册监听设备,开发者可以根据提供的DEVICES_URI传入registerObserver()方法中,就能监听设备上线,下线状态。
239   async function RegisterObserver03() {
240     try {
241       // 监听设备的上下线
242       fileAccessHelperAllServer.registerObserver(fileAccess.DEVICES_URI, true, callbackDir1);
243     } catch (err) {
244       let error: BusinessError = err as BusinessError;
245       console.error("unregisterObserver failed, errCode:" + error.code + ", errMessage:" + error.message);
246     }
247   }
248   //取消设备监听,开发者可以根据提供的DEVICES_URI传入unregisterObserver()方法中,就能取消设备上线,下线状态。
249   async function UnregisterObserver04() {
250     try {
251       // 取消监听设备的上下线
252       fileAccessHelperAllServer.unregisterObserver(fileAccess.DEVICES_URI, callbackDir1);
253     } catch (err) {
254       let error: BusinessError = err as BusinessError;
255       console.error("unregisterObserver failed, errCode:" + error.code + ", errMessage:" + error.message);
256     }
257   }
258   ```
259