1# Developing a File Manager Application (for System Applications Only) 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 is prebuilt with the **FileManager** application. You can also develop your own file manager application as required. 10 11## How to Develop 12For details about the APIs for developing the user file manager, see [User File Access and Management](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md). 13 141. Request permissions required. 15 Request the ohos.permission.FILE_ACCESS_MANAGER and ohos.permission.GET_BUNDLE_INFO_PRIVILEGED permissions. For details, see [Requesting Permissions for System_basic Applications](../security/AccessToken/determine-application-mode.md#requesting-permissions-for-system_basic-applications). 16 17 > **NOTE** 18 > 19 > The ohos.permission.FILE_ACCESS_MANAGER permission allows your application to call the user file access framework APIs. 20 > 21 > The ohos.permission.GET_BUNDLE_INFO_PRIVILEGED permission allows your application to obtain information about file management server applications supported by the system. 22 232. Import dependent modules. 24 25 ```ts 26 import { fileAccess } from '@kit.CoreFileKit'; 27 import { fileExtensionInfo } from '@kit.CoreFileKit'; 28 ``` 29 30 The **fileAccess** module provides APIs for basic file operations, and the **fileExtensionInfo** module provides key structs for application development. 31 323. Query device information. 33 You can obtain attributes of the devices managed by one or all file management servers in the system. You can also filter devices as required. 34 35 In the user file access framework, **RootInfo** indicates the attribute information of a device. For example, obtain **RootInfo** of all devices. 36 37 ```ts 38 import { common } from '@kit.AbilityKit'; 39 import { BusinessError } from '@kit.BasicServicesKit'; 40 import { Filter } from '@kit.CoreFileKit'; 41 42 // The context is passed from EntryAbility. Ensure that the return value of this.getUIContext().getHostContext() is UIAbilityContext. 43 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 44 45 // Create a helper object for connecting to all file management servers in the system. 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. View directories. 83 In the user file access framework, **FileInfo** indicates basic information about a file or folder. You can use **listfile()** to obtain a **FileIterator** object that traverses all files (folder) of the next level or use **scanfile()** to obtain a **FileIterator** object that meets the specified conditions. 84 85 Currently, **listfile()** and **scanfile()** can be called by the **RootInfo** object to traverse the next-level files or filter the entire directory tree. In addition, **listfile()** and **scanfile()** can be called by the **FileInfo** object to traverse the next-level files or filter the specified directories. 86 87 ```ts 88 import { BusinessError } from '@kit.BasicServicesKit'; 89 import { Filter } from '@kit.CoreFileKit'; 90 91 // Start from the root directory. 92 let rootInfos = []; 93 // Obtain rootInfos by using 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"]}; // Set the filter. 98 try { 99 let fileIterator = rootInfo.listFile(); // Traverse the root directory of rootinfos[0] and return an iterator object. 100 // let fileIterator = rootInfo.scanFile(filter); // Filter device rootinfos[0] files that meet the specified conditions and return a FileIterator object. 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 // Start from the specified directory. 117 let fileInfoDir: fileAccess.FileInfo = fileInfos[0]; // fileInfoDir indicates the information about a directory. 118 let subFileInfos: Array<fileAccess.FileInfo> = []; 119 let isDone02: boolean = false; 120 let filter02: Filter = {suffix : [".txt", ".jpg", ".xlsx"]}; // Set the filter. 121 try { 122 let fileIterator = fileInfoDir.listFile(); // Traverse files in the specified directory and return an iterator object. 123 // let fileIterator = rootInfo.scanFile(filter02); // Filter the files in the specified directory and return a FileIterator object. 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. Perform operations on files or directories. 141 You can integrate APIs of the user file access framework to implement user behaviors, such as deleting, renaming, creating, and moving a file or folder. The following example shows how to create a file. For details about other APIs, see [User File Access and Management](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md). 142 143 ```ts 144 import { BusinessError } from '@kit.BasicServicesKit'; 145 146 // The local device is used as an example. 147 // Create a file. 148 // sourceUri is the URI in fileinfo of the Download directory. 149 // You need to use the obtained URI for development. 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 // Obtain fileAccessHelperAllServer by referring to the sample code of 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## Listening for Device Online/Offline Status 169 170For details about the APIs, see [User File Access and Management](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md). 171 172You can use **notify()** to observe not only the changes of directories, but also the device online/offline status. 173 174 1751. Request permissions required. 176 177 Request the ohos.permission.FILE_ACCESS_MANAGER and ohos.permission.GET_BUNDLE_INFO_PRIVILEGED permissions. For details, see [Declaring Permissions](../security/AccessToken/declare-permissions.md). 178 179 > **NOTE** 180 > 181 > The ohos.permission.FILE_ACCESS_MANAGER permission allows your application to call the user file access framework APIs. 182 > 183 > The ohos.permission.GET_BUNDLE_INFO_PRIVILEGED permission allows your application to obtain information about file management server applications supported by the system. 184 1852. Import dependent modules. 186 187 ```ts 188 import { fileAccess } from '@kit.CoreFileKit'; 189 import { fileExtensionInfo } from '@kit.CoreFileKit'; 190 ``` 191 192 The **fileAccess** module provides APIs for basic file operations, and the **fileExtensionInfo** module provides key structs for application development. 193 1943. Define the observer callback. 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. Observe devices. 207 208 To listen for the device online/offline status, pass in [DEVICES_URI](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md#constant) to **registerObserver**. To cancel the listening for the device online/offline status, pass in **DEVICES_URI** to **unregisterObserver()**. 209 210 ```ts 211 import { BusinessError } from '@kit.BasicServicesKit'; 212 import { common } from '@kit.AbilityKit'; 213 214 // Define the observer callback. 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 // The context is passed from EntryAbility. Ensure that the return value of this.getUIContext().getHostContext() is UIAbilityContext. 224 let context = this.getUIContext().getHostContext() as common.UIAbilityContext; 225 // Create a helper object for connecting to all file management servers in the system. 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 // Pass in DEVICES_URI to registerObserver() to listen for the device online/offline status. 239 async function RegisterObserver03() { 240 try { 241 // Subscribe to the device online/offline status. 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 // Pass in DEVICES_URI to unregisterObserver () to cancel the device status listening. 249 async function UnregisterObserver04() { 250 try { 251 // Unsubscribe from the device online/offline status. 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