0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HarmonyOS運動開発:ファイルプレビューの正しい実装方法を深く解析する

Posted at

鴻蒙核心技术##運動開発##Core File Kit(ファイル基本サービス)##Preview Kit(ファイルプレビュー サービス)#

前言

HarmonyOS開発において、ファイルプレビュー機能は一般的なニーズです。特にユーザーがアップロードする画像、ドキュメント、オーディオ、ビデオなどのリソースを処理する際です。しかし、ファイルプレビューの実装は常にスムーズとは限りません。特にファイル権限やプレビュー ウィンドウの管理が関わる場合です。この記事では、「適切なファイルを選んでプレビューする」というテーマを基に、HarmonyOSにおけるファイルプレビューの核心ポイントを深く解析し、実際の開発で得た経験やコツを共有し、開発者がよく陥る落とし穴を回避するお手伝いをします。

前言:ファイルプレビューの痛みと挑戦

HarmonyOSにおいて、ファイルプレビュー機能は表面上は簡単そうに見えますが、実際には多くの詳細が潜んでいます。開発者は、ファイル権限が不足していたり、プレビュー ウィンドウが正常に開かなかったり、繰り返し開いたりするなどの問題に遭遇することがよくあります。これらの問題は、ユーザー体験に影響を及ぼすだけでなく、アプリがクラッシュしたり、データが失われたりする原因にもなります。したがって、正しいファイルプレビューの実装方法を掌握することは非常に重要です。

核心要点:ファイル URI 権限の永続化

HarmonyOSにおいて、DocumentViewPickerから取得したファイル URIは、一時的な権限しか持たず、この権限は直接ファイルプレビューには使用できません。さもないと、プレビューが失敗します。したがって、ファイル URIの権限を永続化する処理を行う必要があります。

権限永続化コード解析

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

fileShare.persistPermission:これは重要な永続化メソッドで、ファイル URIの権限を一時的から永続的なものに変更し、プレビュー機能がファイルに正常にアクセスできるようにします。

uri:これはファイルのパスで、その形式が正しいことを確認する必要があります。

operationMode:ここではREAD_MODEを指定し、読み取り権限のみを付与します。これはプレビュー機能が要求する最低限の権限です。

また、persistPermissionメソッドを使用するには、アプリのconfig.jsonファイルに以下の権限を宣言する必要があります。

{
  "name": "ohos.permission.FILE_ACCESS_PERSIST"
}

ファイルのMIMEタイプを取得する

ファイルをプレビューする前に、そのMIMEタイプを明確にすることが重要です。これは、プレビュー機能の正確性にとって非常に重要です。以下はMIMEタイプを取得するためのコードの実装です。

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';
  }
}

コード解析

filePath.split('.').pop():ファイルパスからファイル拡張子を取得し、これはMIMEタイプを判断するための鍵です。

switch文:拡張子に応じて対応するMIMEタイプを返します。ここでは一般的な画像、ビデオ、オーディオ、テキスト、HTMLファイルタイプをカバーしています。

• デフォルト値:ファイルタイプが特定できない場合は、application/octet-streamを返します。これは一般的なバイナリストリームタイプです。

ファイルプレビューの実装詳細

ファイルをプレビューするための実装には、ファイルの存在確認、プレビューの可否、プレビュー パラメーターの準備、プレビュー ウィンドウの管理など、複数の手順が含まれます。以下が完整的なコードの実装です。

async previewFile(): Promise<void> {
  if (!this.selectedFilePath) {
    promptAction.showToast({ message: 'ファイルを選択してください', duration: 2000 });
    return;
  }

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

    // 1. ファイルの存在を確認する
    try {
      await fs.access(this.selectedFilePath);
    } catch {
      promptAction.showToast({ message: 'ファイルが存在しないかアクセスできません', duration: 2000 });
      return;
    }

    // 2. プレビューできるかどうかを確認する
    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: 'このファイルタイプのプレビューはサポートされていません', duration: 2000 });
      return;
    }

    // 3. プレビュー パラメーターを準備する
    const fileInfo: filePreview.PreviewInfo = {
      title: this.fileName,
      uri: uri,
      mimeType: this.getMimeType(this.selectedFilePath)
    };

    // 4. プレビュー ウィンドウの有無を確認する
    const hasDisplayed = await filePreview.hasDisplayed(uiContext);

    if (hasDisplayed) {
        // もしウィンドウが既に存在する場合は閉じる
        await filePreview.closePreview(uiContext)
    } else {
      // 新しいプレビュー ウィンドウを開く
      const displayInfo: filePreview.DisplayInfo = {
        x: 100,  // ウィンドウの開始X座標
        y: 100,  // ウィンドウの開始Y座標
        width: 800, // ウィンドウの幅
        height: 800 // ウィンドウの高さ
      };

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

    console.info('ファイルのプレビューに成功しました');
  } catch (err) {
    const error = err as BusinessError;
    console.error(`プレビューに失敗しました、エラーコード: ${error.code}, エラー情報: ${error.message}`);
    promptAction.showToast({
      message: `プレビューに失敗しました: ${error.message}`,
      duration: 2000
    });
  }
}

コード解析

• ファイルの存在を確認する:fs.accessメソッドを使用してファイル パスが有効かどうかを確認します。

• ファイルの権限を永続化する:fileShare.persistPermissionメソッドを使用して、ファイル URIに永続的な読み取り権限があることを確認します。

• プレビューできるかどうかを確認する:filePreview.canPreviewメソッドを使用して、ファイル タイプがプレビューをサポートしているかどうかを判断します。

• プレビュー パラメーターを準備する:filePreview.PreviewInfoオブジェクトを構築し、ファイルのタイトル、URI、MIMEタイプを含めます。

• プレビュー ウィンドウを管理する:filePreview.hasDisplayedを使用して、既にプレビュー ウィンドウがあるかどうかを確認します。存在する場合は、filePreview.closePreviewを使用してウィンドウを閉じます。存在しない場合は、filePreview.openPreviewを使用して新しいプレビュー ウィンドウを開きます。

总结:ファイルプレビューの正しい実装方法

HarmonyOS開発において、ファイルプレビュー機能を実装するには、ファイル権限、MIMEタイプの取得、プレビュー ウィンドウの管理など、複数の側面に注意する必要があります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?