/** * PermissionManager.uts * * Utility class for managing Android permissions throughout the app * Handles requesting permissions, checking status, and directing users to settings */ /** * Common permission types that can be requested */ export enum PermissionType { BLUETOOTH = 'bluetooth', LOCATION = 'location', STORAGE = 'storage', CAMERA = 'camera', MICROPHONE = 'microphone', NOTIFICATIONS = 'notifications', CALENDAR = 'calendar', CONTACTS = 'contacts', SENSORS = 'sensors' } /** * Result of a permission request */ type PermissionResult = { granted: boolean; grantedPermissions: string[]; deniedPermissions: string[]; }; /** * Manages permission requests and checks throughout the app */ export class PermissionManager { /** * Maps permission types to the actual Android permission strings */ private static getPermissionsForType(type: PermissionType): string[] { switch (type) { case PermissionType.BLUETOOTH: return [ 'android.permission.BLUETOOTH_SCAN', 'android.permission.BLUETOOTH_CONNECT', 'android.permission.BLUETOOTH_ADVERTISE' ]; case PermissionType.LOCATION: return [ 'android.permission.ACCESS_FINE_LOCATION', 'android.permission.ACCESS_COARSE_LOCATION' ]; case PermissionType.STORAGE: return [ 'android.permission.READ_EXTERNAL_STORAGE', 'android.permission.WRITE_EXTERNAL_STORAGE' ]; case PermissionType.CAMERA: return ['android.permission.CAMERA']; case PermissionType.MICROPHONE: return ['android.permission.RECORD_AUDIO']; case PermissionType.NOTIFICATIONS: return ['android.permission.POST_NOTIFICATIONS']; case PermissionType.CALENDAR: return [ 'android.permission.READ_CALENDAR', 'android.permission.WRITE_CALENDAR' ]; case PermissionType.CONTACTS: return [ 'android.permission.READ_CONTACTS', 'android.permission.WRITE_CONTACTS' ]; case PermissionType.SENSORS: return ['android.permission.BODY_SENSORS']; default: return []; } } /** * Get appropriate display name for a permission type */ private static getPermissionDisplayName(type: PermissionType): string { switch (type) { case PermissionType.BLUETOOTH: return '蓝牙'; case PermissionType.LOCATION: return '位置'; case PermissionType.STORAGE: return '存储'; case PermissionType.CAMERA: return '相机'; case PermissionType.MICROPHONE: return '麦克风'; case PermissionType.NOTIFICATIONS: return '通知'; case PermissionType.CALENDAR: return '日历'; case PermissionType.CONTACTS: return '联系人'; case PermissionType.SENSORS: return '身体传感器'; default: return '未知权限'; } } /** * Check if a permission is granted * @param type The permission type to check * @returns True if the permission is granted, false otherwise */ static isPermissionGranted(type: PermissionType): boolean { try { const permissions = this.getPermissionsForType(type); const activity = UTSAndroid.getUniActivity(); if (activity == null || permissions.length === 0) { return false; } // Check each permission in the group for (const permission of permissions) { if (!UTSAndroid.checkSystemPermissionGranted(activity, [permission])) { return false; } } return true; } catch (e: any) { __f__('error', 'at ak/PermissionManager.uts:132', `Error checking ${type} permission:`, e); return false; } } /** * Request a permission from the user * @param type The permission type to request * @param callback Function to call with the result of the permission request * @param showRationale Whether to show a rationale dialog if permission was previously denied */ static requestPermission(type: PermissionType, callback: (result: PermissionResult) => void, showRationale: boolean = true): void { try { const permissions = this.getPermissionsForType(type); const activity = UTSAndroid.getUniActivity(); if (activity == null || permissions.length === 0) { callback({ granted: false, grantedPermissions: [], deniedPermissions: permissions } as PermissionResult); return; } // Check if already granted let allGranted = true; for (const permission of permissions) { if (!UTSAndroid.checkSystemPermissionGranted(activity, [permission])) { allGranted = false; break; } } if (allGranted) { callback({ granted: true, grantedPermissions: permissions, deniedPermissions: [] } as PermissionResult); return; } // Request the permissions UTSAndroid.requestSystemPermission(activity, permissions, (granted: boolean, grantedPermissions: string[]) => { if (granted) { callback({ granted: true, grantedPermissions: grantedPermissions, deniedPermissions: [] } as PermissionResult); } else if (showRationale) { // Show rationale dialog this.showPermissionRationale(type, callback); } else { // Just report the denial callback({ granted: false, grantedPermissions: grantedPermissions, deniedPermissions: this.getDeniedPermissions(permissions, grantedPermissions) } as PermissionResult); } }, (denied: boolean, deniedPermissions: string[]) => { callback({ granted: false, grantedPermissions: this.getGrantedPermissions(permissions, deniedPermissions), deniedPermissions: deniedPermissions } as PermissionResult); }); } catch (e: any) { __f__('error', 'at ak/PermissionManager.uts:217', `Error requesting ${type} permission:`, e); callback({ granted: false, grantedPermissions: [], deniedPermissions: this.getPermissionsForType(type) } as PermissionResult); } } /** * Show a rationale dialog explaining why the permission is needed */ private static showPermissionRationale(type: PermissionType, callback: (result: PermissionResult) => void): void { const permissionName = this.getPermissionDisplayName(type); uni.showModal({ title: '权限申请', content: `需要${permissionName}权限才能使用相关功能`, confirmText: '去设置', cancelText: '取消', success: (result) => { if (result.confirm) { this.openAppSettings(); callback({ granted: false, grantedPermissions: [], deniedPermissions: this.getPermissionsForType(type) } as PermissionResult); } else { callback({ granted: false, grantedPermissions: [], deniedPermissions: this.getPermissionsForType(type) } as PermissionResult); } } }); } /** * Open the app settings page */ static openAppSettings(): void { try { const context = UTSAndroid.getAppContext(); if (context != null) { const intent = new android.content.Intent(); intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); const uri = android.net.Uri.fromParts("package", context.getPackageName(), null); intent.setData(uri); intent.addFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } } catch (e: any) { __f__('error', 'at ak/PermissionManager.uts:285', 'Failed to open app settings', e); uni.showToast({ title: '请手动前往系统设置修改应用权限', icon: 'none', duration: 3000 }); } } /** * Helper to get the list of granted permissions */ private static getGrantedPermissions(allPermissions: string[], deniedPermissions: string[]): string[] { return allPermissions.filter((p): boolean => !deniedPermissions.includes(p)); } /** * Helper to get the list of denied permissions */ private static getDeniedPermissions(allPermissions: string[], grantedPermissions: string[]): string[] { return allPermissions.filter((p): boolean => !grantedPermissions.includes(p)); } /** * Request multiple permission types at once * @param types Array of permission types to request * @param callback Function to call when all permissions have been processed */ static requestMultiplePermissions(types: PermissionType[], callback: (results: Map) => void): void { if (types.length === 0) { callback(new Map()); return; } const results = new Map(); let remaining = types.length; for (const type of types) { this.requestPermission(type, (result) => { results.set(type, result); remaining--; if (remaining === 0) { callback(results); } }, true); } } /** * Convenience method to request Bluetooth permissions * @param callback Function to call after the permission request */ static requestBluetoothPermissions(callback: (granted: boolean) => void): void { this.requestPermission(PermissionType.BLUETOOTH, (result) => { // For Bluetooth, we also need location permissions on Android if (result.granted) { this.requestPermission(PermissionType.LOCATION, (locationResult) => { callback(locationResult.granted); }); } else { callback(false); } }); } } //# sourceMappingURL=PermissionManager.uts.map