9 changed files with 871 additions and 59 deletions
@ -0,0 +1,324 @@ |
|||
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'; |
|||
|
|||
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 getDescription(Permission permission) { |
|||
switch (permission) { |
|||
case Permission.phone: |
|||
return '用于拨打电话功能'; |
|||
case Permission.sms: |
|||
return '用于发送短信功能'; |
|||
case Permission.calendarWriteOnly: |
|||
return '用于创建日历事件和提醒'; |
|||
case Permission.calendarFullAccess: |
|||
return '用于读取和管理日历事件及提醒'; |
|||
case Permission.location: |
|||
return '用于获取当前位置信息'; |
|||
default: |
|||
return '应用功能需要'; |
|||
} |
|||
} |
|||
|
|||
// 获取名称 |
|||
String getName(Permission permission) { |
|||
switch (permission) { |
|||
case Permission.phone: |
|||
return '电话'; |
|||
case Permission.sms: |
|||
return '短信'; |
|||
case Permission.calendarWriteOnly: |
|||
return '日历写入'; |
|||
case Permission.calendarFullAccess: |
|||
return '日历完整访问'; |
|||
case Permission.location: |
|||
return '位置信息'; |
|||
default: |
|||
return permission.toString(); |
|||
} |
|||
} |
|||
|
|||
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.grey; |
|||
} 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 { |
|||
if (status.isPermanentlyDenied) { |
|||
// 打开应用设置 |
|||
controller.openSettings(); |
|||
return; |
|||
} |
|||
|
|||
if (!status.isGranted) { |
|||
// 请求权限 |
|||
final result = await controller.requestPermission(permission); |
|||
|
|||
if (result.isGranted) { |
|||
Get.snackbar('成功'.tr, '权限已授予'.tr, snackPosition: SnackPosition.BOTTOM); |
|||
} else if (result.isPermanentlyDenied) { |
|||
Get.dialog( |
|||
AlertDialog( |
|||
title: Text('需要权限'.tr), |
|||
content: Text('此权限需要在设置中手动开启'.tr), |
|||
actions: [ |
|||
TextButton( |
|||
onPressed: () => Get.back(), |
|||
child: Text('取消'.tr), |
|||
), |
|||
TextButton( |
|||
onPressed: () { |
|||
Get.back(); |
|||
controller.openSettings(); |
|||
}, |
|||
child: Text('去设置'.tr), |
|||
), |
|||
], |
|||
), |
|||
); |
|||
} |
|||
|
|||
// 刷新界面 |
|||
Get.forceAppUpdate(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,4 +1,4 @@ |
|||
#import <Flutter/Flutter.h> |
|||
|
|||
|
|||
@interface BleServicePlugin : NSObject<FlutterPlugin> |
|||
@end |
|||
Loading…
Reference in new issue