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
|
}
}
|