Browse Source

Merge commit 'baa8b699cbf6b6be697c9789e15d85ded227b7d4' into lxm

weicu
lxm 1 year ago
parent
commit
d3e56ae5f6
  1. 69
      lib/core/utils/permission_util.dart

69
lib/core/utils/permission_util.dart

@ -1,15 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:app_settings/app_settings.dart'; import 'package:app_settings/app_settings.dart';
import 'dart:developer';
import 'logger.dart'; import 'logger.dart';
// class Logger {
// static void e(String tag, String message) {
// debugPrint('[$tag] ERROR: $message');
// }
// }
class PermissionUtil { class PermissionUtil {
static final PermissionUtil instance = PermissionUtil._(); static final PermissionUtil instance = PermissionUtil._();
PermissionUtil._(); PermissionUtil._();
@ -27,18 +20,18 @@ class PermissionUtil {
}) async { }) async {
try { try {
final PermissionStatus status = await permissionType.status; final PermissionStatus status = await permissionType.status;
log('初始权限状态 for $permissionName: $status'); Logger.d('PermissionUtil', '初始权限状态 [$permissionName]: $status');
// 处理已授权状态(包括授予状态和临时通知权限) // 处理已授权状态(包括授予状态和临时通知权限)
if (status == PermissionStatus.granted || if (status == PermissionStatus.granted ||
status == PermissionStatus.provisional) { status == PermissionStatus.provisional) {
log('$permissionName 权限已授予或临时授权。'); Logger.i('PermissionUtil', '$permissionName 权限已授予或临时授权');
return true; return true;
} }
// 处理永久拒绝状态 // 处理永久拒绝状态
if (status == PermissionStatus.permanentlyDenied) { if (status == PermissionStatus.permanentlyDenied) {
log('$permissionName 权限被永久拒绝,显示引导对话框。'); Logger.w('PermissionUtil', '$permissionName 权限被永久拒绝,显示引导对话框');
await _showPermanentDenialDialog( await _showPermanentDenialDialog(
context: context, context: context,
permissionName: permissionName, permissionName: permissionName,
@ -51,7 +44,7 @@ class PermissionUtil {
// 处理初始拒绝/未决定状态 // 处理初始拒绝/未决定状态
if (status == PermissionStatus.denied) { if (status == PermissionStatus.denied) {
log('$permissionName 权限被拒绝或未决定,显示说明横幅并请求。'); Logger.d('PermissionUtil', '$permissionName 权限被拒绝或未决定,显示说明横幅并请求');
_showExplanationOverlay( _showExplanationOverlay(
context: context, context: context,
permissionName: permissionName, permissionName: permissionName,
@ -59,17 +52,17 @@ class PermissionUtil {
); );
final PermissionStatus newStatus = await permissionType.request(); final PermissionStatus newStatus = await permissionType.request();
log('请求后 $permissionName 的新权限状态: $newStatus'); Logger.d('PermissionUtil', '请求后 $permissionName 的新权限状态: $newStatus');
_hideExplanationOverlay(); _hideExplanationOverlay();
// 处理请求后的状态 // 处理请求后的状态
if (newStatus == PermissionStatus.granted || if (newStatus == PermissionStatus.granted ||
newStatus == PermissionStatus.provisional) { newStatus == PermissionStatus.provisional) {
log('$permissionName 权限在请求后被授予或临时授权。'); Logger.i('PermissionUtil', '$permissionName 权限在请求后被授予');
return true; return true;
} else if (newStatus == PermissionStatus.permanentlyDenied) { } else if (newStatus == PermissionStatus.permanentlyDenied) {
log('$permissionName 权限在请求后被永久拒绝,再次显示引导对话框。'); Logger.w('PermissionUtil', '$permissionName 权限在请求后被永久拒绝');
await _showPermanentDenialDialog( await _showPermanentDenialDialog(
context: context, context: context,
permissionName: permissionName, permissionName: permissionName,
@ -84,21 +77,29 @@ class PermissionUtil {
// 处理受限状态 // 处理受限状态
if (status == PermissionStatus.restricted || if (status == PermissionStatus.restricted ||
status == PermissionStatus.limited) { status == PermissionStatus.limited) {
log('$permissionName 权限受限或受限访问: $status'); Logger.w('PermissionUtil', '$permissionName 权限受限或受限访问: $status');
await _showRestrictedPermissionDialog(context, permissionName); await _showRestrictedPermissionDialog(context, permissionName);
return false; return false;
} }
// 其他未知状态处理 // 其他未知状态处理
log('$permissionName 处于未知状态: $status'); Logger.e('PermissionUtil', '$permissionName 处于未知状态: $status');
return false; return false;
} catch (e) { } catch (e, stackTrace) {
Logger.e('PermissionUtil', '请求 $permissionName 权限失败: $e'); Logger.e(
'PermissionUtil',
'请求 $permissionName 权限失败: $e',
e,
stackTrace,
);
_hideExplanationOverlay(); _hideExplanationOverlay();
return false; return false;
} }
} }
/// 显示权限解释横幅(漂浮在UI顶部的说明性UI)
///
/// 在请求权限前显示,向用户解释为什么需要这个权限
void _showExplanationOverlay({ void _showExplanationOverlay({
required BuildContext context, required BuildContext context,
required String permissionName, required String permissionName,
@ -114,7 +115,7 @@ class PermissionUtil {
child: Material( child: Material(
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
elevation: 4, elevation: 4,
color: Colors.white, color: Theme.of(context).colorScheme.background,
child: Padding( child: Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Column( child: Column(
@ -143,16 +144,23 @@ class PermissionUtil {
Future.delayed(Duration.zero, () { Future.delayed(Duration.zero, () {
if (_explanationOverlayEntry != null) { if (_explanationOverlayEntry != null) {
Overlay.of(context).insert(_explanationOverlayEntry!); Overlay.of(context).insert(_explanationOverlayEntry!);
log('权限说明叠加层已显示。'); Logger.i('PermissionUtil', '权限说明叠加层已显示 ($permissionName)');
} }
}); });
} }
/// 隐藏权限解释横幅
void _hideExplanationOverlay() { void _hideExplanationOverlay() {
_explanationOverlayEntry?.remove(); if (_explanationOverlayEntry != null) {
_explanationOverlayEntry = null; _explanationOverlayEntry?.remove();
_explanationOverlayEntry = null;
Logger.d('PermissionUtil', '权限说明叠加层已移除');
}
} }
/// 显示永久拒绝后的设置引导对话框
///
/// 在权限被永久拒绝时调用,提示用户前往设置手动开启权限
Future<void> _showPermanentDenialDialog({ Future<void> _showPermanentDenialDialog({
required BuildContext context, required BuildContext context,
required String permissionName, required String permissionName,
@ -160,6 +168,8 @@ class PermissionUtil {
required String settingsButtonText, required String settingsButtonText,
required String cancelButtonText, required String cancelButtonText,
}) async { }) async {
Logger.i('PermissionUtil', '显示永久拒绝对话框 ($permissionName)');
await showDialog<void>( await showDialog<void>(
context: context, context: context,
barrierDismissible: false, barrierDismissible: false,
@ -168,11 +178,15 @@ class PermissionUtil {
content: Text(permanentDenialText), content: Text(permanentDenialText),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.pop(context), onPressed: () {
Logger.d('PermissionUtil', '用户取消设置 ($permissionName)');
Navigator.pop(context);
},
child: Text(cancelButtonText), child: Text(cancelButtonText),
), ),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
Logger.d('PermissionUtil', '用户同意前往设置 ($permissionName)');
Navigator.pop(context); Navigator.pop(context);
AppSettings.openAppSettings(); AppSettings.openAppSettings();
}, },
@ -183,8 +197,12 @@ class PermissionUtil {
); );
} }
/// 显示受限权限对话框
///
/// 在权限受限状态(如iOS上的受限照片访问)时调用
Future<void> _showRestrictedPermissionDialog( Future<void> _showRestrictedPermissionDialog(
BuildContext context, String permissionName) async { BuildContext context, String permissionName) async {
Logger.w('PermissionUtil', '显示受限权限对话框 ($permissionName)');
await showDialog( await showDialog(
context: context, context: context,
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
@ -192,7 +210,10 @@ class PermissionUtil {
content: const Text('此功能在当前设备上不可用或受限,请检查设备设置或系统限制'), content: const Text('此功能在当前设备上不可用或受限,请检查设备设置或系统限制'),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.pop(context), onPressed: () {
Logger.d('PermissionUtil', '用户确认受限权限 ($permissionName)');
Navigator.pop(context);
},
child: const Text('确定'), child: const Text('确定'),
), ),
], ],

Loading…
Cancel
Save