From 5b9c2c6bf811df99eaad1599121398f75e6aab99 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Wed, 10 Sep 2025 18:12:10 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=9D=83=E9=99=90):=20=E5=9C=A8=E6=9D=83?= =?UTF-8?q?=E9=99=90=E8=A7=86=E5=9B=BE=E9=A1=B6=E9=83=A8=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=90=8E=E5=8F=B0=E6=9D=83=E9=99=90=E8=AE=BE=E7=BD=AE=E5=85=A5?= =?UTF-8?q?=E5=8F=A3=EF=BC=8C=E4=BB=85=E5=AF=B9Android=E4=B8=AD=E6=96=87?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E7=94=A8=E6=88=B7=E6=98=BE=E7=A4=BA=E3=80=82?= =?UTF-8?q?=E5=8C=85=E5=90=AB=E5=AE=8C=E6=95=B4=E7=9A=84=E5=93=81=E7=89=8C?= =?UTF-8?q?=E5=AE=9A=E5=88=B6=E5=8C=96=E8=AE=BE=E7=BD=AE=E6=8C=87=E5=8D=97?= =?UTF-8?q?=EF=BC=8C=E5=B8=AE=E5=8A=A9=E7=94=A8=E6=88=B7=E6=AD=A3=E7=A1=AE?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=90=8E=E5=8F=B0=E8=BF=90=E8=A1=8C=E6=9D=83?= =?UTF-8?q?=E9=99=90=E4=BB=A5=E7=A1=AE=E4=BF=9DAI=E5=8A=A9=E6=89=8B?= =?UTF-8?q?=E9=9A=8F=E6=97=B6=E5=93=8D=E5=BA=94=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../permissions/views/permissions_view.dart | 288 ++++++++++++++++++ pubspec.yaml | 2 +- 2 files changed, 289 insertions(+), 1 deletion(-) diff --git a/lib/modules/permissions/views/permissions_view.dart b/lib/modules/permissions/views/permissions_view.dart index 6e633ae81..eca8a7d65 100644 --- a/lib/modules/permissions/views/permissions_view.dart +++ b/lib/modules/permissions/views/permissions_view.dart @@ -69,6 +69,15 @@ class PermissionsView extends GetView { final groups = snapshot.data ?? []; final List widgets = []; + // 添加后台权限条目到最前端(仅在满足条件时) + final backgroundPermissionWidget = _buildBackgroundPermissionSection(isDarkMode); + if (backgroundPermissionWidget is! SizedBox) { + widgets.add(backgroundPermissionWidget); + if (groups.isNotEmpty) { + widgets.add(SizedBox(height: 20.h)); + } + } + for (int i = 0; i < groups.length; i++) { final group = groups[i]; @@ -284,6 +293,285 @@ class PermissionsView extends GetView { ); } + /// 构建后台权限条目 + Widget _buildBackgroundPermissionSection(bool isDarkMode) { + // 检查是否为Android系统且语言为中文 + if (!_shouldShowBackgroundPermissionTutorial()) { + return const SizedBox.shrink(); // 不满足条件时完全隐藏 + } + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 组标题 + Padding( + padding: EdgeInsets.only(left: 4.w, bottom: 8.h), + child: Text( + '后台权限'.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: _buildBackgroundPermissionItem(isDarkMode), + ), + ), + ), + ], + ); + } + + /// 检查是否应该显示后台权限教程入口 + /// 仅在Android系统且中文环境下显示 + bool _shouldShowBackgroundPermissionTutorial() { + // 1. 检查是否为Android系统 + if (!Platform.isAndroid) { + return false; + } + + // 2. 检查设备语言区域是否为中文 + final locale = Get.locale ?? Get.deviceLocale; + if (locale == null) { + return false; + } + + // 检查语言代码是否为中文(zh) + return locale.languageCode == 'zh'; + } + + /// 构建后台权限条目内容 + Widget _buildBackgroundPermissionItem(bool isDarkMode) { + return InkWell( + onTap: () { + _showBackgroundPermissionGuide(); + }, + child: Padding( + padding: EdgeInsets.all(16.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '后台运行'.tr, // 确保随时可以唤醒AI助手 + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w500, + color: isDarkMode ? Colors.white : Colors.black87, + ), + ), + SizedBox(height: 4.h), + Text( + '设置后台运行权限,确保AI助手随时响应您的需求'.tr, // 设置后台运行权限,确保AI助手随时响应您的需求 + style: TextStyle( + fontSize: 12.sp, + color: isDarkMode ? Colors.white70 : Colors.grey[600], + ), + ), + ], + ), + ), + Icon( + Icons.arrow_forward_ios, + size: 16.sp, + color: isDarkMode ? Colors.white70 : Colors.grey[600], + ), + ], + ), + ), + ); + } + + // 显示后台权限设置指南 + void _showBackgroundPermissionGuide() { + final isDarkMode = Theme.of(Get.context!).brightness == Brightness.dark; + + Get.bottomSheet( + Container( + height: Get.height * 0.8, + decoration: BoxDecoration( + color: isDarkMode ? Colors.grey[900] : Colors.white, + borderRadius: BorderRadius.vertical(top: Radius.circular(20.r)), + ), + child: Column( + children: [ + // 顶部标题栏 + Container( + padding: EdgeInsets.all(16.w), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: isDarkMode + ? Colors.grey[700]! + : Colors.grey.shade300)), + ), + child: Row( + children: [ + Text( + '后台运行权限设置'.tr, + style: TextStyle( + fontSize: 18.sp, + fontWeight: FontWeight.bold, + color: isDarkMode ? Colors.white : Colors.black, + ), + ), + Spacer(), + IconButton( + onPressed: () => Get.back(), + icon: Icon( + Icons.close, + color: isDarkMode ? Colors.white : Colors.black, + ), + ), + ], + ), + ), + // 内容区域 + Expanded( + child: SingleChildScrollView( + padding: EdgeInsets.all(16.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '为确保AI助手能够在后台正常运行,请根据您的手机品牌进行以下设置:'.tr, + style: TextStyle( + fontSize: 14.sp, + color: isDarkMode ? Colors.grey[300] : Colors.grey[600], + ), + ), + SizedBox(height: 20.h), + _buildBrandGuide( + '华为/荣耀', + [ + '设置 → 应用 → 应用启动管理', + '找到Voitrans应用', + '关闭"自动管理"', + '开启"允许自启动"、"允许关联启动"、"允许后台活动"' + ], + isDarkMode), + _buildBrandGuide( + 'OPPO', + ['设置 → 应用 → 自启动', '找到Voitrans应用', '打开"后台自启动"'], + isDarkMode), + _buildBrandGuide( + 'vivo', + ['i管家 → 应用管理 → 自启动 → 关联启动', '找到Voitrans应用', '允许"关联启动"'], + isDarkMode), + _buildBrandGuide( + '小米', + ['设置 → 应用设置 → 应用管理', '找到Voitrans应用', '打开"自启动"'], + isDarkMode), + _buildBrandGuide( + '三星', + ['长按Voitrans图标', '应用程序信息 → 电池', '打开"允许后台活动"'], + isDarkMode), + ], + ), + ), + ), + ], + ), + ), + isScrollControlled: true, + ); + } + + // 构建品牌设置指南 + Widget _buildBrandGuide(String brand, List steps, bool isDarkMode) { + return Container( + margin: EdgeInsets.only(bottom: 20.h), + padding: EdgeInsets.all(16.w), + decoration: BoxDecoration( + color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.grey[50], + borderRadius: BorderRadius.circular(12.r), + border: Border.all( + color: isDarkMode ? Colors.grey[700]! : Colors.grey.shade300), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + brand, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.bold, + color: isDarkMode ? Colors.blue[400] : Colors.blue[600], + ), + ), + SizedBox(height: 8.h), + ...steps.asMap().entries.map((entry) { + int index = entry.key; + String step = entry.value; + return Padding( + padding: EdgeInsets.only(bottom: 4.h), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: 20.w, + height: 20.w, + decoration: BoxDecoration( + color: isDarkMode ? Colors.blue[400] : Colors.blue[600], + shape: BoxShape.circle, + ), + child: Center( + child: Text( + '${index + 1}', + style: TextStyle( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + SizedBox(width: 8.w), + Expanded( + child: Text( + step, + style: TextStyle( + fontSize: 14.sp, + color: isDarkMode ? Colors.white : Colors.black87, + ), + ), + ), + ], + ), + ); + }).toList(), + ], + ), + ); + } + void _handlePermissionToggle( Permission permission, PermissionStatus status, diff --git a/pubspec.yaml b/pubspec.yaml index 0346ef700..1a6b7388d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: voitrans description: "Voitrans - AI Voice Assistant." publish_to: "none" -version: 1.0.13+34 +version: 1.0.14+37 environment: sdk: ">=3.3.0 <4.0.0"