初始化
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:hgdj/tools_base/widget/common_alert.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
import '../tools_base/toast.dart';
|
||||
|
||||
class PermissionUtil {
|
||||
static Future<bool> checkPhotoPermission() async {
|
||||
final Permission permission;
|
||||
if (Platform.isIOS || Platform.isMacOS) {
|
||||
permission = Permission.photos;
|
||||
} else {
|
||||
final androidInfo = await DeviceInfoPlugin().androidInfo;
|
||||
// 按 API 级别(sdkInt)判断:Android 13(API 33)起用照片权限,以下用存储权限。
|
||||
// 不能用 version.release(营销版本号字符串,ROM 可能写成 "12L" 等致解析跑偏)
|
||||
permission = androidInfo.version.sdkInt < 33
|
||||
? Permission.storage
|
||||
: Permission.photos;
|
||||
}
|
||||
return _ensure(permission, '需要相册权限才能继续');
|
||||
}
|
||||
|
||||
static Future<bool> checkPhotoAddOnlyPermission() async {
|
||||
final permission = (Platform.isIOS || Platform.isMacOS)
|
||||
? Permission.photosAddOnly
|
||||
: Permission.storage;
|
||||
return _ensure(permission, '需要相册权限才能继续');
|
||||
}
|
||||
|
||||
static Future<bool> checkCameraPermission() async {
|
||||
return _ensure(Permission.camera, '需要相机权限才能继续');
|
||||
}
|
||||
|
||||
/// 先查状态再决定,避免对已永久拒绝的权限再 request()(部分机型不弹框/不正常返回):
|
||||
/// 已授权(含受限相册)放行;永久拒绝/受限直接引导去设置;普通拒绝才弹系统授权框。
|
||||
static Future<bool> _ensure(Permission permission, String denyTip) async {
|
||||
final status = await permission.status;
|
||||
if (status.isGranted || status.isLimited) return true;
|
||||
// 注意:Android 上 status.isPermanentlyDenied 在「从未请求过」时也会为 true
|
||||
// (内部靠 shouldShowRequestRationale 判断,没问过和永久拒绝都返回 false,区分不开),
|
||||
// 会误判成永久拒绝、不弹框直接去设置。所以 Android 一律先 request(),
|
||||
// 由系统决定弹框还是立即返回结果;iOS/macOS 的 status 可靠,永久拒绝/受限直接去设置。
|
||||
// 前提:申请的权限必须已在 AndroidManifest 声明,否则 request() 会立即返回 denied 不弹框。
|
||||
if ((Platform.isIOS || Platform.isMacOS) &&
|
||||
(status.isPermanentlyDenied || status.isRestricted)) {
|
||||
_toSettings();
|
||||
return false;
|
||||
}
|
||||
// 普通拒绝/未询问(及 Android 全部情况):弹系统授权框,结果再统一处理
|
||||
return _handleStatus(await permission.request(), denyTip: denyTip);
|
||||
}
|
||||
|
||||
/// 处理 request() 后的结果:授权放行;永久拒绝引导去设置;普通拒绝弹 toast,
|
||||
/// 下次仍会弹系统授权框,避免误报"已禁止权限"
|
||||
static bool _handleStatus(PermissionStatus status,
|
||||
{String denyTip = '未授权,无法继续'}) {
|
||||
if (status.isGranted || status.isLimited) return true;
|
||||
if (status.isPermanentlyDenied || status.isRestricted) {
|
||||
_toSettings();
|
||||
} else {
|
||||
showToast(denyTip); //普通拒绝给个提示,避免点了没反应
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// 引导去系统设置手动开启
|
||||
static void _toSettings() {
|
||||
CommonAlert.show(
|
||||
content: '您已禁止权限,需要去设置页面手动开启才能继续使用',
|
||||
cancelText: '重试',
|
||||
confirmText: '去设置',
|
||||
barrierDismissible: false, //必须点按钮,点遮罩关掉会以为处理过了
|
||||
).then((toSettings) {
|
||||
if (toSettings) openAppSettings();
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user