DEV Community

zhonghua
zhonghua

Posted on • Edited on

Practical HarmonyOS Sports Development: In-Depth Analysis of Correct File Preview Practices

Practical HarmonyOS Sports Development: In-Depth Analysis of Correct File Preview Practices

Foreword

In HarmonyOS development, the file preview feature is a common requirement, especially when dealing with user-uploaded resources such as images, documents, audio, or video. However, implementing file preview is not always straightforward, particularly when it comes to file permissions and managing the preview window. This article will delve into the core aspects of file preview in HarmonyOS, focusing on the theme of "choosing the right file for preview." It will share practical tips and tricks to help developers avoid common pitfalls.

I. Pain Points and Challenges of File Preview

In HarmonyOS, file preview may seem simple, but it hides many details. Developers often encounter issues such as insufficient file permissions, preview windows failing to open properly, or opening repeatedly. These issues not only affect user experience but can also lead to app crashes or data loss. Therefore, mastering the correct implementation of file preview is crucial.

II. Core Points: Persisting File URI Permissions

In HarmonyOS, the file URI obtained through DocumentViewPicker only has temporary permissions, which cannot be used directly for file preview, as it will result in preview failure. Therefore, we need to handle the persistence of file URI permissions.

Code Analysis for Persisting Permissions

await fileShare.persistPermission([
  {
    uri: uri,
    operationMode: fileShare.OperationMode.READ_MODE
  }
]);
Enter fullscreen mode Exit fullscreen mode
  • fileShare.persistPermission: This is the key method for persisting permissions. It changes the file URI's permissions from temporary to persistent, ensuring that the preview function can access the file properly.

  • uri: This is the file path, which must be in the correct format.

  • operationMode: Specified as READ_MODE, indicating that only read permission is granted, which is the minimum required for preview functionality.

Additionally, to use the persistPermission method, you need to declare the following permission in the app's config.json file:

{
  "name": "ohos.permission.FILE_ACCESS_PERSIST"
}
Enter fullscreen mode Exit fullscreen mode

III. Obtaining the File MIME Type

Before previewing a file, it is essential to determine the file's MIME type, which is crucial for the correctness of the preview function. Below is the code implementation for obtaining the MIME type:

private getMimeType(filePath: string): string {
  const extension = filePath.split('.').pop()?.toLowerCase() || '';

  switch (extension) {
    case 'jpg':
    case 'jpeg':
      return 'image/jpeg';
    case 'png':
      return 'image/png';
    case 'gif':
      return 'image/gif';
    case 'bmp':
      return 'image/bmp';
    case 'webp':
      return 'image/webp';

    case 'mp4':
      return 'video/mp4';
    case 'mov':
      return 'video/quicktime';
    case 'avi':
      return 'video/x-msvideo';

    case 'mp3':
      return 'audio/mpeg';
    case 'wav':
      return 'audio/wav';
    case 'ogg':
      return 'audio/ogg';

    case 'txt':
    case 'log':
      return 'text/plain';

    case 'html':
    case 'htm':
      return 'text/html';

    default:
      return 'application/octet-stream';
  }
}
Enter fullscreen mode Exit fullscreen mode

Code Analysis

  • filePath.split('.').pop(): Obtain the file extension from the file path, which is key to determining the MIME type.

  • switch statement: Returns the corresponding MIME type based on the extension. This covers common image, video, audio, text, and HTML file types.

  • Default value: If the file type cannot be identified, it returns application/octet-stream, a generic binary stream type.

IV. Implementation Details of File Preview

Implementing file preview involves several steps, including checking if the file exists, whether it can be previewed, preparing preview parameters, and managing the preview window. Below is the complete code implementation:

async previewFile(): Promise<void> {
  if (!this.selectedFilePath) {
    promptAction.showToast({ message: 'Please select a file first', duration: 2000 });
    return;
  }

  try {
    let uiContext = this.getUIContext().getHostContext() as Context;

    // 1. Check if the file exists
    try {
      await fs.access(this.selectedFilePath);
    } catch {
      promptAction.showToast({ message: 'File does not exist or is not accessible', duration: 2000 });
      return;
    }

    // 2. Check if it can be previewed
    const uri = this.selectedFilePath.startsWith('file://') ?
      this.selectedFilePath :
      `file://${this.selectedFilePath}`;

    await fileShare.persistPermission([
      {
        uri: uri,
        operationMode: fileShare.OperationMode.READ_MODE
      }
    ]);

    const canPreview = await filePreview.canPreview(uiContext, uri);
    if (!canPreview) {
      promptAction.showToast({ message: 'This file type is not supported for preview', duration: 2000 });
      return;
    }

    // 3. Prepare preview parameters
    const fileInfo: filePreview.PreviewInfo = {
      title: this.fileName,
      uri: uri,
      mimeType: this.getMimeType(this.selectedFilePath)
    };

    // 4. Check if a preview window already exists
    const hasDisplayed = await filePreview.hasDisplayed(uiContext);

    if (hasDisplayed) {
        // Close the existing window
        await filePreview.closePreview(uiContext)
    } else {
      // Open a new preview window
      const displayInfo: filePreview.DisplayInfo = {
        x: 100,  // Window starting x-coordinate
        y: 100,  // Window starting y-coordinate
        width: 800, // Window width
        height: 800 // Window height
      };

      await filePreview.openPreview(uiContext, fileInfo, displayInfo);
    }

    console.info('File preview successful');
  } catch (err) {
    const error = err as BusinessError;
    console.error(`Preview failed, error code: ${error.code}, error message: ${error.message}`);
    promptAction.showToast({
      message: `Preview failed: ${error.message}`,
      duration: 2000
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

Code Analysis

  • Check if the file exists: Use the fs.access method to check if the file path is valid.

  • Persist file permissions: Use the fileShare.persistPermission method to ensure the file URI has persistent read permissions.

  • Check if it can be previewed: Call the filePreview.canPreview method to determine if the file type supports preview.

  • Prepare preview parameters: Construct the filePreview.PreviewInfo object, containing the file title, URI, and MIME type.

  • Manage the preview window: Use filePreview.hasDisplayed to check if a preview window already exists. If it does, call filePreview.closePreview to close the window; if not, call filePreview.openPreview to open a new preview window.

V. Summary: The Correct Way to Implement File Preview

In HarmonyOS development, implementing file preview requires attention to multiple aspects, including file permissions, obtaining MIME types, and managing the preview window.

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.