From 20345cbf74920d49af04cc9fa806c09538267ad8 Mon Sep 17 00:00:00 2001
From: wuqifeng <540416539@qq.com>
Date: Mon, 10 Jul 2023 01:35:34 +0800
Subject: [PATCH] feat:修改头像权限android端优化(权限申请流程还有待优化)
---
android/app/src/main/AndroidManifest.xml | 4 ++++
lib/common/permission/PermissionUtil.dart | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/common/permission/permissionRequestPage.dart | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/pages/reading/bloc/reading_bloc.dart | 2 +-
lib/pages/reading/permissionRequestPage.dart | 189 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
lib/pages/user/modify/user_avatar_bloc/user_avatar_bloc.dart | 15 ++++++++++++++-
6 files changed, 331 insertions(+), 191 deletions(-)
create mode 100644 lib/common/permission/PermissionUtil.dart
create mode 100644 lib/common/permission/permissionRequestPage.dart
delete mode 100644 lib/pages/reading/permissionRequestPage.dart
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 4e58ed2..c2ff064 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -36,6 +36,10 @@
+
+
+
diff --git a/lib/common/permission/PermissionUtil.dart b/lib/common/permission/PermissionUtil.dart
new file mode 100644
index 0000000..c27fbd3
--- /dev/null
+++ b/lib/common/permission/PermissionUtil.dart
@@ -0,0 +1,124 @@
+
+import 'package:flutter/material.dart';
+import 'package:flutter_easyloading/flutter_easyloading.dart';
+import 'package:permission_handler/permission_handler.dart';
+
+///权限检测工具
+class PermissionUtil {
+ static defaultCall(name) {
+ EasyLoading.showToast(name);
+ }
+
+ /// 检测石是否有权限
+ /// [permissionList] 权限申请列表
+ /// [errMsg] 错误信息
+ /// [onSuccess] 全部成功
+ /// [onFailed] 有一个失败
+ /// [goSetting] 前往设置
+ static checkPermission(
+ {required List permissionList,
+ String? errMsg,
+ VoidCallback? onSuccess,
+ VoidCallback? onFailed,
+ VoidCallback? goSetting}) async {
+ ///一个新待申请权限列表
+ List newPermissionList = [];
+
+ ///遍历当前权限申请列表
+ for (Permission permission in permissionList) {
+ PermissionStatus status = await permission.status;
+
+ ///如果不是允许状态就添加到新的申请列表中
+ if (!status.isGranted) {
+ newPermissionList.add(permission);
+ }
+ }
+
+ ///如果需要重新申请的列表不是空的
+ if (newPermissionList.isNotEmpty) {
+ PermissionStatus permissionStatus =
+ await requestPermission(newPermissionList);
+
+ switch (permissionStatus) {
+
+ ///拒绝状态
+ case PermissionStatus.denied:
+ onFailed != null ? onFailed() : defaultCall("权限申请失败");
+ break;
+
+ ///允许状态
+ case PermissionStatus.granted:
+ onSuccess != null ? onSuccess() : defaultCall("权限申请成功");
+ break;
+
+ /// 永久拒绝 活动限制
+ case PermissionStatus.restricted:
+ case PermissionStatus.limited:
+ case PermissionStatus.permanentlyDenied:
+ case PermissionStatus.provisional:
+ goSetting != null
+ ? goSetting( )
+ :await openAppSettings();
+ break;
+ }
+ } else {
+ onSuccess != null ? onSuccess() : defaultCall("权限申请成功");
+ }
+ }
+
+ /// 获取新列表中的权限 如果有一项不合格就返回false
+ static requestPermission(List permissionList) async {
+ Map statuses = await permissionList.request();
+ PermissionStatus currentPermissionStatus = PermissionStatus.granted;
+ statuses.forEach((key, value) {
+ if (!value.isGranted) {
+ currentPermissionStatus = value;
+ return;
+ }
+ });
+ return currentPermissionStatus;
+ }
+
+ static checkLocationAlways(
+ {VoidCallback? onSuccess,
+ VoidCallback? onFailed,
+ VoidCallback? goSetting}) async {
+ ///获取前置状态
+ /// Android没有这一步 ios会先访问这个再访问其他的
+ PermissionStatus status = PermissionStatus.granted;
+ status = await _checkSinglePermission(Permission.locationWhenInUse);
+
+ ///获取第二个状态
+ PermissionStatus status2 = PermissionStatus.denied;
+
+ ///如果前置状态为成功才能执行获取第二个状态
+ if (status.isGranted) {
+ status2 = await _checkSinglePermission(Permission.locationAlways);
+ }
+
+ ///如果两个都成功那么就返回成功
+ if (status.isGranted && status2.isGranted) {
+ onSuccess != null ? onSuccess() : defaultCall("权限申请成功");
+
+ ///如果有一个拒绝那么就失败了
+ } else if (status.isDenied || status2.isDenied) {
+ onFailed != null ? onFailed() : defaultCall("权限申请失败");
+ } else {
+ goSetting != null ? goSetting() : await openAppSettings();
+ }
+ }
+
+ static _checkSinglePermission(Permission permission) async {
+ ///获取当前状态
+ PermissionStatus status = await permission.status;
+ PermissionStatus currentPermissionStatus = PermissionStatus.granted;
+
+ ///如果它状态不是允许那么就去获取
+ if (!status.isGranted) {
+ currentPermissionStatus = await requestPermission([permission]);
+ }
+
+ ///返回最终状态
+ return currentPermissionStatus;
+ }
+}
diff --git a/lib/common/permission/permissionRequestPage.dart b/lib/common/permission/permissionRequestPage.dart
new file mode 100644
index 0000000..c99702a
--- /dev/null
+++ b/lib/common/permission/permissionRequestPage.dart
@@ -0,0 +1,188 @@
+import 'dart:io';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:permission_handler/permission_handler.dart';
+
+import '../../utils/log_util.dart';
+
+/// 权限检查及请求
+/// 外部可通过此方法来进行权限的检查和请求,将自动跳转到`PermissionRequestPage`页面。
+/// 传入 `Permission` 以及对应的权限名称 `permissionTypeStr`,如果有权限则返回 `Future true`
+/// `isRequiredPermission` 如果为 `true`,则 "取消" 按钮将执行 "退出app" 的操作
+Future permissionCheckAndRequest(
+ BuildContext context,
+ Permission permission,
+ String permissionTypeStr,
+ {bool isRequiredPermission = false}) async {
+ if (!await permission.status.isGranted) {
+ await Navigator.of(context).push(PageRouteBuilder(
+ opaque: false,
+ pageBuilder: ((context, animation, secondaryAnimation) {
+ return PermissionRequestPage(permission, permissionTypeStr,
+ isRequiredPermission: isRequiredPermission);
+ })));
+ } else {
+ return true;
+ }
+ return false;
+}
+
+class PermissionRequestPage extends StatefulWidget {
+ const PermissionRequestPage(this.permission, this.permissionTypeStr,
+ {super.key, this.isRequiredPermission = false});
+
+ final Permission permission;
+ final String permissionTypeStr;
+ final bool isRequiredPermission;
+
+ @override
+ State createState() => _PermissionRequestPageState();
+}
+
+class _PermissionRequestPageState extends State
+ with WidgetsBindingObserver {
+ bool _isGoSetting = false;
+ late final List msgList;
+ bool _isDialogShowing = false;
+
+ @override
+ void initState() {
+ super.initState();
+ WidgetsBinding.instance.addObserver(this);
+ msgList = [
+ "${widget.permissionTypeStr}功能需要获取您设备的${widget.permissionTypeStr}权限,否则可能无法正常工作。\n是否申请${widget.permissionTypeStr}权限?",
+ "${widget.permissionTypeStr}权限不全,是否重新申请权限?",
+ "没有${widget.permissionTypeStr}权限,您可以手动开启权限",
+ widget.isRequiredPermission ? "退出应用" : "取消"
+ ];
+ _checkPermission(widget.permission);
+ }
+
+ @override
+ void didChangeAppLifecycleState(AppLifecycleState state) {
+ super.didChangeAppLifecycleState(state);
+ Log.d("didChangeAppLifecycleState state=$state _isGoSetting=$_isGoSetting");
+ // 监听 app 从后台切回前台
+ if (state == AppLifecycleState.resumed && _isGoSetting) {
+ _checkPermission(widget.permission);
+ }
+ }
+
+ /// 校验权限
+ void _checkPermission(Permission permission) async {
+ final PermissionStatus status = await permission.status;
+ _handlePermissionStatus(permission, status);
+ }
+
+ void _handlePermissionStatus(Permission permission, PermissionStatus status) {
+ Log.d('_handlePermissionStatus=$status permission=$permission');
+ if (status.isGranted) {
+ _popPage();
+ return;
+ }
+
+ // 还未申请权限或之前拒绝了权限(在 iOS 上为首次申请权限,拒绝后将变为 `永久拒绝权限`)
+ if (status.isDenied) {
+ showAlert(
+ permission, msgList[0], msgList[3], _isGoSetting ? "前往系统设置" : "确定");
+ }
+ // 权限已被永久拒绝
+ if (status.isPermanentlyDenied) {
+ _isGoSetting = true;
+ showAlert(
+ permission, msgList[2], msgList[3], _isGoSetting ? "前往系统设置" : "确定");
+ }
+ // 拥有部分权限
+ if (status.isLimited) {
+ if (Platform.isIOS || Platform.isMacOS) _isGoSetting = true;
+ showAlert(
+ permission, msgList[1], msgList[3], _isGoSetting ? "前往系统设置" : "确定");
+ }
+ // 拥有部分权限,活动限制(例如,设置了家长///控件,仅在iOS以上受支持。(仅限 iOS)
+ if (status.isRestricted) {
+ if (Platform.isIOS || Platform.isMacOS) _isGoSetting = true;
+ showAlert(
+ permission, msgList[1], msgList[3], _isGoSetting ? "前往系统设置" : "确定");
+ }
+ }
+
+ void showAlert(Permission permission, String message, String cancelMsg,
+ String confirmMsg) {
+ if (_isDialogShowing) {
+ // 对话框已经在显示中,不重复弹出
+ Log.d("对话框已经在显示中,不重复弹出");
+ return;
+ }
+ _isDialogShowing = true;
+ showDialog(
+ context: context,
+ builder: (context) {
+ return AlertDialog(
+ title: const Text("温馨提示"),
+ content: Text(message),
+ actions: [
+ TextButton(
+ child: Text(cancelMsg),
+ onPressed: () {
+ widget.isRequiredPermission
+ ? _quitApp()
+ : _popDialogAndPage(context);
+ }),
+ TextButton(
+ child: Text(confirmMsg),
+ onPressed: () {
+ if (_isGoSetting) {
+ openAppSettings();
+ } else {
+ _requestPermisson(permission);
+ }
+ _popDialog(context);
+ })
+ ],
+ );
+ }).then((value) => {
+ _isDialogShowing = false,
+ });
+ }
+
+ /// 申请权限
+ void _requestPermisson(Permission permission) async {
+ // 申请权限
+ PermissionStatus status = await permission.request();
+ Log.d('requestPermisson权限检测=$status _isGoSetting=$_isGoSetting');
+ // 再次校验
+ _handlePermissionStatus(permission, status);
+ }
+
+ @override
+ void dispose() {
+ WidgetsBinding.instance.removeObserver(this);
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Container();
+ }
+
+ /// 退出应用程序
+ void _quitApp() {
+ SystemChannels.platform.invokeMethod("SystemNavigator.pop");
+ }
+
+ /// 关闭整个权限申请页面
+ void _popDialogAndPage(BuildContext dialogContext) {
+ _popDialog(dialogContext);
+ _popPage();
+ }
+
+ /// 关闭弹窗
+ void _popDialog(BuildContext dialogContext) {
+ Navigator.of(dialogContext).pop();
+ }
+
+ /// 关闭透明页面
+ void _popPage() {
+ Navigator.of(context).pop();
+ }
+}
diff --git a/lib/pages/reading/bloc/reading_bloc.dart b/lib/pages/reading/bloc/reading_bloc.dart
index e4f933f..071c33c 100644
--- a/lib/pages/reading/bloc/reading_bloc.dart
+++ b/lib/pages/reading/bloc/reading_bloc.dart
@@ -14,7 +14,7 @@ import '../../../models/course_process_entity.dart';
import '../../../utils/loading.dart';
import '../../../utils/log_util.dart';
-import '../permissionRequestPage.dart';
+import '../../../common/permission/permissionRequestPage.dart';
part 'reading_event.dart';
part 'reading_state.dart';
diff --git a/lib/pages/reading/permissionRequestPage.dart b/lib/pages/reading/permissionRequestPage.dart
deleted file mode 100644
index cffeb24..0000000
--- a/lib/pages/reading/permissionRequestPage.dart
+++ /dev/null
@@ -1,189 +0,0 @@
-import 'dart:io';
-import 'package:flutter/material.dart';
-import 'package:flutter/services.dart';
-import 'package:permission_handler/permission_handler.dart';
-
-import '../../utils/log_util.dart';
-
-/// 权限检查及请求
-/// 外部可通过此方法来进行权限的检查和请求,将自动跳转到`PermissionRequestPage`页面。
-/// 传入 `Permission` 以及对应的权限名称 `permissionTypeStr`,如果有权限则返回 `Future true`
-/// `isRequiredPermission` 如果为 `true`,则 "取消" 按钮将执行 "退出app" 的操作
-Future permissionCheckAndRequest(
- BuildContext context,
- Permission permission,
- String permissionTypeStr,
- {bool isRequiredPermission = false}) async {
- if (!await permission.status.isGranted) {
- await Navigator.of(context).push(PageRouteBuilder(
- opaque: true,
- barrierColor: const Color.fromRGBO(255, 0, 0, 0.7),
- pageBuilder: ((context, animation, secondaryAnimation) {
- return PermissionRequestPage(permission, permissionTypeStr,
- isRequiredPermission: isRequiredPermission);
- })));
- } else {
- return true;
- }
- return false;
-}
-
-class PermissionRequestPage extends StatefulWidget {
- const PermissionRequestPage(this.permission, this.permissionTypeStr,
- {super.key, this.isRequiredPermission = false});
-
- final Permission permission;
- final String permissionTypeStr;
- final bool isRequiredPermission;
-
- @override
- State createState() => _PermissionRequestPageState();
-}
-
-class _PermissionRequestPageState extends State
- with WidgetsBindingObserver {
- bool _isGoSetting = false;
- late final List msgList;
- bool _isDialogShowing = false;
-
- @override
- void initState() {
- super.initState();
- WidgetsBinding.instance.addObserver(this);
- msgList = [
- "${widget.permissionTypeStr}功能需要获取您设备的${widget.permissionTypeStr}权限,否则可能无法正常工作。\n是否申请${widget.permissionTypeStr}权限?",
- "${widget.permissionTypeStr}权限不全,是否重新申请权限?",
- "没有${widget.permissionTypeStr}权限,您可以手动开启权限",
- widget.isRequiredPermission ? "退出应用" : "取消"
- ];
- _checkPermission(widget.permission);
- }
-
- @override
- void didChangeAppLifecycleState(AppLifecycleState state) {
- super.didChangeAppLifecycleState(state);
- Log.d("didChangeAppLifecycleState state=$state _isGoSetting=$_isGoSetting");
- // 监听 app 从后台切回前台
- if (state == AppLifecycleState.resumed && _isGoSetting) {
- _checkPermission(widget.permission);
- }
- }
-
- /// 校验权限
- void _checkPermission(Permission permission) async {
- final PermissionStatus status = await permission.status;
- _handlePermissionStatus(permission, status);
- }
-
- void _handlePermissionStatus(Permission permission, PermissionStatus status) {
- Log.d('_handlePermissionStatus=$status permission=$permission');
- if (status.isGranted) {
- _popPage();
- return;
- }
-
- // 还未申请权限或之前拒绝了权限(在 iOS 上为首次申请权限,拒绝后将变为 `永久拒绝权限`)
- if (status.isDenied) {
- showAlert(
- permission, msgList[0], msgList[3], _isGoSetting ? "前往系统设置" : "确定");
- }
- // 权限已被永久拒绝
- if (status.isPermanentlyDenied) {
- _isGoSetting = true;
- showAlert(
- permission, msgList[2], msgList[3], _isGoSetting ? "前往系统设置" : "确定");
- }
- // 拥有部分权限
- if (status.isLimited) {
- if (Platform.isIOS || Platform.isMacOS) _isGoSetting = true;
- showAlert(
- permission, msgList[1], msgList[3], _isGoSetting ? "前往系统设置" : "确定");
- }
- // 拥有部分权限,活动限制(例如,设置了家长///控件,仅在iOS以上受支持。(仅限 iOS)
- if (status.isRestricted) {
- if (Platform.isIOS || Platform.isMacOS) _isGoSetting = true;
- showAlert(
- permission, msgList[1], msgList[3], _isGoSetting ? "前往系统设置" : "确定");
- }
- }
-
- void showAlert(Permission permission, String message, String cancelMsg,
- String confirmMsg) {
- if (_isDialogShowing) {
- // 对话框已经在显示中,不重复弹出
- Log.d("对话框已经在显示中,不重复弹出");
- return;
- }
- _isDialogShowing = true;
- showDialog(
- context: context,
- builder: (context) {
- return AlertDialog(
- title: const Text("温馨提示"),
- content: Text(message),
- actions: [
- TextButton(
- child: Text(cancelMsg),
- onPressed: () {
- widget.isRequiredPermission
- ? _quitApp()
- : _popDialogAndPage(context);
- }),
- TextButton(
- child: Text(confirmMsg),
- onPressed: () {
- if (_isGoSetting) {
- openAppSettings();
- } else {
- _requestPermisson(permission);
- }
- _popDialog(context);
- })
- ],
- );
- }).then((value) => {
- _isDialogShowing = false,
- });
- }
-
- /// 申请权限
- void _requestPermisson(Permission permission) async {
- // 申请权限
- PermissionStatus status = await permission.request();
- Log.d('requestPermisson权限检测=$status _isGoSetting=$_isGoSetting');
- // 再次校验
- _handlePermissionStatus(permission, status);
- }
-
- @override
- void dispose() {
- WidgetsBinding.instance.removeObserver(this);
- super.dispose();
- }
-
- @override
- Widget build(BuildContext context) {
- return Container();
- }
-
- /// 退出应用程序
- void _quitApp() {
- SystemChannels.platform.invokeMethod("SystemNavigator.pop");
- }
-
- /// 关闭整个权限申请页面
- void _popDialogAndPage(BuildContext dialogContext) {
- _popDialog(dialogContext);
- _popPage();
- }
-
- /// 关闭弹窗
- void _popDialog(BuildContext dialogContext) {
- Navigator.of(dialogContext).pop();
- }
-
- /// 关闭透明页面
- void _popPage() {
- Navigator.of(context).pop();
- }
-}
diff --git a/lib/pages/user/modify/user_avatar_bloc/user_avatar_bloc.dart b/lib/pages/user/modify/user_avatar_bloc/user_avatar_bloc.dart
index 9347a7e..5a4f6ce 100644
--- a/lib/pages/user/modify/user_avatar_bloc/user_avatar_bloc.dart
+++ b/lib/pages/user/modify/user_avatar_bloc/user_avatar_bloc.dart
@@ -1,3 +1,6 @@
+import 'dart:io';
+
+import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
@@ -99,7 +102,17 @@ class UserAvatarBloc extends Bloc {
///获取相册权限
Future getPhotoPermissionStatus() async {
- Permission permission = Permission.photos;
+ Permission permission;
+ if (Platform.isAndroid) {
+ final androidInfo = await DeviceInfoPlugin().androidInfo;
+ if (androidInfo.version.sdkInt <= 32) {
+ permission = Permission.storage;
+ } else {
+ permission = Permission.photos;
+ }
+ } else {
+ permission = Permission.photos;
+ }
PermissionStatus status = await permission.status;
if (status.isGranted) {
return true;
--
libgit2 0.22.2