import 'dart:io'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; class PermissionGroupModel { final String titleKey; final IconData icon; final List permissions; const PermissionGroupModel({ required this.titleKey, required this.icon, required this.permissions, }); } class PermissionGroup { /// 获取蓝牙权限列表(根据平台和Android版本) static List _bluetoothPermissionsFor(int androidSdkVersion) { if (!Platform.isAndroid) return []; // Android 12+ (API 31+) 使用新的蓝牙权限;以下版本不显示(会自动授予) if (androidSdkVersion >= 31) { return [Permission.bluetoothScan, Permission.bluetoothConnect]; } return []; } /// 获取平台特定的权限组列表(同步方法)。 /// /// [androidSdkVersion] 由调用方传入(权限管理页的 controller 在 onInit 里 /// 查一次并缓存),这里不再自己 await DeviceInfoPlugin —— 之前是异步方法, /// 权限管理页每次用 FutureBuilder 内联调用它,任何一次权限状态变化触发 /// 页面重建都会重新 await 一次,短暂进入 ConnectionState.waiting 把列表 /// 换成一个小小的 loading 指示器,SingleChildScrollView 的可滚动内容瞬间 /// 收缩到底,滚动位置跟着被夹到顶部;等 Future resolve 回来也不会自动恢复 /// 原来的滚动位置,表现就是用户点一下弹窗按钮,整个列表"刷"回最上面。 /// 改成同步方法后 FutureBuilder 整个不需要了,就没有这个中间态。 static List getPlatformGroups({ required int androidSdkVersion, }) { final bluetoothPermissions = _bluetoothPermissionsFor(androidSdkVersion); return [ // 蓝牙权限组 - 根据平台动态获取权限 PermissionGroupModel( titleKey: 'bluetoothPermissions', icon: Icons.bluetooth, permissions: bluetoothPermissions, ), // 通知权限组 const PermissionGroupModel( titleKey: 'notificationPermissions', icon: Icons.notifications, permissions: [Permission.notification], ), // 闹钟权限组 - 仅Android const PermissionGroupModel( titleKey: 'alarmPermissions', icon: Icons.alarm, permissions: [Permission.scheduleExactAlarm], ), // 日历权限组 const PermissionGroupModel( titleKey: 'calendarPermissions', icon: Icons.calendar_today, permissions: [Permission.calendarFullAccess], ), // 位置权限组 const PermissionGroupModel( titleKey: 'locationPermissions', icon: Icons.location_on, permissions: [Permission.location], ), // 存储权限组 const PermissionGroupModel( titleKey: 'storagePermissions', icon: Icons.storage, permissions: [Permission.storage], ), // 麦克风权限组 const PermissionGroupModel( titleKey: 'microphonePermissions', icon: Icons.mic, permissions: [Permission.microphone], ), ]; } }