Blame view

lib/common/permission/permissionRequestPage.dart 8.1 KB
1daca20d   吴启风   pref:权限申请页面优化
1
  import 'dart:async';
6051f850   吴启风   feat:带隐私合规权限申请描述的...
2
3
  import 'dart:io';
  import 'package:flutter/material.dart';
e811f164   吴启风   feat:权限申请页面增加隐私合规...
4
  import 'package:flutter_screenutil/flutter_screenutil.dart';
6051f850   吴启风   feat:带隐私合规权限申请描述的...
5
  import 'package:permission_handler/permission_handler.dart';
258578de   吴启风   feat:修复ios上退出应用失效问题
6
  import 'package:wow_english/common/core/app_config_helper.dart';
e811f164   吴启风   feat:权限申请页面增加隐私合规...
7
  import 'package:wow_english/common/permission/permissionRequester.dart';
6051f850   吴启风   feat:带隐私合规权限申请描述的...
8
9
10
  
  import '../../utils/log_util.dart';
  
ba96a4bc   吴启风   feat:方法注释优化
11
  ///带有隐私合规弹窗的透明权限申请页面,主要应对android各大应用市场对隐私权限申请需同步告知索取权限目的
6051f850   吴启风   feat:带隐私合规权限申请描述的...
12
  class PermissionRequestPage extends StatefulWidget {
e811f164   吴启风   feat:权限申请页面增加隐私合规...
13
14
    const PermissionRequestPage(this.permissions,
        this.permissionNames, this.permissionDesc,
6051f850   吴启风   feat:带隐私合规权限申请描述的...
15
16
        {super.key, this.isRequiredPermission = false});
  
1daca20d   吴启风   pref:权限申请页面优化
17
    final List<Permission> permissions;
e811f164   吴启风   feat:权限申请页面增加隐私合规...
18
19
20
    final List<String> permissionNames;
    final String permissionDesc;
  
1daca20d   吴启风   pref:权限申请页面优化
21
    ///是否需要强制授予
6051f850   吴启风   feat:带隐私合规权限申请描述的...
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
    final bool isRequiredPermission;
  
    @override
    State<PermissionRequestPage> createState() => _PermissionRequestPageState();
  }
  
  class _PermissionRequestPageState extends State<PermissionRequestPage>
      with WidgetsBindingObserver {
    bool _isGoSetting = false;
    late final List<String> msgList;
    bool _isDialogShowing = false;
  
    @override
    void initState() {
      super.initState();
      WidgetsBinding.instance.addObserver(this);
e811f164   吴启风   feat:权限申请页面增加隐私合规...
38
39
      String permissionDesc = widget.permissionDesc;
      String permissionStr = widget.permissionNames.join('、');
6051f850   吴启风   feat:带隐私合规权限申请描述的...
40
      msgList = [
e811f164   吴启风   feat:权限申请页面增加隐私合规...
41
42
43
44
        "$permissionDesc,需要获取您设备的$permissionStr权限",
        "你还没有开启$permissionStr权限,开启后即可$permissionDesc",
        "未开启$permissionStr权限导致功能受限,您可以手动开启权限",
        widget.isRequiredPermission ? "退出应用" : "以后再说"
6051f850   吴启风   feat:带隐私合规权限申请描述的...
45
      ];
1daca20d   吴启风   pref:权限申请页面优化
46
      _handlePermission(widget.permissions);
6051f850   吴启风   feat:带隐私合规权限申请描述的...
47
48
49
    }
  
    @override
e811f164   吴启风   feat:权限申请页面增加隐私合规...
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
    Widget build(BuildContext context) {
      double screenWidth = MediaQuery.of(context).size.width;
      // PackageInfo packageInfo = await PackageInfo.fromPlatform();
      // String packageName = packageInfo.packageName;
      return Scaffold(
          backgroundColor: Colors.transparent,
          body: Align(
              alignment: Alignment.topCenter,
              child: Container(
                  width: screenWidth / 2,
                  padding: const EdgeInsets.all(16.0),
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(10.0), // 圆角半径
                    boxShadow: const [
                      BoxShadow(
                        color: Colors.black26,
                        blurRadius: 4.0,
                        offset: Offset(2, 2),
                      ),
                    ],
                  ),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Center(
                        child: Text(
                          '${widget.permissionNames.join('、')}权限使用说明',
                          style: TextStyle(
                              color: Colors.black,
                              fontSize: 15.sp,
                              fontWeight: FontWeight.w500,
                              fontFamily: 'PingFangSC-Regular'),
                          textAlign: TextAlign.left,
                        ),
                      ),
                      16.verticalSpace,
                      Text(
                        widget.permissionDesc,
                        style: const TextStyle(color: Colors.black54,
                            fontFamily: 'PingFangSC-Regular'),
                        textAlign: TextAlign.left,
                      ),
                    ],
                  ))));
    }
  
    @override
6051f850   吴启风   feat:带隐私合规权限申请描述的...
99
100
101
102
    void didChangeAppLifecycleState(AppLifecycleState state) {
      super.didChangeAppLifecycleState(state);
      Log.d("didChangeAppLifecycleState state=$state _isGoSetting=$_isGoSetting");
      // 监听 app 从后台切回前台
e811f164   吴启风   feat:权限申请页面增加隐私合规...
103
      if (state == AppLifecycleState.resumed && _isGoSetting && !_isDialogShowing) {
1daca20d   吴启风   pref:权限申请页面优化
104
        _handlePermission(widget.permissions);
6051f850   吴启风   feat:带隐私合规权限申请描述的...
105
106
107
108
      }
    }
  
    /// 校验权限
1daca20d   吴启风   pref:权限申请页面优化
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
    void _handlePermission(List<Permission> permissions) async {
      ///一个新待申请权限列表
      List<Permission> intentPermissionList = [];
  
      ///遍历当前权限申请列表
      for (Permission permission in permissions) {
        PermissionStatus status = await permission.status;
  
        ///如果不是允许状态就添加到新的申请列表中
        if (!status.isGranted) {
          intentPermissionList.add(permission);
        }
      }
  
      if (intentPermissionList.isEmpty) {
        _popPage(true);
      } else {
        _requestPermission(intentPermissionList);
      }
6051f850   吴启风   feat:带隐私合规权限申请描述的...
128
129
    }
  
1daca20d   吴启风   pref:权限申请页面优化
130
131
132
    ///实际触发请求权限
    Future<void> _requestPermission(List<Permission> permissions) async {
      Log.d('_requestPermission permissions=$permissions');
e811f164   吴启风   feat:权限申请页面增加隐私合规...
133
134
      MapEntry<Permission, PermissionStatus>? statusEntry =
          await requestPermissionsInner(permissions);
1daca20d   吴启风   pref:权限申请页面优化
135
136
137
138
139
140
141
142
      if (statusEntry == null) {
        ///都手动同意授予了
        _popPage(true);
        return;
      }
  
      Permission permission = statusEntry.key;
      PermissionStatus status = statusEntry.value;
e811f164   吴启风   feat:权限申请页面增加隐私合规...
143
  
6051f850   吴启风   feat:带隐私合规权限申请描述的...
144
145
146
      // 还未申请权限或之前拒绝了权限(在 iOS 上为首次申请权限,拒绝后将变为 `永久拒绝权限`)
      if (status.isDenied) {
        showAlert(
e811f164   吴启风   feat:权限申请页面增加隐私合规...
147
            permission, msgList[0], msgList[3], _isGoSetting ? "前往系统设置" : "继续");
6051f850   吴启风   feat:带隐私合规权限申请描述的...
148
149
      }
      // 权限已被永久拒绝
1daca20d   吴启风   pref:权限申请页面优化
150
151
      /// 在 Android 上:Android 11+ (API 30+):用户是否第二次拒绝权限。低于 Android 11 (API 30):用户是否拒绝访问请求的功能,并选择不再显示请求。
      /// 在 iOS 上:如果用户拒绝访问所请求的功能。
6051f850   吴启风   feat:带隐私合规权限申请描述的...
152
153
154
      if (status.isPermanentlyDenied) {
        _isGoSetting = true;
        showAlert(
e811f164   吴启风   feat:权限申请页面增加隐私合规...
155
            permission, msgList[2], msgList[3], _isGoSetting ? "前往系统设置" : "继续");
6051f850   吴启风   feat:带隐私合规权限申请描述的...
156
      }
e811f164   吴启风   feat:权限申请页面增加隐私合规...
157
158
159
      // isLimited:拥有部分权限(受限,仅在 iOS (iOS14+) 上受支持)
      // isRestricted:拥有部分权限,活动限制(例如,设置了家长///控件,仅在iOS以上受支持。(仅限 iOS)
      if (status.isLimited || status.isRestricted) {
6051f850   吴启风   feat:带隐私合规权限申请描述的...
160
161
        if (Platform.isIOS || Platform.isMacOS) _isGoSetting = true;
        showAlert(
e811f164   吴启风   feat:权限申请页面增加隐私合规...
162
            permission, msgList[1], msgList[3], _isGoSetting ? "前往系统设置" : "继续");
6051f850   吴启风   feat:带隐私合规权限申请描述的...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
      }
    }
  
    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()
e811f164   吴启风   feat:权限申请页面增加隐私合规...
186
                          : _popDialog(context, false);
6051f850   吴启风   feat:带隐私合规权限申请描述的...
187
188
189
190
191
192
193
                    }),
                TextButton(
                    child: Text(confirmMsg),
                    onPressed: () {
                      if (_isGoSetting) {
                        openAppSettings();
                      } else {
1daca20d   吴启风   pref:权限申请页面优化
194
                        _handlePermission(widget.permissions);
6051f850   吴启风   feat:带隐私合规权限申请描述的...
195
                      }
e811f164   吴启风   feat:权限申请页面增加隐私合规...
196
                      _popDialog(context, null);
6051f850   吴启风   feat:带隐私合规权限申请描述的...
197
198
199
200
201
                    })
              ],
            );
          }).then((value) => {
            _isDialogShowing = false,
e811f164   吴启风   feat:权限申请页面增加隐私合规...
202
203
            _popPage(value)
          });
6051f850   吴启风   feat:带隐私合规权限申请描述的...
204
205
    }
  
6051f850   吴启风   feat:带隐私合规权限申请描述的...
206
207
208
209
210
211
    @override
    void dispose() {
      WidgetsBinding.instance.removeObserver(this);
      super.dispose();
    }
  
6051f850   吴启风   feat:带隐私合规权限申请描述的...
212
213
    /// 退出应用程序
    void _quitApp() {
258578de   吴启风   feat:修复ios上退出应用失效问题
214
      AppConfigHelper.exitApp();
6051f850   吴启风   feat:带隐私合规权限申请描述的...
215
216
    }
  
6051f850   吴启风   feat:带隐私合规权限申请描述的...
217
    /// 关闭弹窗
e811f164   吴启风   feat:权限申请页面增加隐私合规...
218
219
    /// isAllGranted为null的话跳到系统设置页
    void _popDialog(BuildContext dialogContext, bool? isAllGranted) {
6051f850   吴启风   feat:带隐私合规权限申请描述的...
220
      Navigator.of(dialogContext).pop();
e811f164   吴启风   feat:权限申请页面增加隐私合规...
221
      _popPage(isAllGranted);
6051f850   吴启风   feat:带隐私合规权限申请描述的...
222
223
    }
  
e811f164   吴启风   feat:权限申请页面增加隐私合规...
224
225
226
227
228
229
    /// 关闭权限申请透明页面
    /// isAllGranted 所有权限都授予,为空不关闭
    void _popPage(bool? isAllGranted) {
      if (isAllGranted != null) {
        Navigator.of(context).pop(isAllGranted);
      }
6051f850   吴启风   feat:带隐私合规权限申请描述的...
230
231
    }
  }