c77fb700创建于 2025年1月16日历史提交
/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import bridge from '@arkui-x.bridge';
import { common, Want } from '@kit.AbilityKit';
import { image } from '@kit.ImageKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { FileUtil, Logger, PlatformInfo, PlatformTypeEnum } from '@ohos/utils';
import { ProfileConstants } from '../common/ProfileConstants';
import ErrorCode from '../common/ErrorCodeConstants';
import { PhotoManagerInterface } from '../interface/PhotoManagerInterface';

const TAG = '[PhotoManagerArkUIX]';

export class PhotoManagerArkUIX implements PhotoManagerInterface {
  private static instance: PhotoManagerArkUIX;
  private bridgeImpl: bridge.BridgeObject;

  private constructor() {
    this.bridgeImpl = bridge.createBridge('PhotoManager');
  }

  public static getInstance(): PhotoManagerInterface {
    if (!PhotoManagerArkUIX.instance) {
      PhotoManagerArkUIX.instance = new PhotoManagerArkUIX();
    }
    return PhotoManagerArkUIX.instance;
  }

  private routingUriForiOS(uri: string): string {
    // Intercepts everything after the keyword 'file'
    uri = uri.replace(new RegExp(`.*(${'file'})`), '$1');

    // Remove redundant escape characters
    uri = uri.replace(/\\/g, '');

    // Remove trailing redundant characters
    uri = uri.slice(0, -5);
    return uri;
  }

  public async selectPicture(): Promise<string> {
    if (PlatformInfo.getPlatform() == PlatformTypeEnum.ANDROID) {
      return new Promise((resolve: (uri: string) => void, reject: ((err: BusinessError) => void)) => {
        let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
        PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
        PhotoSelectOptions.maxSelectNumber = 1;
        let photoPicker = new photoAccessHelper.PhotoViewPicker();
        photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => {
          Logger.info(TAG,
            'PhotoViewPicker.select success, PhotoSelectResult uri: ' + JSON.stringify(PhotoSelectResult));
          let uris: Array<string> = PhotoSelectResult.photoUris;
          if (uris.length > 0) {
            resolve(uris[0]);
          } else {
            reject({
              code: ErrorCode.GET_DATA_FAILED,
              name: 'GET_DATA_FAILED',
              message: 'Maybe image selector not selecting an image'
            });
          }
        }).catch((err: BusinessError) => {
          Logger.error(TAG, `PhotoViewPicker.select failed with err: ${err.code}, ${err.message}`);
          reject(err);
        });
      });
    } else {
      return new Promise((resolve: (uri: string) => void, reject: ((err: BusinessError) => void)) => {
        try {
          const context = getContext(this) as common.UIAbilityContext;
          let uri: string = '';
          let want: Want = {
            bundleName: 'com.ohos.photos',
            abilityName: context.abilityInfo.name,
            parameters: {
              uri: '',
            }
          };
          context.startAbilityForResult(want, (err: BusinessError, data: common.AbilityResult) => {
            uri = this.routingUriForiOS(JSON.stringify(data.want?.parameters));
            this.bridgeImpl?.callMethod(
              'copyToSandbox', uri, ProfileConstants.getInstance().LOCAL_PROFILE_NAME).then(() => {
              uri = 'file://' + context.filesDir + '/' + ProfileConstants.getInstance().LOCAL_PROFILE_NAME;
              Logger.info(TAG, 'PhotoManager selectPicture uri is ' + uri);
              resolve(uri)
            }).catch((error: BusinessError) => {
              Logger.info(TAG, 'PhotoManager savePicture failed, error is ' + JSON.stringify(error));
              reject(error);
            });
          });
        } catch (error) {
          let err: BusinessError = error as BusinessError;
          Logger.error(TAG, `PhotoManager startAbilityForResult failed with err: ${err.code}, ${err.message}`);
          reject(err)
        }
      });
    }
  }

  public async savePicture(uri: string): Promise<void> {
    if (PlatformInfo.getPlatform() == PlatformTypeEnum.ANDROID) {
      return new Promise((resolve: () => void, reject: ((err: BusinessError) => void)) => {
        //delete string 'file://' from uri
        let imaUri: string = uri.slice(7);
        FileUtil.copyFile(imaUri, ProfileConstants.getInstance().LOCAL_PROFILE_PATH);
        let imageSource: image.ImageSource = image.createImageSource(ProfileConstants.getInstance().LOCAL_PROFILE_PATH);
        imageSource.createPixelMap((err, pixelMap) => {
          if (err) {
            Logger.error(TAG, `createPixelMap error: ${err}`);
            reject(err);
          } else {
            AppStorage.setOrCreate('profilePixelMap', pixelMap);
            resolve();
          }
        });
      });
    } else {
      return new Promise((resolve: () => void, reject: ((err: BusinessError) => void)) => {
        let imageSource: image.ImageSource = image.createImageSource(ProfileConstants.getInstance().LOCAL_PROFILE_PATH);
        imageSource.createPixelMap((err, pixelMap) => {
          if (err) {
            Logger.error(TAG, `createPixelMap error: ${err}`);
            reject(err);
          } else {
            AppStorage.setOrCreate('profilePixelMap', pixelMap);
            resolve();
          }
        });
      });
    }
  }
}