|
|
@ -2,67 +2,149 @@ import 'package:get/get.dart'; |
|
|
import 'package:permission_handler/permission_handler.dart'; |
|
|
import 'package:permission_handler/permission_handler.dart'; |
|
|
import 'package:flutter/material.dart'; |
|
|
import 'package:flutter/material.dart'; |
|
|
import 'dart:io' show Platform; |
|
|
import 'dart:io' show Platform; |
|
|
|
|
|
import 'package:device_info_plus/device_info_plus.dart'; |
|
|
import '../../../core/utils/permission_util.dart'; |
|
|
import '../../../core/utils/permission_util.dart'; |
|
|
|
|
|
|
|
|
class PermissionsController extends GetxController { |
|
|
class PermissionsController extends GetxController { |
|
|
// 权限状态映射 |
|
|
// 权限状态映射 |
|
|
final RxMap<Permission, PermissionStatus> permissionStatuses = |
|
|
final RxMap<Permission, PermissionStatus> permissionStatuses = |
|
|
<Permission, PermissionStatus>{}.obs; |
|
|
<Permission, PermissionStatus>{}.obs; |
|
|
|
|
|
|
|
|
// 是否正在请求权限 |
|
|
// 是否正在请求权限 |
|
|
final RxBool isRequestingPermission = false.obs; |
|
|
final RxBool isRequestingPermission = false.obs; |
|
|
|
|
|
|
|
|
|
|
|
// Android版本信息(用于权限组显示判断) |
|
|
|
|
|
final RxInt androidSdkVersion = 0.obs; |
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
|
void onInit() { |
|
|
void onInit() { |
|
|
super.onInit(); |
|
|
super.onInit(); |
|
|
|
|
|
_initAndroidVersion(); |
|
|
checkAllPermissions(); |
|
|
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 { |
|
|
Future<Map<Permission, PermissionStatus>> checkAllPermissions() async { |
|
|
final Map<Permission, PermissionStatus> statuses = {}; |
|
|
final Map<Permission, PermissionStatus> statuses = {}; |
|
|
|
|
|
|
|
|
// 根据平台获取需要检查的权限列表 |
|
|
// 根据平台获取需要检查的权限列表 |
|
|
final permissions = _getPlatformPermissions(); |
|
|
final permissions = await _getPlatformPermissions(); |
|
|
|
|
|
|
|
|
for (final permission in permissions) { |
|
|
for (final permission in permissions) { |
|
|
try { |
|
|
try { |
|
|
statuses[permission] = await permission.status; |
|
|
statuses[permission] = await permission.status; |
|
|
|
|
|
print('Permission: $permission, Status: ${statuses[permission]}'); |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
// 某些权限在特定平台可能不支持,设置为拒绝状态 |
|
|
// 某些权限在特定平台可能不支持,设置为拒绝状态 |
|
|
statuses[permission] = PermissionStatus.denied; |
|
|
statuses[permission] = PermissionStatus.denied; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
permissionStatuses.value = statuses; |
|
|
permissionStatuses.value = statuses; |
|
|
return 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 []; |
|
|
|
|
|
} |
|
|
|
|
|
} else if (Platform.isIOS) { |
|
|
|
|
|
// iOS使用基本蓝牙权限 |
|
|
|
|
|
return [Permission.bluetooth]; |
|
|
|
|
|
} |
|
|
|
|
|
return []; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/// 获取平台特定的权限列表 |
|
|
/// 获取平台特定的权限列表 |
|
|
List<Permission> _getPlatformPermissions() { |
|
|
Future<List<Permission>> _getPlatformPermissions() async { |
|
|
|
|
|
final bluetoothPermissions = await _getBluetoothPermissions(); |
|
|
|
|
|
|
|
|
if (Platform.isIOS) { |
|
|
if (Platform.isIOS) { |
|
|
return [ |
|
|
final List<Permission> permissions = [ |
|
|
Permission.calendarFullAccess, |
|
|
Permission.calendarFullAccess, |
|
|
Permission.location, |
|
|
Permission.location, |
|
|
Permission.contacts, |
|
|
Permission.contacts, |
|
|
Permission.bluetooth, |
|
|
...bluetoothPermissions, |
|
|
Permission.notification, |
|
|
Permission.notification, |
|
|
Permission.storage, |
|
|
|
|
|
Permission.microphone, |
|
|
Permission.microphone, |
|
|
]; |
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
// iOS系统不添加存储权限(根据shouldShowStoragePermissions方法) |
|
|
|
|
|
if (shouldShowStoragePermissions()) { |
|
|
|
|
|
permissions.add(Permission.storage); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return permissions; |
|
|
} else if (Platform.isAndroid) { |
|
|
} else if (Platform.isAndroid) { |
|
|
return [ |
|
|
final List<Permission> permissions = [ |
|
|
Permission.calendarFullAccess, |
|
|
Permission.calendarFullAccess, |
|
|
Permission.location, |
|
|
Permission.location, |
|
|
Permission.phone, |
|
|
Permission.phone, |
|
|
Permission.sms, |
|
|
Permission.sms, |
|
|
Permission.contacts, |
|
|
Permission.contacts, |
|
|
Permission.bluetooth, |
|
|
...bluetoothPermissions, |
|
|
Permission.notification, |
|
|
Permission.notification, |
|
|
Permission.scheduleExactAlarm, |
|
|
Permission.scheduleExactAlarm, |
|
|
Permission.storage, |
|
|
|
|
|
Permission.microphone, |
|
|
Permission.microphone, |
|
|
]; |
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
// 只在Android 10及以下版本添加存储权限 |
|
|
|
|
|
if (shouldShowStoragePermissions()) { |
|
|
|
|
|
permissions.add(Permission.storage); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return permissions; |
|
|
} |
|
|
} |
|
|
return []; |
|
|
return []; |
|
|
} |
|
|
} |
|
|
@ -70,9 +152,9 @@ class PermissionsController extends GetxController { |
|
|
/// 请求单个权限 |
|
|
/// 请求单个权限 |
|
|
Future<bool> requestPermission(Permission permission) async { |
|
|
Future<bool> requestPermission(Permission permission) async { |
|
|
if (isRequestingPermission.value) return false; |
|
|
if (isRequestingPermission.value) return false; |
|
|
|
|
|
|
|
|
isRequestingPermission.value = true; |
|
|
isRequestingPermission.value = true; |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
final permissionName = getPermissionName(permission); |
|
|
final permissionName = getPermissionName(permission); |
|
|
final explanationText = _getDetailedDescription(permission); |
|
|
final explanationText = _getDetailedDescription(permission); |
|
|
@ -81,8 +163,8 @@ class PermissionsController extends GetxController { |
|
|
permissionType: permission, |
|
|
permissionType: permission, |
|
|
permissionName: permissionName, |
|
|
permissionName: permissionName, |
|
|
explanationText: explanationText, |
|
|
explanationText: explanationText, |
|
|
permanentDenialText: 'permanentDenialText'.tr.replaceAll( |
|
|
permanentDenialText: |
|
|
'{permission}', permissionName), |
|
|
'permanentDenialText'.tr.replaceAll('{permission}', permissionName), |
|
|
settingsButtonText: 'goToSettings'.tr, |
|
|
settingsButtonText: 'goToSettings'.tr, |
|
|
cancelButtonText: 'cancel'.tr, |
|
|
cancelButtonText: 'cancel'.tr, |
|
|
); |
|
|
); |
|
|
@ -93,7 +175,7 @@ class PermissionsController extends GetxController { |
|
|
|
|
|
|
|
|
// 刷新权限状态 |
|
|
// 刷新权限状态 |
|
|
await checkAllPermissions(); |
|
|
await checkAllPermissions(); |
|
|
|
|
|
|
|
|
return hasPermission; |
|
|
return hasPermission; |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
_showErrorMessage(); |
|
|
_showErrorMessage(); |
|
|
@ -119,6 +201,10 @@ class PermissionsController extends GetxController { |
|
|
return 'contacts'.tr; |
|
|
return 'contacts'.tr; |
|
|
case Permission.bluetooth: |
|
|
case Permission.bluetooth: |
|
|
return 'bluetooth'.tr; |
|
|
return 'bluetooth'.tr; |
|
|
|
|
|
case Permission.bluetoothScan: |
|
|
|
|
|
return 'bluetoothScan'.tr; |
|
|
|
|
|
case Permission.bluetoothConnect: |
|
|
|
|
|
return 'bluetoothConnect'.tr; |
|
|
case Permission.notification: |
|
|
case Permission.notification: |
|
|
return 'notification'.tr; |
|
|
return 'notification'.tr; |
|
|
case Permission.calendarWriteOnly: |
|
|
case Permission.calendarWriteOnly: |
|
|
@ -149,6 +235,10 @@ class PermissionsController extends GetxController { |
|
|
return 'contactsPermissionDetailDesc'.tr; |
|
|
return 'contactsPermissionDetailDesc'.tr; |
|
|
case Permission.bluetooth: |
|
|
case Permission.bluetooth: |
|
|
return 'bluetoothPermissionDetailDesc'.tr; |
|
|
return 'bluetoothPermissionDetailDesc'.tr; |
|
|
|
|
|
case Permission.bluetoothScan: |
|
|
|
|
|
return 'bluetoothScanPermissionDetailDesc'.tr; |
|
|
|
|
|
case Permission.bluetoothConnect: |
|
|
|
|
|
return 'bluetoothConnectPermissionDetailDesc'.tr; |
|
|
case Permission.notification: |
|
|
case Permission.notification: |
|
|
return 'notificationPermissionDetailDesc'.tr; |
|
|
return 'notificationPermissionDetailDesc'.tr; |
|
|
case Permission.calendarWriteOnly: |
|
|
case Permission.calendarWriteOnly: |
|
|
@ -179,6 +269,10 @@ class PermissionsController extends GetxController { |
|
|
return 'contactsPermissionDesc'.tr; |
|
|
return 'contactsPermissionDesc'.tr; |
|
|
case Permission.bluetooth: |
|
|
case Permission.bluetooth: |
|
|
return 'bluetoothPermissionDesc'.tr; |
|
|
return 'bluetoothPermissionDesc'.tr; |
|
|
|
|
|
case Permission.bluetoothScan: |
|
|
|
|
|
return 'bluetoothScanPermissionDesc'.tr; |
|
|
|
|
|
case Permission.bluetoothConnect: |
|
|
|
|
|
return 'bluetoothConnectPermissionDesc'.tr; |
|
|
case Permission.notification: |
|
|
case Permission.notification: |
|
|
return 'notificationPermissionDesc'.tr; |
|
|
return 'notificationPermissionDesc'.tr; |
|
|
case Permission.calendarWriteOnly: |
|
|
case Permission.calendarWriteOnly: |
|
|
@ -219,4 +313,4 @@ class PermissionsController extends GetxController { |
|
|
colorText: Colors.white, |
|
|
colorText: Colors.white, |
|
|
); |
|
|
); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|