You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

373 lines
11 KiB

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import '../controllers/settings_controller.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'dart:ui';
import 'package:deep_voice/core/utils/permission_util.dart'; // 引入PermissionUtil
class PermissionsView extends GetView<SettingsController> {
const PermissionsView({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
return Scaffold(
backgroundColor: isDarkMode ? Colors.black : Colors.grey[50],
appBar: AppBar(
backgroundColor: isDarkMode ? Colors.black : Colors.white,
elevation: 0.5,
leading: IconButton(
icon: Icon(
Icons.arrow_back_ios,
size: 20.w,
color: isDarkMode ? Colors.white : Colors.black87,
),
onPressed: () => Get.back(),
),
title: Text(
'权限管理'.tr,
style: TextStyle(
fontSize: 17.sp,
fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.white : Colors.black,
),
),
centerTitle: true,
),
body: FutureBuilder<Map<Permission, PermissionStatus>>(
future: controller.checkAllPermissions(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text('获取权限状态失败: ${snapshot.error}'.tr));
}
final permissionStatuses = snapshot.data ?? {};
return ListView(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h),
children: [
// 通讯权限组
_buildPermissionSection(
'通讯权限',
Icons.phone_android,
[Permission.phone, Permission.sms],
permissionStatuses,
isDarkMode),
SizedBox(height: 20.h),
// 日历权限组
_buildPermissionSection(
'日历权限',
Icons.calendar_today,
[Permission.calendarFullAccess],
permissionStatuses,
isDarkMode),
SizedBox(height: 20.h),
// 位置权限组
_buildPermissionSection('位置权限', Icons.location_on,
[Permission.location], permissionStatuses, isDarkMode),
],
);
},
),
);
}
// 构建权限组区域
Widget _buildPermissionSection(
String title,
IconData icon,
List<Permission> permissions,
Map<Permission, PermissionStatus> statuses,
bool isDarkMode) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 组标题
Padding(
padding: EdgeInsets.only(left: 4.w, bottom: 8.h),
child: Text(
title.tr,
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
color: isDarkMode ? Colors.blue[400] : Colors.blue[600],
letterSpacing: 1,
),
),
),
// 权限项容器
Container(
decoration: BoxDecoration(
color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.white,
borderRadius: BorderRadius.circular(16.r),
boxShadow: [
BoxShadow(
color: isDarkMode
? Colors.black.withOpacity(0.2)
: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(16.r),
child: BackdropFilter(
filter: isDarkMode
? ImageFilter.blur(sigmaX: 5, sigmaY: 5)
: ImageFilter.blur(sigmaX: 0, sigmaY: 0),
child: Column(
children:
_buildPermissionItems(permissions, statuses, isDarkMode),
),
),
),
),
],
);
}
// 构建权限项列表
List<Widget> _buildPermissionItems(List<Permission> permissions,
Map<Permission, PermissionStatus> statuses, bool isDarkMode) {
final List<Widget> items = [];
// 获取名称
String getName(Permission permission) {
switch (permission) {
case Permission.phone:
return '电话';
case Permission.sms:
return '短信';
case Permission.calendarFullAccess:
return '日历写入';
case Permission.calendarFullAccess:
return '日历完整访问';
case Permission.location:
return '位置信息';
default:
return permission.toString();
}
}
// 获取描述文本
String getDescription(Permission permission) {
switch (permission) {
case Permission.phone:
return '用于拨打电话功能';
case Permission.sms:
return '用于发送短信功能';
case Permission.calendarFullAccess:
return '用于创建日历事件和提醒';
case Permission.calendarFullAccess:
return '用于读取和管理日历事件及提醒';
case Permission.location:
return '用于获取当前位置信息';
default:
return '应用功能需要';
}
}
for (int i = 0; i < permissions.length; i++) {
final permission = permissions[i];
final status = statuses[permission] ?? PermissionStatus.denied;
items.add(
_buildPermissionItem(
name: getName(permission),
description: getDescription(permission),
status: status,
permission: permission,
isDarkMode: isDarkMode,
),
);
// 添加分隔线,最后一个不加
if (i < permissions.length - 1) {
items.add(Divider(
height: 1,
color: isDarkMode ? Colors.white.withOpacity(0.1) : Colors.grey[200],
));
}
}
return items;
}
// 构建单个权限项
Widget _buildPermissionItem({
required String name,
required String description,
required PermissionStatus status,
required Permission permission,
required bool isDarkMode,
}) {
return Padding(
padding: EdgeInsets.all(16.w),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
name.tr,
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w500,
color: isDarkMode ? Colors.white : Colors.black87,
),
),
SizedBox(height: 4.h),
Text(
description.tr,
style: TextStyle(
fontSize: 12.sp,
color: isDarkMode ? Colors.white70 : Colors.grey[600],
),
),
SizedBox(height: 4.h),
_buildStatusText(status, isDarkMode),
],
),
),
Switch(
value: status.isGranted,
onChanged: (value) {
if (value) {
_handlePermissionAction(permission, status);
} else if (status.isGranted) {
controller.openSettings();
}
},
activeColor: Colors.blue[600],
),
],
),
);
}
// 状态文本
Widget _buildStatusText(PermissionStatus status, bool isDarkMode) {
String text;
Color color;
if (status.isGranted) {
text = '已授权'.tr;
color = Colors.green;
} else if (status.isDenied) {
text = '未授权'.tr;
color = Colors.red;
} else if (status.isPermanentlyDenied) {
text = '需要在系统设置中开启'.tr;
color = Colors.orange;
} else if (status.isLimited) {
text = '部分授权'.tr;
color = Colors.orange;
} else {
text = '未知状态'.tr;
color = Colors.grey;
}
return Text(
text,
style: TextStyle(
color: color,
fontSize: 12.sp,
fontWeight: FontWeight.w500,
),
);
}
// 处理权限请求
Future<void> _handlePermissionAction(
Permission permission, PermissionStatus status) async {
try {
// final context = Get.context;
// if (context == null) return;
final permissionName = _getPermissionName(permission);
final explanationText = _getExplanationText(permission);
// 使用 PermissionUtil 请求权限
final hasPermission = await PermissionUtil.instance.requestPermission(
// context: context,
permissionType: permission,
permissionName: permissionName,
explanationText: explanationText,
permanentDenialText: '您已永久拒绝$permissionName权限,请前往应用设置开启',
settingsButtonText: '去设置',
cancelButtonText: '取消',
);
if (hasPermission) {
Get.snackbar(
'成功'.tr,
'$permissionName权限已授予'.tr,
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.green,
colorText: Colors.white,
);
}
// 刷新界面,重新获取权限状态
Get.forceAppUpdate();
} catch (e) {
Get.snackbar(
'错误'.tr,
'请求权限时出错: $e'.tr,
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.red,
colorText: Colors.white,
);
}
}
// 获取权限的用户友好名称
String _getPermissionName(Permission permission) {
switch (permission) {
case Permission.phone:
return '电话';
case Permission.sms:
return '短信';
case Permission.calendarFullAccess:
return '日历写入';
case Permission.calendarFullAccess:
return '日历完整访问';
case Permission.location:
return '位置信息';
default:
return permission.toString();
}
}
// 获取权限说明文本
String _getExplanationText(Permission permission) {
switch (permission) {
case Permission.phone:
return '拨打电话功能需要电话权限';
case Permission.sms:
return '发送短信功能需要短信权限';
case Permission.calendarFullAccess:
return '创建日历事件需要日历写入权限';
case Permission.calendarFullAccess:
return '管理日历事件需要完整日历权限';
case Permission.location:
return '获取位置信息需要位置权限';
default:
return '应用需要此权限以提供完整功能';
}
}
}