手写一个权限申请工具 原创

鸿蒙小白001
发布于 2024-12-19 19:02
浏览
0收藏

一、权限申请的步骤

当我们申请一个需要用户授权的权限时,需要做以下工作

(1)判断是否授权了权限

(2)申请权限

(3)对于拒绝授权的情况,需要二次弹出配置权限弹窗

(4)用户拒绝授权时,应用页面需要展示提示语

每次申请权限都要进行这么多步骤的操作过于繁琐,那么写一个工具类就有必要了。初步实现效果为调用申请权限的静态方法,回调授权成功或者失败,失败就展示提示语。


二、效果展示

如图为点击开启权限,首先拒绝授权,页面出现提示语;再次点击授权,出现设置权限弹窗,此时选择不允许,提示语依然存在;再点击按钮,此时选择允许,提示语消失,授权成功


手写一个权限申请工具-鸿蒙开发者社区

三、关键代码逻辑

(1)检查权限授权与否

/**
 * 检查权限是否已授权
 * @param permission
 * @param onGrant
 */
static checkPermissionGrant(permission: Permissions, context: common.UIAbilityContext,
  onGrant: (granted: boolean) => void
): void {
  let hasPermission = false;
  let tokenId: number = 0;
  try {
    let bundleInfo: bundleManager.BundleInfo =
      bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
    let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
    tokenId = appInfo.accessTokenId;
  } catch (error) {
  }

  try {
    let atManager = abilityAccessCtrl.createAtManager();
    let granted = atManager.checkAccessTokenSync(tokenId, permission);
    hasPermission = granted === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED
  } catch (error) {
  }
  if (hasPermission) {
    //已获得权限,回调成功的方法
    onGrant(true)
  } else {
    //未获得权限,去申请权限
    PermissionUtil.requestPermissions(permission, context, (granted: boolean) => {
      onGrant(granted)
    });
  }
}

(2)根据authResults和dialogShownResults判断是否授权成功,是否需要弹出设置权限弹窗

static requestPermissions(permission: Permissions, context: common.UIAbilityContext,
  onGrant: (granted: boolean) => void): void {
  let atManager = abilityAccessCtrl.createAtManager();
  try {
    atManager.requestPermissionsFromUser(context, [permission]).then((data) => {
      if (data.authResults[0] === 0) {
        //用户已授权
        onGrant(true)
      } else if (data.authResults[0] === -1) {
        //用户未授权
        if (data.dialogShownResults && (data.dialogShownResults[0])) {
          // 表示有弹框表明已经向用户展示请求授权的弹窗但是用户拒绝了授权,此时需要在页面添加提示语
          onGrant(false)
        } else {
          //表示当前应用没有被授权且没有向用户展示请求授权的弹框,此时可以弹权限设置弹框
          PermissionUtil.openPermissionsSetting(permission, context, onGrant)
        }
      }
    }).catch((err: Error) => {
    });
  } catch (err) {
  }
}

(3)根据权限设置弹窗返回值判断是否授权成功

static openPermissionsSetting(permission: Permissions, context: common.UIAbilityContext,
  onGranted: (granted: boolean) => void): void {
  let atManager = abilityAccessCtrl.createAtManager();
  atManager.requestPermissionOnSetting(context, [permission])
    .then((data: Array<abilityAccessCtrl.GrantStatus>) => {
      if (data[0] === -1) {
        //用户再次拒绝了授权
        onGranted(false)
      } else if (data[0] === 0) {
        //用户同意授权
        onGranted(true)
      }
    })
    .catch((err: BusinessError) => {
    });
}

四、完整代码

PermissionUtil.ets

import { abilityAccessCtrl, bundleManager, common, Permissions } from "@kit.AbilityKit";
import { BusinessError } from "@kit.BasicServicesKit";

export class PermissionUtil {
  static reqPermissionsFromUser(permission: Permissions, context: common.UIAbilityContext,
    onGranted: (granted: boolean) => void) {

    PermissionUtil.checkPermissionGrant(permission, context, (granted: boolean) => {
      onGranted(granted)
    })
  }

  /**
   * 检查权限是否已授权
   * @param permission
   * @param onGrant
   */
  static checkPermissionGrant(permission: Permissions, context: common.UIAbilityContext,
    onGrant: (granted: boolean) => void
  ): void {
    let hasPermission = false;
    let tokenId: number = 0;
    try {
      let bundleInfo: bundleManager.BundleInfo =
        bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);
      let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
      tokenId = appInfo.accessTokenId;
    } catch (error) {
    }

    try {
      let atManager = abilityAccessCtrl.createAtManager();
      let granted = atManager.checkAccessTokenSync(tokenId, permission);
      hasPermission = granted === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED
    } catch (error) {
    }
    if (hasPermission) {
      //已获得权限,回调成功的方法
      onGrant(true)
    } else {
      //未获得权限,去申请权限
      PermissionUtil.requestPermissions(permission, context, (granted: boolean) => {
        onGrant(granted)
      });
    }
  }

  static requestPermissions(permission: Permissions, context: common.UIAbilityContext,
    onGrant: (granted: boolean) => void): void {
    let atManager = abilityAccessCtrl.createAtManager();
    try {
      atManager.requestPermissionsFromUser(context, [permission]).then((data) => {
        if (data.authResults[0] === 0) {
          //用户已授权
          onGrant(true)
        } else if (data.authResults[0] === -1) {
          //用户未授权
          if (data.dialogShownResults && (data.dialogShownResults[0])) {
            // 表示有弹框表明已经向用户展示请求授权的弹窗但是用户拒绝了授权,此时需要在页面添加提示语
            onGrant(false)
          } else {
            //表示当前应用没有被授权且没有向用户展示请求授权的弹框,此时可以弹权限设置弹框
            PermissionUtil.openPermissionsSetting(permission, context, onGrant)
          }
        }
      }).catch((err: Error) => {
      });
    } catch (err) {
    }
  }

  static openPermissionsSetting(permission: Permissions, context: common.UIAbilityContext,
    onGranted: (granted: boolean) => void): void {
    let atManager = abilityAccessCtrl.createAtManager();
    atManager.requestPermissionOnSetting(context, [permission])
      .then((data: Array<abilityAccessCtrl.GrantStatus>) => {
        if (data[0] === -1) {
          //用户再次拒绝了授权
          onGranted(false)
        } else if (data[0] === 0) {
          //用户同意授权
          onGranted(true)
        }
      })
      .catch((err: BusinessError) => {
      });
  }
}


Index.ets

import {  common, Permissions } from '@kit.AbilityKit';
import { promptAction } from '@kit.ArkUI';
import { PermissionUtil } from '../PermissionUtil';

@Entry
@Component
struct Index {
  @State isShowPermissions: boolean = false;
  @State permissionsMessage: string | Resource = "录音需要开启麦克风权限才能正常使用,";
  private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
  permission: Permissions = 'ohos.permission.MICROPHONE'
  requestPermission(){
    PermissionUtil.reqPermissionsFromUser(this.permission, this.context, (granted: boolean) => {
      if (granted) {
        promptAction.showToast({ message: "已授权" })
      }
      this.isShowPermissions = !granted
    })
  }
  build() {
    Column({ space: 10 }) {
      Column() {
        if (this.isShowPermissions) {
          Text() {
            Span(this.permissionsMessage)
            Span("开启权限")
              .fontColor('#0A59F7')
              .onClick(() => {
                this.requestPermission()
              })
          }
          .width('100%')
          .padding({
            left: 16,
            right: 16
          })
          .margin({
            bottom: 16
          })
        }
      }.justifyContent(FlexAlign.End)
      .layoutWeight(1)

      Button("开启麦克风权限")
        .onClick(() => {
          this.requestPermission()
        })
        .backgroundColor('#0A59F7')
        .width(288)
        .margin({
          bottom: 16
        })
    }
    .justifyContent(FlexAlign.SpaceBetween)
    .width('100%')
    .height('100%')
  }
}

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报
回复
    相关推荐