HarmonyOS開発におけるデータ保存と写真選択の効率的な実装

HarmonyOSアプリケーション開発において、頻繁に使用される機能を効率的に実装するためのユーティリティクラスを紹介します。本記事では、シンプルなキー・バリュー形式のデータを永続化するための「データストレージユーティリティ」と、ユーザーが写真を選択するための「画像ピッカーユーティリティ」の2つの実装例を解説します。

1. データストレージユーティリティ

アプリケーション内で設定情報や一時的なデータを保存・取得する際に、HarmonyOSのPreferences APIを利用します。以下のユーティリティクラスは、この操作を簡素化します。

DataStorageUtil.ts

import common from '@ohos.app.ability.common';
import { BusinessError } from '@ohos.base';
import Logger from '.../utils/Logger';

const TAG = '[DataStorageUtil]';

export class DataStorageUtil {
  private dataStore: Preferences | null = null;

  constructor(context: common.UIAbilityContext) {
    try {
      this.dataStore = preferencesHelper.getPreferences(context, 'app_data');
    } catch (err) {
      Logger.error(TAG, `Failed to initialize preferences. Code: ${(err as BusinessError).code}`);
    }
  }

  /**
   * データを保存します。
   * @param storageKey キー
   * @param dataValue 値
   * @returns 保存成功時はtrue、失敗時はfalse
   */
  storeValue(storageKey: string, dataValue: string): boolean {
    if (!this.dataStore) {
      Logger.error(TAG, 'Preferences is not initialized.');
      return false;
    }
    try {
      this.dataStore.putSync(storageKey, dataValue);
      this.dataStore.flush();
      return true;
    } catch (err) {
      const code = (err as BusinessError).code;
      const message = (err as BusinessError).message;
      Logger.error(TAG, `Failed to store data. Key: ${storageKey}. Code: ${code}, message: ${message}`);
      return false;
    }
  }

  /**
   * データを取得します。
   * @param storageKey キー
   * @returns 値。存在しない場合はnull
   */
  retrieveValue(storageKey: string): string | null {
    if (!this.dataStore) {
      Logger.error(TAG, 'Preferences is not initialized.');
      return null;
    }
    try {
      const val = this.dataStore.getSync(storageKey, null) as string;
      Logger.info(TAG, `Succeeded in retrieving value for key: ${storageKey}. Value: ${val}`);
      return val;
    } catch (err) {
      const code = (err as BusinessError).code;
      const message = (err as BusinessError).message;
      Logger.error(TAG, `Failed to retrieve data. Key: ${storageKey}. Code: ${code}, message: ${message}`);
      return null;
    }
  }
}

使用例: DataStoragePage.ets

import Logger from '.../utils/Logger';
import common from '@ohos.app.ability.common';
import { BusinessError } from '@ohos.base';
import { DataStorageUtil } from '.../utils/DataStorageUtil';
import { isBlank } from '.../utils/StringUtil';

const TAG = '[DataStoragePage]';

@Entry
@Component
struct DataStoragePage {
  @State displayText: string = 'Hello World';
  private context = getContext(this) as common.UIAbilityContext;
  dataStorage: DataStorageUtil = new DataStorageUtil(this.context);

  onPageShow(): void {
    try {
      const result = this.dataStorage.retrieveValue("user_setting");
      this.displayText = isBlank(result) ? 'データがありません' : result;
      Logger.info(TAG, "displayText: " + this.displayText);
    } catch (err) {
      const code = (err as BusinessError).code;
      const message = (err as BusinessError).message;
      console.error(`Failed to access storage. Code:${code}, message:${message}`);
    }
  }

  build() {
    Row() {
      Column({ space: 12 }) {
        Text(this.displayText)

        Button('保存データ').onClick(() => {
          const success = this.dataStorage.storeValue("user_setting", "こんにちは、HarmonyOS!");
          Logger.info(TAG, "storeValue result: " + success);
        })

        Button('取得データ').onClick(() => {
          const result = this.dataStorage.retrieveValue("user_setting");
          this.displayText = result || 'データがありません';
          Logger.info(TAG, "retrieveValue result: " + this.displayText);
        })
      }
      .width('100%')
    }
    .height('100%')
  }
}

2. 画像ピッカーユーティリティ

HarmonyOSアプリでは、ユーザーが端末のギャラリーから写真を選択する機能がよく使われます。以下のユーティリティは、この操作をカプセル化し、開発を簡素化します。

ImagePickerUtil.ts

import picker from '@ohos.file.picker';
import Logger from '.../utils/Logger';
import { BusinessError } from '@ohos.base';

const TAG = '[ImagePickerUtil]';

/**
 * ギャラリーから画像のパスを選択します。
 * @param callback 選択結果を返すコールバック関数
 */
export function selectImageFromGallery(callback: (error: BusinessError | null, uri?: string) => void) {
  const imagePickerConfig = new picker.PhotoSelectOptions();
  imagePickerConfig.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE; // 画像のみを選択
  imagePickerConfig.maxSelectNumber = 1; // 1枚のみ選択

  const galleryPicker = new picker.PhotoViewPicker();
  galleryPicker.select(imagePickerConfig).then((photoSelectResult) => {
    const selectedImageUris = photoSelectResult.photoUris;
    if (selectedImageUris && selectedImageUris.length > 0) {
      const filePath = selectedImageUris[0];
      Logger.info(TAG, `Selected image path: ${filePath}`);
      callback(null, filePath);
    } else {
      Logger.info(TAG, 'No image selected.');
      callback(null, undefined);
    }
  }).catch((err: BusinessError) => {
    Logger.error(TAG, `Failed to open photo picker. Code: ${err.code}, message: ${err.message}`);
    callback(err, undefined);
  });
}

使用例: ImagePickerPage.ets

import picker from '@ohos.file.picker';
import Logger from '.../utils/Logger';
import { selectImageFromGallery } from '.../utils/ImagePickerUtil';
import { BusinessError } from '@ohos.base';

const TAG = '[ImagePickerPage]';

@Entry
@Component
struct ImagePickerPage {
  @State selectedImageUri: string = '';
  @State displayMessage: string = 'ギャラリーから写真を選択してください';

  build() {
    Row() {
      Column() {
        Button('写真を選択')
          .margin(10)
          .onClick(() => {
            selectImageFromGallery((err: BusinessError | null, filePath?: string) => {
              if (err) {
                Logger.error(TAG, "Image selection failed: " + err.message);
                this.displayMessage = '選択に失敗しました';
              } else if (filePath) {
                this.selectedImageUri = filePath;
                this.displayMessage = '写真が選択されました';
                Logger.info(TAG, "Selected image URI: " + filePath);
              } else {
                this.displayMessage = '写真が選択されませんでした';
              }
            });
          })

        Image(this.selectedImageUri)
          .alt($r('app.media.icon'))
          .width(150)
          .height(150)
      }
      .width('100%')
    }
    .height('100%')
  }
}

タグ: HarmonyOS ArkTS Preferences PhotoViewPicker データストレージ

7月13日 21:14 投稿