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.
336 lines
10 KiB
336 lines
10 KiB
import 'package:get/get.dart';
|
|
import 'package:get_storage/get_storage.dart';
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'dart:io' show Platform;
|
|
import 'package:device_info_plus/device_info_plus.dart';
|
|
import '../../../core/utils/permission_util.dart';
|
|
|
|
class PermissionsController extends GetxController {
|
|
// 权限状态映射
|
|
final RxMap<Permission, PermissionStatus> permissionStatuses =
|
|
<Permission, PermissionStatus>{}.obs;
|
|
|
|
// 是否正在请求权限
|
|
final RxBool isRequestingPermission = false.obs;
|
|
|
|
// Android版本信息(用于权限组显示判断)
|
|
final RxInt androidSdkVersion = 0.obs;
|
|
|
|
final GetStorage _storage = GetStorage();
|
|
bool? _isCalendarFullAccess;
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
_isCalendarFullAccess = _storage.read('record_permission_calendar');
|
|
_initAndroidVersion();
|
|
checkAllPermissions();
|
|
}
|
|
|
|
/// 初始化Android版本信息
|
|
Future<void> _initAndroidVersion() async {
|
|
if (Platform.isAndroid) {
|
|
try {
|
|
final deviceInfo = DeviceInfoPlugin();
|
|
final androidInfo = await deviceInfo.androidInfo;
|
|
androidSdkVersion.value = androidInfo.version.sdkInt;
|
|
} catch (e) {
|
|
print('获取Android版本信息失败: $e');
|
|
androidSdkVersion.value = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 检查是否应该显示蓝牙权限组
|
|
bool shouldShowBluetoothPermissions() {
|
|
if (Platform.isAndroid) {
|
|
// Android 12+ (API 31+) 才显示蓝牙权限组
|
|
return androidSdkVersion.value >= 31;
|
|
} else if (Platform.isIOS) {
|
|
// iOS显示蓝牙权限组
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// 检查是否应该显示存储权限组
|
|
bool shouldShowStoragePermissions() {
|
|
if (Platform.isAndroid) {
|
|
// Android 10及以下版本 (API 29及以下) 才显示存储权限组
|
|
return androidSdkVersion.value <= 29 && androidSdkVersion.value > 0;
|
|
}
|
|
// iOS系统不显示存储权限组
|
|
return false;
|
|
}
|
|
|
|
/// 检查所有权限状态
|
|
Future<Map<Permission, PermissionStatus>> checkAllPermissions() async {
|
|
final Map<Permission, PermissionStatus> statuses = {};
|
|
|
|
// 根据平台获取需要检查的权限列表
|
|
final permissions = await _getPlatformPermissions();
|
|
|
|
for (final permission in permissions) {
|
|
try {
|
|
if (Platform.isIOS &&
|
|
permission == Permission.calendarFullAccess &&
|
|
_isCalendarFullAccess == true) {
|
|
PermissionStatus calendarStatus = await permission.status;
|
|
if (calendarStatus == PermissionStatus.denied) {
|
|
statuses[permission] = PermissionStatus.granted;
|
|
} else {
|
|
statuses[permission] = await permission.status;
|
|
_storage.write('record_permission_calendar', false);
|
|
}
|
|
} else {
|
|
statuses[permission] = await permission.status;
|
|
}
|
|
print('Permission: $permission, Status: ${statuses[permission]}');
|
|
} catch (e) {
|
|
// 某些权限在特定平台可能不支持,设置为拒绝状态
|
|
statuses[permission] = PermissionStatus.denied;
|
|
}
|
|
}
|
|
|
|
permissionStatuses.value = statuses;
|
|
return statuses;
|
|
}
|
|
|
|
/// 获取蓝牙权限列表(根据Android版本)
|
|
Future<List<Permission>> _getBluetoothPermissions() async {
|
|
if (Platform.isAndroid) {
|
|
try {
|
|
final deviceInfo = DeviceInfoPlugin();
|
|
final androidInfo = await deviceInfo.androidInfo;
|
|
// Android 12+ (API 31+) 使用新的蓝牙权限
|
|
if (androidInfo.version.sdkInt >= 31) {
|
|
return [
|
|
Permission.bluetoothScan,
|
|
Permission.bluetoothConnect,
|
|
];
|
|
}
|
|
// Android 12以下不显示蓝牙权限(因为会自动授予)
|
|
return [];
|
|
} catch (e) {
|
|
print('获取Android版本信息失败: $e');
|
|
return [];
|
|
}
|
|
}
|
|
return [];
|
|
}
|
|
|
|
/// 获取平台特定的权限列表
|
|
Future<List<Permission>> _getPlatformPermissions() async {
|
|
final bluetoothPermissions = await _getBluetoothPermissions();
|
|
|
|
if (Platform.isIOS) {
|
|
final List<Permission> permissions = [
|
|
Permission.calendarFullAccess,
|
|
Permission.location,
|
|
Permission.contacts,
|
|
//...bluetoothPermissions,
|
|
Permission.notification,
|
|
Permission.microphone,
|
|
];
|
|
|
|
// iOS系统不添加存储权限(根据shouldShowStoragePermissions方法)
|
|
if (shouldShowStoragePermissions()) {
|
|
permissions.add(Permission.storage);
|
|
}
|
|
|
|
return permissions;
|
|
} else if (Platform.isAndroid) {
|
|
final List<Permission> permissions = [
|
|
Permission.calendarFullAccess,
|
|
Permission.location,
|
|
Permission.phone,
|
|
Permission.sms,
|
|
Permission.contacts,
|
|
...bluetoothPermissions,
|
|
Permission.notification,
|
|
Permission.scheduleExactAlarm,
|
|
Permission.microphone,
|
|
];
|
|
|
|
// 只在Android 10及以下版本添加存储权限
|
|
if (shouldShowStoragePermissions()) {
|
|
permissions.add(Permission.storage);
|
|
}
|
|
|
|
return permissions;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
/// 请求单个权限
|
|
Future<bool> requestPermission(Permission permission) async {
|
|
if (isRequestingPermission.value) return false;
|
|
|
|
isRequestingPermission.value = true;
|
|
|
|
try {
|
|
final permissionName = getPermissionName(permission);
|
|
final explanationText = _getDetailedDescription(permission);
|
|
|
|
final hasPermission = await PermissionUtil.instance.requestPermission(
|
|
permissionType: permission,
|
|
permissionName: permissionName,
|
|
explanationText: explanationText,
|
|
permanentDenialText:
|
|
'permanentDenialText'.tr.replaceAll('{permission}', permissionName),
|
|
settingsButtonText: 'goToSettings'.tr,
|
|
cancelButtonText: 'cancel'.tr,
|
|
);
|
|
|
|
if (hasPermission) {
|
|
// _showSuccessMessage();
|
|
if (Platform.isIOS && permission == Permission.calendarFullAccess) {
|
|
if (_isCalendarFullAccess == null) {
|
|
_storage.write('record_permission_calendar', true);
|
|
_isCalendarFullAccess = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 刷新权限状态
|
|
await checkAllPermissions();
|
|
|
|
return hasPermission;
|
|
} catch (e) {
|
|
_showErrorMessage();
|
|
return false;
|
|
} finally {
|
|
isRequestingPermission.value = false;
|
|
}
|
|
}
|
|
|
|
/// 打开系统设置
|
|
void openSettings() {
|
|
openAppSettings();
|
|
}
|
|
|
|
/// 获取权限的用户友好名称
|
|
String getPermissionName(Permission permission) {
|
|
switch (permission) {
|
|
case Permission.phone:
|
|
return 'phone'.tr;
|
|
case Permission.sms:
|
|
return 'sms'.tr;
|
|
case Permission.contacts:
|
|
return 'contacts'.tr;
|
|
case Permission.bluetooth:
|
|
return 'bluetooth'.tr;
|
|
case Permission.bluetoothScan:
|
|
return 'bluetoothScan'.tr;
|
|
case Permission.bluetoothConnect:
|
|
return 'bluetoothConnect'.tr;
|
|
case Permission.notification:
|
|
return 'notification'.tr;
|
|
case Permission.calendarWriteOnly:
|
|
return 'calendarWrite'.tr;
|
|
case Permission.calendarFullAccess:
|
|
return 'calendarFullAccess'.tr;
|
|
case Permission.location:
|
|
return 'locationInfo'.tr;
|
|
case Permission.scheduleExactAlarm:
|
|
return 'alarm'.tr;
|
|
case Permission.storage:
|
|
return 'storagePermission'.tr;
|
|
case Permission.microphone:
|
|
return 'microphonePermission'.tr;
|
|
default:
|
|
return permission.toString();
|
|
}
|
|
}
|
|
|
|
/// 获取权限说明文本
|
|
String _getDetailedDescription(Permission permission) {
|
|
switch (permission) {
|
|
case Permission.phone:
|
|
return 'phonePermissionDetailDesc'.tr;
|
|
case Permission.sms:
|
|
return 'smsPermissionDetailDesc'.tr;
|
|
case Permission.contacts:
|
|
return 'contactsPermissionDetailDesc'.tr;
|
|
case Permission.bluetooth:
|
|
return 'bluetoothPermissionDetailDesc'.tr;
|
|
case Permission.bluetoothScan:
|
|
return 'bluetoothScanPermissionDetailDesc'.tr;
|
|
case Permission.bluetoothConnect:
|
|
return 'bluetoothConnectPermissionDetailDesc'.tr;
|
|
case Permission.notification:
|
|
return 'notificationPermissionDetailDesc'.tr;
|
|
case Permission.calendarWriteOnly:
|
|
return 'calendarWritePermissionDetailDesc'.tr;
|
|
case Permission.calendarFullAccess:
|
|
return 'calendarFullAccessPermissionDetailDesc'.tr;
|
|
case Permission.location:
|
|
return 'locationPermissionDetailDesc'.tr;
|
|
case Permission.scheduleExactAlarm:
|
|
return 'alarmPermissionDetailDesc'.tr;
|
|
case Permission.storage:
|
|
return 'storagePermissionExplanation'.tr;
|
|
case Permission.microphone:
|
|
return 'microphonePermissionExplanation'.tr;
|
|
default:
|
|
return 'appNeedsPermissionForFullFunction'.tr;
|
|
}
|
|
}
|
|
|
|
/// 获取权限描述
|
|
String getPermissionDescription(Permission permission) {
|
|
switch (permission) {
|
|
case Permission.phone:
|
|
return 'phonePermissionDesc'.tr;
|
|
case Permission.sms:
|
|
return 'smsPermissionDesc'.tr;
|
|
case Permission.contacts:
|
|
return 'contactsPermissionDesc'.tr;
|
|
case Permission.bluetooth:
|
|
return 'bluetoothPermissionDesc'.tr;
|
|
case Permission.bluetoothScan:
|
|
return 'bluetoothScanPermissionDesc'.tr;
|
|
case Permission.bluetoothConnect:
|
|
return 'bluetoothConnectPermissionDesc'.tr;
|
|
case Permission.notification:
|
|
return 'notificationPermissionDesc'.tr;
|
|
case Permission.calendarWriteOnly:
|
|
return 'calendarWritePermissionDesc'.tr;
|
|
case Permission.calendarFullAccess:
|
|
return 'calendarFullAccessPermissionDesc'.tr;
|
|
case Permission.location:
|
|
return 'locationPermissionDesc'.tr;
|
|
case Permission.scheduleExactAlarm:
|
|
return 'alarmPermissionDesc'.tr;
|
|
case Permission.storage:
|
|
return 'storagePermissionExplanation'.tr;
|
|
case Permission.microphone:
|
|
return 'microphonePermissionExplanation'.tr;
|
|
default:
|
|
return 'appFunctionNeeds'.tr;
|
|
}
|
|
}
|
|
|
|
/// 显示成功消息
|
|
void _showSuccessMessage() {
|
|
Get.snackbar(
|
|
'success'.tr,
|
|
'permissionGranted'.tr,
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
backgroundColor: Colors.green,
|
|
colorText: Colors.white,
|
|
);
|
|
}
|
|
|
|
/// 显示错误消息
|
|
void _showErrorMessage() {
|
|
Get.snackbar(
|
|
'error'.tr,
|
|
'permissionRequestError'.tr,
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
backgroundColor: Colors.red,
|
|
colorText: Colors.white,
|
|
);
|
|
}
|
|
}
|
|
|