鸿蒙中打开相机相册

发布于:2025-03-05 ⋅ 阅读:(118) ⋅ 点赞:(0)

1。module.json5中配置相应的权限

    requestPermissions: [
      {
        "name": "ohos.permission.CAMERA",
        "reason": "$string:permission_reason_camera",
        "usedScene": {
          "abilities": [
            "EntryAbility"
          ],
          "when": "inuse"
        }
      },
      {
        "name": 'ohos.permission.READ_MEDIA',
        "reason":"$string:permission_reason_IMG",
        "usedScene": {}

      }
    ],

2.src/main/resources/base/element/string.json配置提示说明

    {
      "name": "permission_reason_camera",
      "value": "Used for scanning barcodes"
    },
    {
      "name": "permission_reason_IMG",
      "value": "用于获取图库信息"
    }

3.ui部分

import { PhotoClass } from './utils/PhotoClass';

@Entry
@Component
struct MyComponent {
  build() {
    Column() {
      Button('相机')
        .onClick(async () => {
          const takePicture = await PhotoClass.requestCameraPermission() as string
          if (takePicture) {
            console.log("拍照成功,URI: ", takePicture); // 打印成功情况
          } else {
            console.error("拍照失败,没有返回的图片 URI");
          }
        })
      Button('相册').onClick(async () => {
        try {
          const takePicture = await PhotoClass.photoAlbum(getContext()); // 使用 await 获取相册返回的结果
          console.log("访问相册成功,URI: ", takePicture); // 打印成功情况
        } catch (error) {
          console.error("访问相册过程中发生错误: ", error);
        }
      })
    }
  }
}

4.添加相应工具

  4-1:PhotoClass

import { camera, cameraPicker } from "@kit.CameraKit"
import { abilityAccessCtrl, common, Permissions } from "@kit.AbilityKit"
import { BusinessError } from "@kit.BasicServicesKit"
import { CustomDialogExampleTwo } from "./PhotoAuthorizationDialog";
import { permission } from "./Permission";

export class PhotoClass {
  private static dialogControllerTwo: CustomDialogController | null = new CustomDialogController({
    builder: CustomDialogExampleTwo(),
    onWillDismiss: (dismissDialogAction: DismissDialogAction) => {
      console.info("reason=" + JSON.stringify(dismissDialogAction.reason));
      console.log("dialog onWillDismiss");
      if (dismissDialogAction.reason === DismissReason.PRESS_BACK ||
        dismissDialogAction.reason === DismissReason.TOUCH_OUTSIDE) {
        dismissDialogAction.dismiss();
      }
    },
    offset: { dx: 0, dy: -25 }
  });
  private static PermissionsData: Permissions[] = ['ohos.permission.READ_MEDIA'];
  private static context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;

  public static async startCameraPicker(context: Context): Promise<string | undefined> {
    try {
      const pickerProfile: cameraPicker.PickerProfile = {
        cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
      };
      const pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(context,
        [cameraPicker.PickerMediaType.PHOTO, cameraPicker.PickerMediaType.VIDEO],
        pickerProfile
      );
      console.log("The picker result is: " + JSON.stringify(pickerResult));
      if (pickerResult.resultCode === 0) {
        const takePicture = pickerResult.resultUri;
        context.eventHub.emit("updateImage", pickerResult.resultUri);
        return takePicture
      }
    } catch (error) {
      const err = error as BusinessError;
      console.error(`The pick call failed. Error code: ${err.code}`);
      return undefined
    }
    return undefined
  }

  public static async photoAlbum(context: Context): Promise<string> {
    let url: string = '';

    const isAccess = await permission.checkAccess(PhotoClass.PermissionsData[0]);
    if (isAccess) {
      url = await permission.updateAvatar();
    } else {
      url = await permission.reqPermissionsFromUser(PhotoClass.PermissionsData, PhotoClass.context);
    }

    return url;
  }

  public static async reqPermissionsFromUser(): Promise<number[]> {
    const context = getContext() as common.UIAbilityContext;
    const atManager = abilityAccessCtrl.createAtManager();
    const grantStatus = await atManager.requestPermissionsFromUser(context, ['ohos.permission.CAMERA']);
    return grantStatus.authResults;
  }

  public static async requestCameraPermission(): Promise<string | undefined> {
    const grantStatus = await PhotoClass.reqPermissionsFromUser();
    for (const status of grantStatus) {
      if (status === 0) {
        return await PhotoClass.startCameraPicker(PhotoClass.context);
      } else if (status === -1 && PhotoClass.dialogControllerTwo) {
        await PhotoClass.dialogControllerTwo.open();
      }
    }
    return undefined
  }
}

4-2:Permission

import { photoAccessHelper } from "@kit.MediaLibraryKit";
import { abilityAccessCtrl, bundleManager, common, Permissions, Want } from '@kit.AbilityKit';
import { BusinessError } from "@kit.BasicServicesKit";
import { promptAction } from "@kit.ArkUI";

class Permission {
  private atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  private confirmConfig: promptAction.ShowDialogOptions = {
    title: "温馨提示",
    message: "未授权访问媒体资源无法打开相册,是否前往设置进行授权?",
    buttons: [
      { text: '离开', color: '40vp' },
      { text: '去授权', color: '#000' }
    ]
  }

  // 检查是否授权
  async checkAccess(permissions: Permissions) {
    let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION |
    bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_METADATA;
    const ApplicationInfo = bundleManager.getBundleInfoForSelfSync(bundleFlags)
    let tokenID: number = ApplicationInfo.appInfo.accessTokenId
    // permissions.forEach((item: Permissions) => {
    const data = await this.atManager.checkAccessToken(tokenID, permissions)
    if (data === 0) {
      return true

    } else {
      return false
    }
  }

  // 申请授权
  async reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext) {
    // 选中图片信息
    const data = await this.atManager.requestPermissionsFromUser(context, permissions)

    let grantStatus: Array<number> = data.authResults;
    if (grantStatus[0] === 0) {
      // 用户授权,可以继续访问目标操作
      const str = await this.updateAvatar()
      return str
    } else {
      // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
      promptAction.showDialog(this.confirmConfig).then((confirm) => {
        if (confirm.index === 1) {
          this.openPermissionSetting(permissions)
        }
      })
      return ''
    }
  }

  // 打开权限设置
  async openPermissionSetting(permissions: Array<Permissions>) {
    let context: Context = getContext(this) as common.UIAbilityContext;
    this.atManager.requestPermissionOnSetting(context, permissions)
      .then((data: Array<abilityAccessCtrl.GrantStatus>) => {
        if (data[0] === 0) {
          promptAction.showToast({ message: '授权成功' })
        } else {
          promptAction.showToast({ message: '授权失败,请重新授权' })

        }
      })
      .catch((err: BusinessError) => {
        console.log('openPermissionSettingErr', JSON.stringify(err))
      });
  }

  // 打开相册
  async updateAvatar() {
    // 1. 选择相册照片
    // 选择照片配置
    const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions()
    photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE
    photoSelectOptions.maxSelectNumber = 1
    // 选择照片对象
    const photoPicker = new photoAccessHelper.PhotoViewPicker()
    const photoResult = await photoPicker.select(photoSelectOptions)
    const uri = photoResult.photoUris[0]
    return uri
  }
}

export const permission = new Permission()

4-3:PhotoAuthorizationDialog

import { common, Want } from "@kit.AbilityKit"

@CustomDialog
export struct CustomDialogExampleTwo {
  controllerTwo?: CustomDialogController

  build() {
    Column() {
      Text('应用相机权限未开启,是否前往开启').fontSize(20).margin({ top: 45, bottom: 45 })
      Flex({ justifyContent: FlexAlign.SpaceAround }) {
        Button('取消').width('45%')
          .onClick(() => {
            this.controllerTwo?.close()
          }).backgroundColor('#f4f4f4').fontColor(Color.Black)
        Button('前往').width('45%')
          .onClick(() => {
            let context = getContext(this) as common.UIAbilityContext;
            let want: Want = {
              bundleName: 'com.huawei.hmos.settings', //设置应用bundleName
              abilityName: 'com.huawei.hmos.settings.MainAbility', //设置应用abilityName
              uri: "application_info_entry", //通知管理页面
              parameters: {
                pushParams: context.abilityInfo.bundleName
              }
            }
            context.startAbility(want)
            this.controllerTwo?.close()
          }).backgroundColor('#ff313b').fontColor(Color.White)
      }.margin({ bottom: 20 })
    }
  }
}