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