DEV Community

SameX
SameX

Posted on

HarmonyOS Next in Practice: Building an All-Purpose File Manager Application

This article aims to deeply explore the technical details of the Huawei HarmonyOS Next system (up to API 12 as of now) in developing multilingual e-commerce platforms, and is summarized based on actual development practices. It mainly serves as a vehicle for technical sharing and communication. Mistakes and omissions are inevitable. Colleagues are welcome to put forward valuable opinions and questions so that we can make progress together. This article is original content, and any form of reprint must indicate the source and the original author.
In today's digital age, file managers have become an important tool for people to manage local and media files. Today, we will explore in depth how to develop a powerful file manager application based on the HarmonyOS Next system, covering the whole process from basic architecture design to the implementation of core functions, allowing you to fully master the application development skills of HarmonyOS Next in the field of file management.

I. Application Architecture Design: Application of the MVC Architecture

(I) Overview of the MVC Architecture

The MVC (Model-View-Controller) architecture is a classic software design pattern that divides an application into three main parts: the Model, the View, and the Controller. In our file manager application, the application of this architecture will make the code structure clearer, easier to maintain and extend.

(II) The Model Layer

The Model layer is responsible for handling the storage, retrieval, and update of data. In the file manager application, it mainly involves operations on files and directories, such as file reading, writing, deletion, copying, and moving. We will use the system APIs of HarmonyOS Next to implement these operations. For example, we will use the fileIo module for file read and write operations and the directoryIo module to handle directory-related operations.

(III) The View Layer

The View layer is responsible for presenting the user interface, displaying lists of files and directories, and providing interactive elements such as operation buttons. We will use the ArkUI framework to build the user interface. Through a componentized approach, such as using the List component to display the file list and the Button component to implement the operation buttons, we ensure that the interface is simple, beautiful, and easy to operate.

(IV) The Controller Layer

The Controller layer acts as a bridge between the Model and the View. It is responsible for handling user input events and calling the corresponding methods of the Model layer according to the business logic. For example, when the user clicks the file upload button, the Controller will obtain the file path selected by the user and call the upload method of the Model layer to upload the file to the specified location.

(V) Using the System Picker to Implement File Selection and Saving

To follow the security principles of HarmonyOS Next and avoid directly accessing the user's file system, we will widely use the System Picker to implement file selection and saving functions. When the user needs to open a file, the file selector (FilePicker) is used to let the user select the file, and the application will perform subsequent operations after obtaining the file path selected by the user. Similarly, when saving a file, the save path selector provided by the system is used to ensure that the file is saved to the correct location.

II. Permission Application and Management

(I) Review of the Permission Mechanism

In the HarmonyOS Next system, permissions are divided into two types: system_grant (system authorization) and user_grant (user authorization). System authorization permissions are automatically granted when the application is installed, while user authorization permissions need to be requested from the user when the application is running.

(II) Permissions Required by the Application and the Application Method

  1. Read File Permission (user_grant) When the application needs to read the user's local files, it needs to apply for the ohos.permission.READ_EXTERNAL_STORAGE permission (assuming it is the permission to read external storage files, which is actually defined by the system). When the application starts, it requests authorization from the user through the requestPermissionsFromUser() interface. For example:
import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
const readPermission: Permissions = 'ohos.permission.READ_EXTERNAL_STORAGE';
async function checkReadPermissionGrant(): Promise<abilityAccessCtrl.GrantStatus> {
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  let grantStatus: abilityAccessCtrl.GrantStatus = abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;
  // Get the accessTokenID of the application
  let tokenId: number = 0;
  try {
    let bundleInfo: bundleManager.BundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
    tokenId = appInfo.accessTokenId;
  } catch (error) {
    const err: BusinessError = error as BusinessError;
    console.error(`Failed to get bundle info for self. Code is ${err.code}, message is ${err.message}`);
  }
  // Check whether the application has been granted the permission
  try:
    grantStatus = await atManager.checkAccessToken(tokenId, readPermission);
  } catch (error) {
    const err: BusinessError = error as BusinessError;
    console.error(`Failed to check access token. Code is £{"name": "ohos.permission.READ_MEDIA_FILES",
"reason": "$string:reason_for_read_media_files",
"usedScene": {
"abilities": [
"MainAbility"
],
"when":"inuse"
}
}
Enter fullscreen mode Exit fullscreen mode

At the same time, when the application is running, according to the user authorization process, request authorization from the user through the requestPermissionsFromUser() interface (if this permission belongs to the user_grant type), and handle the user's authorization result.

III. Implementation of Core Functions

(I) File Operation Functions

  1. File Reading Use the open() method of the fileIo module to open the file, obtain the file descriptor, and then read the file content through the read() method. For example:
import { fileIo } from '@kit.CoreFileKit';
async function readFile(filePath: string): Promise<string> {
  let file = await fileIo.open(filePath, fileIo.OpenMode.READ_ONLY);
  let buffer = new ArrayBuffer(fileIo.statSync(filePath).size);
  await fileIo.read(file.fd, buffer);
  await fileIo.close(file.fd);
  return new TextDecoder().decode(buffer);
}
Enter fullscreen mode Exit fullscreen mode
  1. File Writing Open the file in write mode using the open() method of the fileIo module, and write the data into the file using the write() method. For example:
async function writeFile(filePath: string, content: string): Promise<void> {
  let file = await fileIo.open(filePath, fileIo.OpenMode.WRITE_ONLY | fileIo.OpenMode.CREATE);
  await fileIo.write(file.fd, new TextEncoder().encode(content));
  await fileIo.close(file.fd);
}
Enter fullscreen mode Exit fullscreen mode
  1. File Deletion, Copying, and Moving Use the relevant methods of the fileIo and directoryIo modules to implement file deletion, copying, and moving operations. For example, file deletion can use the unlink() method, file copying can first read the content of the source file and then write it to the target file, and file moving can be achieved by first copying and then deleting the source file (atomic operations need to be considered to ensure data integrity). ### (II) Network Operation Functions
  2. File Upload Use the http or https module (assuming HarmonyOS Next provides similar network request modules) to implement the file upload function. First, create an HttpRequest object, set the request method to POST, upload address and other parameters, and then send the file content as the request body. For example:
import { http } from '@kit.NetworkKit';
async function uploadFile(filePath: string, uploadUrl: string): Promise<void> {
  let fileContent = await readFile(filePath);
  let request = http.createHttpRequest();
  request.method = 'POST';
  request.url = uploadUrl;
  request.headers = { 'Content-Type': 'application/octet-stream' };
  request.requestBody = new Uint8Array(new TextEncoder().encode(fileContent));
  try:
    await request.send();
    if (request.responseCode === 200) {
      console.log('File upload successful.');
    } else {
      console.error('File upload failed, error code: ', request.responseCode);
    }
  } catch (error) {
    console.error('File upload process error: ', error);
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. File Download Similarly, use the network request module to implement the file download function. Create an HttpRequest object, set the request method to GET, download address and other parameters, and then receive the file content returned by the server and save it to local. For example:
async function downloadFile(downloadUrl: string, savePath: string): Promise<void> {
  let request = http.createHttpRequest();
  request.method = 'GET';
  request.url = downloadUrl;
  try:
    await request.send();
    if (request.responseCode === 200) {
      await writeFile(savePath, request.responseData.toString());
      console.log('File download successful, save path: ', savePath);
    } else:
      console.error('File download failed, error code: ', request.responseCode);
    }
  } catch (error) {
    console.error('File download process error: ', error);
  }
}
Enter fullscreen mode Exit fullscreen mode

(III) Sharing Function

  1. Sharing Method Selection Provide multiple sharing methods, such as sharing files via email, SMS, social media, etc. After the user selects a file to share, a sharing method selection interface is popped up to let the user select an appropriate sharing channel.
  2. Sharing Implementation According to the sharing method selected by the user, use the corresponding system API to implement the sharing operation. For example, when sharing a file via email, use the sharing interface of the email client to add the file as an attachment to the email. Assuming HarmonyOS Next provides the share module to implement the sharing function, here is a simple example of sharing via email (the actual interface may be different):
import { share } from '@kit.ShareKit';
async function shareFileByEmail(filePath: string, recipient: £{"name": "ohos.permission.READ_MEDIA_FILES",
"reason": "$string:reason_for_read_media_files",
"usedScene": {
"abilities": [
"MainAbility"
],
"when":"inuse"
}
}
try:
    await share.share(shareData, { recipients: [recipient] });
    console.log('File shared via email successfully.');
  } catch (error) {
    console.error('File sharing failed: ', error);
  }
}
Enter fullscreen mode Exit fullscreen mode

IV. Summary and Outlook

Through this practical project, we have successfully built a file manager application based on the HarmonyOS Next system, covering core functions such as file browsing, management, upload, download, and sharing. During the development process, we have deeply applied key technologies such as the application sandbox and permission mechanism of HarmonyOS Next, system authorization and user authorization, restricted open permissions and ACL application, and System Picker, ensuring the security, stability, and functionality of the application.
Looking ahead, with the continuous development and improvement of the HarmonyOS Next system, we can further optimize the performance of the file manager, such as improving the efficiency of large file operations and enhancing the file search function. At the same time, combined with distributed technology, we can achieve cross-device file management and sharing, providing users with a more convenient and efficient file management experience. We hope that this article can provide useful references and inspirations for HarmonyOS Next developers and stimulate the development of more innovative applications.

Top comments (0)