1# Developing a File Manager Application (for System Applications Only) 2 3OpenHarmony is prebuilt with the **FileManager** application. You can also develop your own file manager application as required. 4 5## How to Develop 6For 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). 7 81. Apply for permissions required.<br> 9 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). 10 11 > **NOTE** 12 > 13 > The ohos.permission.FILE_ACCESS_MANAGER permission allows your application to call the user file access framework APIs. 14 > 15 > The ohos.permission.GET_BUNDLE_INFO_PRIVILEGED permission allows your application to obtain information about file management server applications supported by the system. 16 172. Import dependent modules. 18 19 ```ts 20 import { fileAccess } from '@kit.CoreFileKit'; 21 import { fileExtensionInfo } from '@kit.CoreFileKit'; 22 ``` 23 24 The **fileAccess** module provides APIs for basic file operations, and the **fileExtensionInfo** module provides key structs for application development. 25 263. Query device information.<br> 27 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. 28 29 In the user file access framework, **RootInfo** indicates the attribute information of a device. For example, obtain **RootInfo** of all devices. 30 31 ```ts 32 import { common } from '@kit.AbilityKit'; 33 import { BusinessError } from '@kit.BasicServicesKit'; 34 import { Filter } from '@kit.CoreFileKit'; 35 36 // Obtain the application context. 37 let context = getContext(this) as common.UIAbilityContext; 38 39 // Create a helper object for connecting to all file management servers in the system. 40 let fileAccessHelperAllServer: fileAccess.FileAccessHelper; 41 function createFileAccessHelper(): void { 42 try { // this.context is the context passed from EntryAbility. 43 fileAccessHelperAllServer = fileAccess.createFileAccessHelper(context); 44 if (!fileAccessHelperAllServer) { 45 console.error("createFileAccessHelper interface returns an undefined object"); 46 } 47 } catch (err) { 48 let error: BusinessError = err as BusinessError; 49 console.error("createFileAccessHelper failed, errCode:" + error.code + ", errMessage:" + error.message); 50 } 51 } 52 let rootInfos: Array<fileAccess.RootInfo> = []; 53 async function getRoots(): Promise<void>{ 54 let rootIterator: fileAccess.RootIterator; 55 let isDone: boolean = false; 56 try { 57 rootIterator = await fileAccessHelperAllServer.getRoots(); 58 if (!rootIterator) { 59 console.error("getRoots interface returns an undefined object"); 60 return; 61 } 62 while (!isDone) { 63 let result = rootIterator.next(); 64 console.info("next result = " + JSON.stringify(result)); 65 isDone = result.done; 66 if (!isDone) 67 rootInfos.push(result.value); 68 } 69 } catch (err) { 70 let error: BusinessError = err as BusinessError; 71 console.error("getRoots failed, errCode:" + error.code + ", errMessage:" + error.message); 72 } 73 } 74 ``` 75 764. View directories. 77 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. 78 79 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. 80 81 ```ts 82 import { BusinessError } from '@kit.BasicServicesKit'; 83 import { Filter } from '@kit.CoreFileKit'; 84 85 // Start from the root directory. 86 let rootInfos = []; 87 // Obtain rootInfos by using getRoots(). 88 let rootInfo: fileAccess.RootInfo = rootInfos[0]; 89 let fileInfos: Array<fileAccess.FileInfo> = []; 90 let isDone: boolean = false; 91 let filter: Filter = {suffix : [".txt", ".jpg", ".xlsx"]}; // Set the filter. 92 try { 93 let fileIterator = rootInfo.listFile(); // Traverse the root directory of rootinfos[0] and return an iterator object. 94 // let fileIterator = rootInfo.scanFile(filter); // Filter device rootinfos[0] files that meet the specified conditions and return a FileIterator object. 95 if (!fileIterator) { 96 console.error("listFile interface returns an undefined object"); 97 } 98 while (!isDone) { 99 let result = fileIterator.next(); 100 console.info("next result = " + JSON.stringify(result)); 101 isDone = result.done; 102 if (!isDone) 103 fileInfos.push(result.value); 104 } 105 } catch (err) { 106 let error: BusinessError = err as BusinessError; 107 console.error("listFile failed, errCode:" + error.code + ", errMessage:" + error.message); 108 } 109 110 // Start from the specified directory. 111 let fileInfoDir: fileAccess.FileInfo = fileInfos[0]; // fileInfoDir indicates the information about a directory. 112 let subFileInfos: Array<fileAccess.FileInfo> = []; 113 let isDone02: boolean = false; 114 let filter02: Filter = {suffix : [".txt", ".jpg", ".xlsx"]}; // Set the filter. 115 try { 116 let fileIterator = fileInfoDir.listFile(); // Traverse files in the specified directory and return an iterator object. 117 // let fileIterator = rootInfo.scanFile(filter02); // Filter the files in the specified directory and return a FileIterator object. 118 if (!fileIterator) { 119 console.error("listFile interface returns an undefined object"); 120 } 121 while (!isDone02) { 122 let result = fileIterator.next(); 123 console.info("next result = " + JSON.stringify(result)); 124 isDone02 = result.done; 125 if (!isDone02) 126 subFileInfos.push(result.value); 127 } 128 } catch (err) { 129 let error: BusinessError = err as BusinessError; 130 console.error("listFile failed, errCode:" + error.code + ", errMessage:" + error.message); 131 } 132 ``` 133 1345. Perform operations on files or directories. 135 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). 136 137 ```ts 138 import { BusinessError } from '@kit.BasicServicesKit'; 139 140 // The local device is used as an example. 141 // Create a file. 142 // sourceUri is the URI in fileinfo of the Download directory. 143 // You need to use the obtained URI for development. 144 async function creatFile(): Promise<void> { 145 let sourceUri: string = "file://docs/storage/Users/currentUser/Download"; 146 let displayName: string = "file1"; 147 let fileUri: string = ''; 148 try { 149 // Obtain fileAccessHelperAllServer by referring to the sample code of fileAccess.createFileAccessHelper. 150 fileUri = await fileAccessHelperAllServer.createFile(sourceUri, displayName); 151 if (!fileUri) { 152 console.error("createFile return undefined object"); 153 } 154 console.info("createFile sucess, fileUri: " + JSON.stringify(fileUri)); 155 } catch (err) { 156 let error: BusinessError = err as BusinessError; 157 console.error("createFile failed, errCode:" + error.code + ", errMessage:" + error.message); 158 }; 159 } 160 ``` 161 162## Listening for Device Online/Offline Status 163 164For details about the APIs, see [User File Access and Management](../reference/apis-core-file-kit/js-apis-fileAccess-sys.md). 165 166You can use **notify()** to observe not only the changes of directories, but also the device online/offline status. 167 168 1691. Request permissions required.<br> 170 171 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). 172 173 > **NOTE** 174 > 175 > The ohos.permission.FILE_ACCESS_MANAGER permission allows your application to call the user file access framework APIs. 176 > 177 > The ohos.permission.GET_BUNDLE_INFO_PRIVILEGED permission allows your application to obtain information about file management server applications supported by the system. 178 1792. Import dependent modules. 180 181 ```ts 182 import { fileAccess } from '@kit.CoreFileKit'; 183 import { fileExtensionInfo } from '@kit.CoreFileKit'; 184 ``` 185 186 The **fileAccess** module provides APIs for basic file operations, and the **fileExtensionInfo** module provides key structs for application development. 187 1883. Define the observer callback. 189 190 ```ts 191 const callbackDir1 = (NotifyMessageDir: fileAccess.NotifyMessage) => { 192 if (NotifyMessageDir != undefined) { 193 console.log('NotifyType: ' + NotifyMessageDir.type + 'NotifyUri:' + NotifyMessageDir.uris[0]); 194 } else { 195 console.error("NotifyMessageDir is undefined"); 196 } 197 } 198 ``` 199 2004. Observe devices. 201 202 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()**. 203 204 ```ts 205 import { BusinessError } from '@kit.BasicServicesKit'; 206 import { common } from '@kit.AbilityKit'; 207 208 // Define the observer callback. 209 const callbackDir1 = (NotifyMessageDir: fileAccess.NotifyMessage) => { 210 if (NotifyMessageDir != undefined) { 211 console.log('NotifyType: ' + NotifyMessageDir.type + 'NotifyUri:' + NotifyMessageDir.uris[0]); 212 } else { 213 console.error("NotifyMessageDir is undefined"); 214 } 215 } 216 217 let context = getContext(this) as common.UIAbilityContext; 218 // Create a helper object for connecting to all file management servers in the system. 219 let fileAccessHelperAllServer: fileAccess.FileAccessHelper; 220 function createFileAccessHelper(): void { 221 try { // this.context is the context passed from EntryAbility. 222 fileAccessHelperAllServer = fileAccess.createFileAccessHelper(context); 223 if (!fileAccessHelperAllServer) { 224 console.error("createFileAccessHelper interface returns an undefined object"); 225 } 226 } catch (err) { 227 let error: BusinessError = err as BusinessError; 228 console.error("createFileAccessHelper failed, errCode:" + error.code + ", errMessage:" + error.message); 229 } 230 } 231 // Pass in DEVICES_URI to registerObserver() to listen for the device online/offline status. 232 async function UnregisterObserver03() { 233 try { 234 // Listen for the device online/offline status. 235 fileAccessHelperAllServer.registerObserver(fileAccess.DEVICES_URI, true, callbackDir1); 236 } catch (err) { 237 let error: BusinessError = err as BusinessError; 238 console.error("unregisterObserver failed, errCode:" + error.code + ", errMessage:" + error.message); 239 } 240 } 241 // Pass in DEVICES_URI to unregisterObserver () to cancel the device status listening. 242 async function UnregisterObserver04() { 243 try { 244 // Unsubscribe from the device online/offline status. 245 fileAccessHelperAllServer.unregisterObserver(fileAccess.DEVICES_URI, callbackDir1); 246 } catch (err) { 247 let error: BusinessError = err as BusinessError; 248 console.error("unregisterObserver failed, errCode:" + error.code + ", errMessage:" + error.message); 249 } 250 } 251 ``` 252