permission_engine.dart 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. import 'package:flutter/material.dart';
  2. import 'package:permission_handler/permission_handler.dart';
  3. import 'package:photo_manager/photo_manager.dart';
  4. import 'package:shared/utils/device_utils.dart';
  5. import 'package:shared/utils/log_utils.dart';
  6. import 'package:widgets/dialog/app_default_dialog.dart';
  7. import 'package:widgets/dialog/permission_desc_dialog.dart';
  8. import '../../channel/native_version_channel.dart';
  9. import '../dialog/dialog_engine.dart';
  10. /*
  11. * 动态权限的申请与校验
  12. */
  13. class PermissionEngine {
  14. // 私有构造函数
  15. PermissionEngine._privateConstructor();
  16. // 单例实例
  17. static final PermissionEngine _instance = PermissionEngine._privateConstructor();
  18. // 获取单例实例的访问点
  19. factory PermissionEngine() {
  20. return _instance;
  21. }
  22. /// 申请多媒体相册权限
  23. void requestPhotosPermission(void Function() success) async {
  24. //相册的选项
  25. if (DeviceUtils.isIOS) {
  26. //申请授权
  27. final value = await PhotoManager.requestPermissionExtend();
  28. if (value.hasAccess) {
  29. //已授权
  30. Log.d("相册已授权");
  31. success();
  32. } else if (value == PermissionState.limited) {
  33. Log.d("相册访问受限,去设置受限");
  34. PhotoManager.presentLimited();
  35. } else {
  36. Log.d("相册无授权,去设置");
  37. DialogEngine.show(
  38. widget: AppDefaultDialog(
  39. title: "Alert",
  40. message: 'No album permission, go to settings?',
  41. confirmAction: () {
  42. PhotoManager.openSetting();
  43. },
  44. ),
  45. );
  46. }
  47. } else {
  48. //Android的图片选择权限校验,
  49. final androidSdkInt = await NativeVersionChannel.getAndroidSdkInt();
  50. //根据Android版本判断
  51. Permission permission;
  52. if (androidSdkInt >= 33) {
  53. // Android 13 (Tiramisu) 及以上
  54. permission = Permission.mediaLibrary;
  55. } else if (androidSdkInt >= 29) {
  56. // Android 10 (Q) 及以上
  57. permission = Permission.photos;
  58. } else {
  59. permission = Permission.storage;
  60. }
  61. final status = await permission.status;
  62. Log.d("status:$status androidSdkInt:$androidSdkInt");
  63. late PermissionState ps;
  64. if (status.isGranted) {
  65. // 已经授权
  66. success();
  67. } else {
  68. // 未授权,则准备发起一次申请
  69. var permissionRequestFuture = PhotoManager.requestPermissionExtend();
  70. // 延迟500毫秒的Future
  71. var delayFuture = Future.delayed(const Duration(milliseconds: 500), () => 'delay');
  72. // 使用Future.any等待上述两个Future中的任何一个完成
  73. var firstCompleted = await Future.any([permissionRequestFuture, delayFuture]);
  74. // 判断响应结果
  75. if (firstCompleted == 'delay') {
  76. Log.d("判断响应结果:1");
  77. // 如果是延迟Future完成了,表示500毫秒内没有获得权限响应,显示对话框
  78. _showPermissionDialog(
  79. "“YYHome” would like to access your multimedia album for functions such as image uploading and saving. Please allow me to obtain your permission");
  80. // 再次等待权限请求结果
  81. ps = await permissionRequestFuture;
  82. DialogEngine.dismiss(tag: "permission");
  83. } else {
  84. Log.d("判断响应结果:2");
  85. // 权限请求已完成,立刻取消对话框展示(如果已经展示的话)
  86. DialogEngine.dismiss(tag: "permission");
  87. ps = firstCompleted as PermissionState;
  88. }
  89. if (ps.isAuth) {
  90. // 用户授权
  91. success();
  92. } else {
  93. // 权限被拒绝
  94. await DialogEngine.show(
  95. widget: AppDefaultDialog(
  96. message: "Please set the permission to open the photo album on your phone",
  97. title: "Alert",
  98. confirmAction: () {
  99. openAppSettings();
  100. }),
  101. );
  102. }
  103. }
  104. }
  105. }
  106. // 检查是否有可访问媒体
  107. Future<bool> _checkMediaAccess() async {
  108. try {
  109. final albums = await PhotoManager.getAssetPathList();
  110. return albums.isNotEmpty;
  111. } catch (e) {
  112. return false;
  113. }
  114. }
  115. /// 申请相机权限
  116. void requestCameraPermission(void Function() success) async {
  117. // 获取当前的权限
  118. var status = await Permission.camera.status;
  119. if (status.isGranted) {
  120. // 已经授权
  121. success();
  122. } else {
  123. // 未授权,则准备发起一次申请
  124. var permissionRequestFuture = Permission.camera.request();
  125. // 延迟500毫秒的Future
  126. var delayFuture = Future.delayed(const Duration(milliseconds: 500), () => 'delay');
  127. // 使用Future.any等待上述两个Future中的任何一个完成
  128. var firstCompleted = await Future.any([permissionRequestFuture, delayFuture]);
  129. // 判断响应结果
  130. if (firstCompleted == 'delay') {
  131. // 如果是延迟Future完成了,表示500毫秒内没有获得权限响应,显示对话框
  132. _showPermissionDialog(
  133. "“YYHome” requests to use your camera permission for functions such as taking avatars, uploading and saving images. Please allow me to obtain your permission");
  134. // 再次等待权限请求结果
  135. status = await permissionRequestFuture;
  136. DialogEngine.dismiss(tag: "permission");
  137. } else {
  138. // 权限请求已完成,立刻取消对话框展示(如果已经展示的话)
  139. DialogEngine.dismiss(tag: "permission");
  140. status = firstCompleted as PermissionStatus;
  141. }
  142. if (status.isGranted) {
  143. // 用户授权
  144. success();
  145. } else {
  146. // 权限被拒绝
  147. await DialogEngine.show(
  148. widget: AppDefaultDialog(
  149. message: "Please set the permission to open the camera on your phone",
  150. title: "Alert",
  151. confirmAction: () {
  152. openAppSettings();
  153. }),
  154. );
  155. }
  156. }
  157. }
  158. /// 校验并申请定位权限
  159. Future<bool> requestLocationPermission() async {
  160. // 获取当前的权限
  161. var status = await Permission.location.status;
  162. if (status.isGranted) {
  163. // 已经授权
  164. return true;
  165. } else {
  166. // 未授权,则准备发起一次申请
  167. var permissionRequestFuture = Permission.location.request();
  168. // 延迟500毫秒的Future
  169. var delayFuture = Future.delayed(const Duration(milliseconds: 500), () => 'delay');
  170. // 使用Future.any等待上述两个Future中的任何一个完成
  171. var firstCompleted = await Future.any([permissionRequestFuture, delayFuture]);
  172. // 判断响应结果
  173. if (firstCompleted == 'delay') {
  174. // 如果是延迟Future完成了,表示500毫秒内没有获得权限响应,显示对话框
  175. _showPermissionDialog("“YYHome” want to access your location permission to obtain your location and recommend nearby information");
  176. // 再次等待权限请求结果
  177. status = await permissionRequestFuture;
  178. DialogEngine.dismiss(tag: "permission");
  179. } else {
  180. Log.d("权限请求已完成,立刻取消对话框展示");
  181. // 权限请求已完成,立刻取消对话框展示(如果已经展示的话)
  182. DialogEngine.dismiss(tag: "permission");
  183. status = firstCompleted as PermissionStatus;
  184. }
  185. if (status.isGranted) {
  186. // 用户授权
  187. return true;
  188. } else {
  189. // 权限被拒绝
  190. await DialogEngine.show(
  191. widget: AppDefaultDialog(
  192. message: "Please go to your phone settings to enable location permission",
  193. title: "Alert",
  194. confirmAction: () {
  195. openAppSettings();
  196. }),
  197. );
  198. return false;
  199. }
  200. }
  201. }
  202. /// 申请拨打电话权限
  203. void requestCallPhonePermission(void Function() success) async {
  204. // 获取当前的权限
  205. var status = await Permission.phone.status;
  206. if (status.isGranted) {
  207. // 已经授权
  208. success();
  209. } else {
  210. // 未授权,则准备发起一次申请
  211. var permissionRequestFuture = Permission.phone.request();
  212. // 延迟500毫秒的Future
  213. var delayFuture = Future.delayed(const Duration(milliseconds: 500), () => 'delay');
  214. // 使用Future.any等待上述两个Future中的任何一个完成
  215. var firstCompleted = await Future.any([permissionRequestFuture, delayFuture]);
  216. // 判断响应结果
  217. if (firstCompleted == 'delay') {
  218. // 如果是延迟Future完成了,表示500毫秒内没有获得权限响应,显示对话框
  219. _showPermissionDialog("“YYHome”requires permission to make phone calls for communication. Please allow access to this permission");
  220. // 再次等待权限请求结果
  221. status = await permissionRequestFuture;
  222. DialogEngine.dismiss(tag: "permission");
  223. } else {
  224. // 权限请求已完成,立刻取消对话框展示(如果已经展示的话)
  225. DialogEngine.dismiss(tag: "permission");
  226. status = firstCompleted as PermissionStatus;
  227. }
  228. if (status.isGranted) {
  229. // 用户授权
  230. success();
  231. } else {
  232. // 权限被拒绝
  233. await DialogEngine.show(
  234. widget: AppDefaultDialog(
  235. message: "Please go to your phone settings to enable phone calls permission",
  236. title: "Alert",
  237. confirmAction: () {
  238. openAppSettings();
  239. }),
  240. );
  241. }
  242. }
  243. }
  244. //顶部展示权限声明详情弹窗
  245. void _showPermissionDialog(String desc) {
  246. DialogEngine.show(
  247. clickMaskDismiss: false,
  248. backDismiss: true,
  249. tag: "permission",
  250. maskColor: Colors.transparent,
  251. widget: PermissionDescDialog(desc),
  252. );
  253. }
  254. }