import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import { bundleManager, common, PermissionRequestResult } from '@kit.AbilityKit';
import { BusinessError } from '@ohos.base';
import { ToastUtil } from './ToastUtil';/*** 權限工具類(申請授權相關)* author: CSDN-鴻蒙布道師* since: 2025/04/22*/
export class PermissionUtil {/*** 獲取應用上下文*/private static getContext(): common.UIAbilityContext {return getContext() as common.UIAbilityContext;}/*** 創建權限管理器實例*/private static createAtManager(): abilityAccessCtrl.AtManager {return abilityAccessCtrl.createAtManager();}/*** 校驗當前是否已經授權* @param permission 待判斷的權限* @returns 已授權 true,未授權 false*/static async checkPermissions(permission: Permissions): Promise<boolean> {const grantStatus = await PermissionUtil.checkAccessToken(permission);return grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;}/*** 校驗并申請權限* @param permissions 需要授權的權限* @returns true 表示授權成功,false 表示用戶拒絕授權*/static async checkAndRequestPermissions(permissions: Permissions | Array<Permissions>): Promise<boolean> {const isGranted = await PermissionUtil.checkPermissions(permissions as Permissions);if (isGranted) {return true;}return PermissionUtil.requestPermissionsEasy(permissions);}/*** 申請權限(支持單個或多個權限組合)* @param permissions 需要授權的權限* @returns true 表示授權成功,false 表示用戶拒絕授權*/static async requestPermissions(permissions: Permissions | Array<Permissions>): Promise<boolean> {const atManager = PermissionUtil.createAtManager();const context = PermissionUtil.getContext();const permissionArray = Array.isArray(permissions) ? [...permissions] : [permissions];try {const result = await atManager.requestPermissionsFromUser(context, permissionArray);return PermissionUtil.isPermissionGranted(result);} catch (error) {PermissionUtil.handleError(error, '申請權限失敗');return false;}}/*** 申請權限并提供二次授權機會(推薦使用此方法)* @param permissions 需要授權的權限* @returns true 表示授權成功,false 表示用戶拒絕授權*/static async requestPermissionsEasy(permissions: Permissions | Array<Permissions>): Promise<boolean> {const granted = await PermissionUtil.requestPermissions(permissions);if (granted) {return true;}return PermissionUtil.requestPermissionOnSettingEasy(Array.isArray(permissions) ? [...permissions] : [permissions]);}/*** 二次向用戶申請權限(適用于單個權限或讀寫權限組)* @param permissions 需要授權的權限集合* @returns true 表示授權成功,false 表示用戶拒絕授權*/static async requestPermissionOnSetting(permissions: Permissions | Array<Permissions>): Promise<boolean> {const atManager = PermissionUtil.createAtManager();const context = PermissionUtil.getContext();const permissionArray = Array.isArray(permissions) ? [...permissions] : [permissions];try {const result = await atManager.requestPermissionOnSetting(context, permissionArray);return PermissionUtil.isPermissionGranted(result);} catch (error) {PermissionUtil.handleError(error, '二次申請權限失敗');return false;}}/*** 二次向用戶申請權限(適用于多個權限)* @param permissions 需要授權的權限集合* @returns true 表示授權成功,false 表示用戶拒絕授權*/static async requestPermissionOnSettingEasy(permissions: Array<Permissions>): Promise<boolean> {for (const permission of permissions) {const isGranted = await PermissionUtil.checkPermissions(permission);if (!isGranted) {const granted = await PermissionUtil.requestPermissionOnSetting(permission);if (!granted) {return false;}}}return true;}/*** 檢查權限是否已授予* @param data 授權結果* @returns true 表示所有權限均已授予,false 表示存在未授予權限*/private static isPermissionGranted(data: PermissionRequestResult | Array<number>): boolean {const authResults = Array.isArray(data) ? data : data.authResults;return authResults.every((status) => status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED);}/*** 校驗訪問令牌是否已授權* @param permission 待檢查權限* @returns 授權狀態*/private static async checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {const atManager = PermissionUtil.createAtManager();let tokenId = 0;try {const bundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);tokenId = bundleInfo.appInfo.accessTokenId;} catch (error) {PermissionUtil.handleError(error, '獲取應用信息失敗');return abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;}try {return await atManager.checkAccessToken(tokenId, permission);} catch (error) {PermissionUtil.handleError(error, '校驗授權信息失敗');return abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;}}/*** 錯誤處理方法* @param error 錯誤對象(明確指定為 BusinessError 類型)* @param message 提示信息*/private static handleError(error: BusinessError, message: string): void {console.error(`${message}: ${error.message}`);ToastUtil.showToast(`${message}: ${error.message}`);}
}代碼如下:
import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
import { bundleManager, common, PermissionRequestResult } from '@kit.AbilityKit';
import { BusinessError } from '@ohos.base';
import { ToastUtil } from './ToastUtil';/*** 權限工具類(申請授權相關)* author: CSDN-鴻蒙布道師* since: 2025/04/22*/
export class PermissionUtil {/*** 獲取應用上下文*/private static getContext(): common.UIAbilityContext {return getContext() as common.UIAbilityContext;}/*** 創建權限管理器實例*/private static createAtManager(): abilityAccessCtrl.AtManager {return abilityAccessCtrl.createAtManager();}/*** 校驗當前是否已經授權* @param permission 待判斷的權限* @returns 已授權 true,未授權 false*/static async checkPermissions(permission: Permissions): Promise<boolean> {const grantStatus = await PermissionUtil.checkAccessToken(permission);return grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;}/*** 校驗并申請權限* @param permissions 需要授權的權限* @returns true 表示授權成功,false 表示用戶拒絕授權*/static async checkAndRequestPermissions(permissions: Permissions | Array<Permissions>): Promise<boolean> {const isGranted = await PermissionUtil.checkPermissions(permissions as Permissions);if (isGranted) {return true;}return PermissionUtil.requestPermissionsEasy(permissions);}/*** 申請權限(支持單個或多個權限組合)* @param permissions 需要授權的權限* @returns true 表示授權成功,false 表示用戶拒絕授權*/static async requestPermissions(permissions: Permissions | Array<Permissions>): Promise<boolean> {const atManager = PermissionUtil.createAtManager();const context = PermissionUtil.getContext();const permissionArray = Array.isArray(permissions) ? [...permissions] : [permissions];try {const result = await atManager.requestPermissionsFromUser(context, permissionArray);return PermissionUtil.isPermissionGranted(result);} catch (error) {PermissionUtil.handleError(error, '申請權限失敗');return false;}}/*** 申請權限并提供二次授權機會(推薦使用此方法)* @param permissions 需要授權的權限* @returns true 表示授權成功,false 表示用戶拒絕授權*/static async requestPermissionsEasy(permissions: Permissions | Array<Permissions>): Promise<boolean> {const granted = await PermissionUtil.requestPermissions(permissions);if (granted) {return true;}return PermissionUtil.requestPermissionOnSettingEasy(Array.isArray(permissions) ? [...permissions] : [permissions]);}/*** 二次向用戶申請權限(適用于單個權限或讀寫權限組)* @param permissions 需要授權的權限集合* @returns true 表示授權成功,false 表示用戶拒絕授權*/static async requestPermissionOnSetting(permissions: Permissions | Array<Permissions>): Promise<boolean> {const atManager = PermissionUtil.createAtManager();const context = PermissionUtil.getContext();const permissionArray = Array.isArray(permissions) ? [...permissions] : [permissions];try {const result = await atManager.requestPermissionOnSetting(context, permissionArray);return PermissionUtil.isPermissionGranted(result);} catch (error) {PermissionUtil.handleError(error, '二次申請權限失敗');return false;}}/*** 二次向用戶申請權限(適用于多個權限)* @param permissions 需要授權的權限集合* @returns true 表示授權成功,false 表示用戶拒絕授權*/static async requestPermissionOnSettingEasy(permissions: Array<Permissions>): Promise<boolean> {for (const permission of permissions) {const isGranted = await PermissionUtil.checkPermissions(permission);if (!isGranted) {const granted = await PermissionUtil.requestPermissionOnSetting(permission);if (!granted) {return false;}}}return true;}/*** 檢查權限是否已授予* @param data 授權結果* @returns true 表示所有權限均已授予,false 表示存在未授予權限*/private static isPermissionGranted(data: PermissionRequestResult | Array<number>): boolean {const authResults = Array.isArray(data) ? data : data.authResults;return authResults.every((status) => status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED);}/*** 校驗訪問令牌是否已授權* @param permission 待檢查權限* @returns 授權狀態*/private static async checkAccessToken(permission: Permissions): Promise<abilityAccessCtrl.GrantStatus> {const atManager = PermissionUtil.createAtManager();let tokenId = 0;try {const bundleInfo = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION);tokenId = bundleInfo.appInfo.accessTokenId;} catch (error) {PermissionUtil.handleError(error, '獲取應用信息失敗');return abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;}try {return await atManager.checkAccessToken(tokenId, permission);} catch (error) {PermissionUtil.handleError(error, '校驗授權信息失敗');return abilityAccessCtrl.GrantStatus.PERMISSION_DENIED;}}/*** 錯誤處理方法* @param error 錯誤對象(明確指定為 BusinessError 類型)* @param message 提示信息*/private static handleError(error: BusinessError, message: string): void {console.error(`${message}: ${error.message}`);ToastUtil.showToast(`${message}: ${error.message}`);}
}