Reason Pun

增加了权限申请页面和隐私提示页面

1 +import 'dart:io';
2 +
3 +import 'package:flutter/material.dart';
4 +import 'package:flutter/services.dart';
5 +import 'package:permission_handler/permission_handler.dart';
6 +
7 +/// 创建人: Created by zhaolong
8 +/// 创建时间:Created by on 2020/12/9.
9 +///
10 +/// 可关注公众号:我的大前端生涯 获取最新技术分享
11 +/// 可关注网易云课堂:https://study.163.com/instructor/1021406098.htm
12 +/// 可关注博客:https://blog.csdn.net/zl18603543572
13 +///
14 +/// 代码清单
15 +///权限请求模版
16 +class PermissionRequestWidget extends StatefulWidget {
17 + final Permission permission;
18 + final List<String> permissionList;
19 + final bool isCloseApp;
20 + final String leftButtonText;
21 +
22 + const PermissionRequestWidget({
23 + Key? key,
24 + required this.permission,
25 + required this.permissionList,
26 + this.leftButtonText = "再考虑一下",
27 + this.isCloseApp = false,
28 + }) : super(key: key);
29 +
30 + @override
31 + _PermissionRequestWidgetState createState() =>
32 + _PermissionRequestWidgetState();
33 +}
34 +
35 +class _PermissionRequestWidgetState extends State<PermissionRequestWidget>
36 + with WidgetsBindingObserver {
37 + //页面的初始化函数
38 + @override
39 + void initState() {
40 + super.initState();
41 + checkPermission();
42 + //注册观察者
43 + if (WidgetsBinding.instance != null) {
44 + WidgetsBinding.instance!.addObserver(this);
45 + }
46 + }
47 +
48 + @override
49 + void didChangeAppLifecycleState(AppLifecycleState state) {
50 + super.didChangeAppLifecycleState(state);
51 + if (state == AppLifecycleState.resumed && _isGoSetting) {
52 + checkPermission();
53 + }
54 + }
55 +
56 + ///[PermissionStatus.denied] 用户拒绝访问所请求的特性
57 + ///[PermissionStatus.granted] 用户被授予对所请求特性的访问权。
58 + ///[PermissionStatus.restricted] iOS 平台 用户拒绝这个权限
59 + ///[PermissionStatus.limited] 用户已授权此应用程序进行有限访问。
60 + ///[PermissionStatus.permanentlyDenied] 被永久拒绝
61 + void checkPermission({PermissionStatus? status}) async {
62 + //权限
63 + Permission permission = widget.permission;
64 +
65 + status ??= await permission.status;
66 + if (status.isGranted) {
67 + Navigator.of(context).pop(true);
68 + return;
69 + }
70 + if (!status.isLimited) {
71 + //第一次申请
72 + showPermissionAlert(widget.permissionList[0], "同意", permission);
73 + } else if (status.isDenied) {
74 + if (Platform.isIOS) {
75 + showPermissionAlert(widget.permissionList[2], "去设置中心", permission,
76 + isSetting: true);
77 + return;
78 + }
79 + //用户第一次申请拒绝
80 + showPermissionAlert(widget.permissionList[1], "重试", permission);
81 + } else if (status.isPermanentlyDenied) {
82 + //第二次申请 用户拒绝
83 + showPermissionAlert(widget.permissionList[2], "去设置中心", permission,
84 + isSetting: true);
85 + } else {
86 + //通过
87 + Navigator.of(context).pop(true);
88 + }
89 + }
90 +
91 + //是否去设置中心
92 + bool _isGoSetting = false;
93 +
94 + void showPermissionAlert(
95 + String message,
96 + String rightString,
97 + Permission permission, {
98 + bool isSetting = false,
99 + }) {
100 + showDialog(
101 + builder: (BuildContext context) {
102 + return AlertDialog(
103 + title: const Text("温馨提示"),
104 + content: Container(
105 + padding: const EdgeInsets.all(12),
106 + child: Text(message),
107 + ),
108 + actions: [
109 + //左边的按钮
110 + TextButton(
111 + child: Text(widget.leftButtonText),
112 + onPressed: () {
113 + if (widget.isCloseApp) {
114 + closeApp();
115 + } else {
116 + Navigator.of(context).pop(false);
117 + }
118 + },
119 + ),
120 + //右边的按钮
121 + TextButton(
122 + child: Text(rightString),
123 + onPressed: () {
124 + //关闭弹框
125 + Navigator.of(context).pop();
126 + if (isSetting) {
127 + _isGoSetting = true;
128 + //去设置中心
129 + openAppSettings();
130 + } else {
131 + //申请权限
132 + requestPermission(permission);
133 + }
134 + },
135 + )
136 + ],
137 + );
138 + },
139 + context: context);
140 + }
141 +
142 + void requestPermission(Permission permission) async {
143 + //发起权限申请
144 + PermissionStatus status = await permission.request();
145 + //校验
146 + checkPermission();
147 + }
148 +
149 + /// TODO 暂未使用
150 + void requestPermissionList(List<Permission> list) async {
151 + //多个权限申请
152 + Map<Permission, PermissionStatus> statuses = await [
153 + Permission.location,
154 + Permission.storage,
155 + ].request();
156 + }
157 +
158 + void closeApp() {
159 + //关闭应用的方法
160 + SystemChannels.platform.invokeMethod("SystemNavigator.pop");
161 + }
162 +
163 + @override
164 + void dispose() {
165 + //注销观察者
166 + if (WidgetsBinding.instance != null) {
167 + WidgetsBinding.instance!.removeObserver(this);
168 + }
169 +
170 + super.dispose();
171 + }
172 +
173 + @override
174 + Widget build(BuildContext context) {
175 + return const Scaffold(
176 + backgroundColor: Colors.transparent,
177 + );
178 + }
179 +}
1 +import 'package:flutter/gestures.dart';
2 +import 'package:flutter/material.dart';
3 +import 'package:one_poem/res/constant.dart';
4 +import 'package:one_poem/routers/fluro_navigator.dart';
5 +
6 +/// 创建人: Created by zhaolong
7 +/// 创建时间:Created by on 2020/12/12.
8 +///
9 +/// 可关注公众号:我的大前端生涯 获取最新技术分享
10 +/// 可关注网易云课堂:https://study.163.com/instructor/1021406098.htm
11 +/// 可关注博客:https://blog.csdn.net/zl18603543572
12 +///
13 +/// 代码清单
14 +///代码清单
15 +class ProtocolModel {
16 + late TapGestureRecognizer _registerProtocolRecognizer;
17 + late TapGestureRecognizer _privacyProtocolRecognizer;
18 +
19 + ///用来显示 用户协议对话框
20 + Future<bool> showProtocolFunction(BuildContext context) async {
21 + //注册协议的手势
22 + _registerProtocolRecognizer = TapGestureRecognizer();
23 + //隐私协议的手势
24 + _privacyProtocolRecognizer = TapGestureRecognizer();
25 +
26 + //苹果风格弹框
27 + bool isShow = await showDialog(
28 + //上下文对象
29 + context: context,
30 + //对话框内容
31 + builder: (BuildContext context) {
32 + return showAlertDialog(context);
33 + },
34 + );
35 +
36 + ///销毁
37 + _registerProtocolRecognizer.dispose();
38 + _privacyProtocolRecognizer.dispose();
39 +
40 + return Future.value(isShow);
41 + }
42 +
43 + AlertDialog showAlertDialog(BuildContext context) {
44 + return AlertDialog(
45 + title: const Text("温馨提示"),
46 + content: Container(
47 + height: 260,
48 + padding: const EdgeInsets.all(1),
49 + //可滑动布局
50 + child: SingleChildScrollView(
51 + child: buildContent(context),
52 + ),
53 + ),
54 + actions: [
55 + TextButton(
56 + child: const Text("不同意"),
57 + onPressed: () {
58 + Navigator.of(context).pop(false);
59 + },
60 + ),
61 + TextButton(
62 + child: const Text("同意"),
63 + onPressed: () {
64 + Navigator.of(context).pop(true);
65 + },
66 + ),
67 + ],
68 + );
69 + }
70 +
71 + //协议说明文案
72 + String userPrivateProtocol =
73 + "我们一向尊重并会严格保护用户在使用本产品时的合法权益(包括用户隐私、用户数据等)不受到任何侵犯。本协议(包括本文最后部分的隐私政策)是用户(包括通过各种合法途径获取到本产品的自然人、法人或其他组织机构,以下简称“用户”或“您”)与我们之间针对本产品相关事项最终的、完整的且排他的协议,并取代、合并之前的当事人之间关于上述事项的讨论和协议。本协议将对用户使用本产品的行为产生法律约束力,您已承诺和保证有权利和能力订立本协议。用户开始使用本产品将视为已经接受本协议,请认真阅读并理解本协议中各种条款,包括免除和限制我们的免责条款和对用户的权利限制(未成年人审阅时应由法定监护人陪同),如果您不能接受本协议中的全部条款,请勿开始使用本产品";
74 +
75 + buildContent(BuildContext context) {
76 + return RichText(
77 + text: TextSpan(
78 + text: "请您在使用本产品之前仔细阅读",
79 + style: TextStyle(color: Colors.grey[600]),
80 + children: [
81 + TextSpan(
82 + text: "《用户协议》",
83 + style: const TextStyle(color: Colors.blue),
84 + //点击事件
85 + recognizer: _registerProtocolRecognizer
86 + ..onTap = () {
87 + //打开用户协议
88 + openUserProtocol(context);
89 + },
90 + ),
91 + TextSpan(
92 + text: "与",
93 + style: TextStyle(color: Colors.grey[600]),
94 + ),
95 + TextSpan(
96 + text: "《隐私协议》",
97 + style: const TextStyle(color: Colors.blue),
98 + //点击事件
99 + recognizer: _privacyProtocolRecognizer
100 + ..onTap = () {
101 + //打开隐私协议
102 + openPrivateProtocol(context);
103 + },
104 + ),
105 + TextSpan(
106 + text: userPrivateProtocol,
107 + style: TextStyle(color: Colors.grey[600]),
108 + ),
109 + ]),
110 + );
111 + }
112 +
113 + //查看用户协议
114 + void openUserProtocol(BuildContext context) {
115 + NavigatorUtils.goWebViewPage(
116 + context,
117 + '用户协议',
118 + Constant.protocolUrl,
119 + );
120 + }
121 +
122 + //查看隐私协议
123 + void openPrivateProtocol(BuildContext context) {
124 + NavigatorUtils.goWebViewPage(
125 + context,
126 + '隐私协议',
127 + Constant.privacyUrl,
128 + );
129 + }
130 +}
1 import 'package:flustars/flustars.dart'; 1 import 'package:flustars/flustars.dart';
2 import 'package:flutter/foundation.dart'; 2 import 'package:flutter/foundation.dart';
3 +import 'package:flutter/gestures.dart';
3 import 'package:flutter/material.dart'; 4 import 'package:flutter/material.dart';
4 import 'package:flutter/services.dart'; 5 import 'package:flutter/services.dart';
6 +import 'package:one_poem/common/permission_request_widget.dart';
7 +import 'package:one_poem/common/protocol_model.dart';
8 +import 'package:one_poem/home/webview_page.dart';
5 import 'package:one_poem/login/widgets/my_text_field.dart'; 9 import 'package:one_poem/login/widgets/my_text_field.dart';
6 import 'package:one_poem/res/constant.dart'; 10 import 'package:one_poem/res/constant.dart';
7 import 'package:one_poem/res/resources.dart'; 11 import 'package:one_poem/res/resources.dart';
...@@ -18,6 +22,8 @@ import '../login_router.dart'; ...@@ -18,6 +22,8 @@ import '../login_router.dart';
18 import 'package:flutter_gen/gen_l10n/one_poem_localizations.dart'; 22 import 'package:flutter_gen/gen_l10n/one_poem_localizations.dart';
19 import 'package:one_poem/extension/int_extension.dart'; 23 import 'package:one_poem/extension/int_extension.dart';
20 24
25 +import 'package:permission_handler/permission_handler.dart';
26 +
21 /// design/1注册登录/index.html 27 /// design/1注册登录/index.html
22 class LoginPage extends StatefulWidget { 28 class LoginPage extends StatefulWidget {
23 const LoginPage({Key? key}) : super(key: key); 29 const LoginPage({Key? key}) : super(key: key);
...@@ -27,7 +33,7 @@ class LoginPage extends StatefulWidget { ...@@ -27,7 +33,7 @@ class LoginPage extends StatefulWidget {
27 } 33 }
28 34
29 class _LoginPageState extends State<LoginPage> 35 class _LoginPageState extends State<LoginPage>
30 - with ChangeNotifierMixin<LoginPage> { 36 + with ChangeNotifierMixin<LoginPage>, ProtocolModel {
31 //定义一个controller 37 //定义一个controller
32 final TextEditingController _nameController = TextEditingController(); 38 final TextEditingController _nameController = TextEditingController();
33 final TextEditingController _passwordController = TextEditingController(); 39 final TextEditingController _passwordController = TextEditingController();
...@@ -55,6 +61,40 @@ class _LoginPageState extends State<LoginPage> ...@@ -55,6 +61,40 @@ class _LoginPageState extends State<LoginPage>
55 overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]); 61 overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom]);
56 }); 62 });
57 _nameController.text = SpUtil.getString(Constant.phone).nullSafe; 63 _nameController.text = SpUtil.getString(Constant.phone).nullSafe;
64 +
65 + List<String> _list = [
66 + "为您更好的体验应用,所以需要获取您的手机文件存储权限,以保存您的一些偏好设置",
67 + "您已拒绝权限,所以无法保存您的一些偏好设置,将无法使用APP",
68 + "您已拒绝权限,请在设置中心中同意APP的权限请求",
69 + "其他错误"
70 + ];
71 +
72 + Future.delayed(Duration.zero, () {
73 + NavigatorUtils.pushPageByFade(
74 + context: context,
75 + //目标页面
76 + targetPage: PermissionRequestWidget(
77 + //所需要申请的权限
78 + permission: Permission.camera,
79 + //显示关闭应用按钮
80 + isCloseApp: true,
81 + //提示文案
82 + permissionList: _list,
83 + ),
84 + //权限申请结果
85 + dismissCallBack: (value) {
86 + showPrivacyPage();
87 + });
88 + });
89 + }
90 +
91 + void showPrivacyPage() async {
92 + bool isAgreement = await showProtocolFunction(context);
93 + if (isAgreement) {
94 + // next();
95 + } else {
96 + SystemChannels.platform.invokeMethod("SystemNavigator.pop");
97 + }
58 } 98 }
59 99
60 void _verify() { 100 void _verify() {
...@@ -125,6 +165,46 @@ class _LoginPageState extends State<LoginPage> ...@@ -125,6 +165,46 @@ class _LoginPageState extends State<LoginPage>
125 hintText: OnePoemLocalizations.of(context).inputPasswordHint, 165 hintText: OnePoemLocalizations.of(context).inputPasswordHint,
126 ), 166 ),
127 Gaps.vGap24, 167 Gaps.vGap24,
168 + Text.rich(
169 + TextSpan(
170 + text: '登录即代表同意并阅读',
171 + style: const TextStyle(fontSize: 12, color: Color(0xFF999999)),
172 + children: [
173 + TextSpan(
174 + text: '《用户协议》',
175 + style: TextStyle(color: Theme.of(context).primaryColor),
176 + recognizer: TapGestureRecognizer()
177 + ..onTap = () {
178 + Navigator.of(context)
179 + .push(MaterialPageRoute(builder: (context) {
180 + return const WebViewPage(
181 + title: '《用户协议》',
182 + url: Constant.protocolUrl,
183 + );
184 + }));
185 + },
186 + ),
187 + const TextSpan(text: '和'),
188 + TextSpan(
189 + text: '《隐私政策》',
190 + style: TextStyle(color: Theme.of(context).primaryColor),
191 + recognizer: TapGestureRecognizer()
192 + ..onTap = () {
193 + Navigator.of(context).push(
194 + MaterialPageRoute(
195 + builder: (context) {
196 + return const WebViewPage(
197 + title: '《隐私政策》',
198 + url: Constant.privacyUrl,
199 + );
200 + },
201 + ),
202 + );
203 + },
204 + ),
205 + ]),
206 + ),
207 + Gaps.vGap16,
128 MyButton( 208 MyButton(
129 key: const Key('login'), 209 key: const Key('login'),
130 onPressed: _clickable ? _login : null, 210 onPressed: _clickable ? _login : null,
......
1 import 'package:flutter/foundation.dart'; 1 import 'package:flutter/foundation.dart';
2 +import 'package:flutter/gestures.dart';
2 import 'package:flutter/material.dart'; 3 import 'package:flutter/material.dart';
3 import 'package:flutter/services.dart'; 4 import 'package:flutter/services.dart';
5 +import 'package:one_poem/home/webview_page.dart';
4 import 'package:one_poem/login/widgets/my_text_field.dart'; 6 import 'package:one_poem/login/widgets/my_text_field.dart';
5 import 'package:one_poem/res/resources.dart'; 7 import 'package:one_poem/res/resources.dart';
6 import 'package:one_poem/res/styles.dart'; 8 import 'package:one_poem/res/styles.dart';
...@@ -32,6 +34,7 @@ class _RegisterPageState extends State<RegisterPage> ...@@ -32,6 +34,7 @@ class _RegisterPageState extends State<RegisterPage>
32 final FocusNode _nodeText2 = FocusNode(); 34 final FocusNode _nodeText2 = FocusNode();
33 final FocusNode _nodeText3 = FocusNode(); 35 final FocusNode _nodeText3 = FocusNode();
34 bool _clickable = false; 36 bool _clickable = false;
37 + bool _switchSelected=true;
35 38
36 @override 39 @override
37 Map<ChangeNotifier, List<VoidCallback>?>? changeNotifier() { 40 Map<ChangeNotifier, List<VoidCallback>?>? changeNotifier() {
...@@ -130,6 +133,39 @@ class _RegisterPageState extends State<RegisterPage> ...@@ -130,6 +133,39 @@ class _RegisterPageState extends State<RegisterPage>
130 keyboardType: TextInputType.visiblePassword, 133 keyboardType: TextInputType.visiblePassword,
131 hintText: OnePoemLocalizations.of(context).inputPasswordHint, 134 hintText: OnePoemLocalizations.of(context).inputPasswordHint,
132 ), 135 ),
136 + Gaps.vGap8,
137 + Text.rich(
138 + TextSpan(
139 + text: '登录即代表同意并阅读',
140 + style: TextStyle(fontSize: 14, color: const Color(0xFF999999)),
141 + children: [
142 + TextSpan(
143 + text: '《用户协议》',
144 + style: TextStyle(color: Theme.of(context).primaryColor),
145 + recognizer: TapGestureRecognizer()
146 + ..onTap = () {
147 + Navigator.of(context)
148 + .push(MaterialPageRoute(builder: (context) {
149 + return WebViewPage(
150 + title: '《用户协议》', url: 'https://flutter.dev');
151 + }));
152 + },
153 + ),
154 + TextSpan(text: '和'),
155 + TextSpan(
156 + text: '《隐私政策》',
157 + style: TextStyle(color: Theme.of(context).primaryColor),
158 + recognizer: TapGestureRecognizer()
159 + ..onTap = () {
160 + Navigator.of(context)
161 + .push(MaterialPageRoute(builder: (context) {
162 + return WebViewPage(
163 + title: '《隐私政策》', url: 'https://flutter.dev');
164 + }));
165 + },
166 + ),
167 + ]),
168 + ),
133 Gaps.vGap24, 169 Gaps.vGap24,
134 MyButton( 170 MyButton(
135 key: const Key('register'), 171 key: const Key('register'),
......
...@@ -2,6 +2,9 @@ import 'package:flutter/foundation.dart'; ...@@ -2,6 +2,9 @@ import 'package:flutter/foundation.dart';
2 2
3 class Constant { 3 class Constant {
4 4
5 + static const String privacyUrl = "https://www.mofunenglish.com/index.php?act=about&mdl=agreement";
6 + static const String protocolUrl = "https://www.mofunenglish.com/index.php?act=about&mdl=agreement";
7 +
5 /// App运行在Release环境时,inProduction为true;当App运行在Debug和Profile环境时,inProduction为false 8 /// App运行在Release环境时,inProduction为true;当App运行在Debug和Profile环境时,inProduction为false
6 static const bool inProduction = kReleaseMode; 9 static const bool inProduction = kReleaseMode;
7 10
......
...@@ -5,11 +5,12 @@ import 'routers.dart'; ...@@ -5,11 +5,12 @@ import 'routers.dart';
5 5
6 /// fluro的路由跳转工具类 6 /// fluro的路由跳转工具类
7 class NavigatorUtils { 7 class NavigatorUtils {
8 -
9 static void push(BuildContext context, String path, 8 static void push(BuildContext context, String path,
10 {bool replace = false, bool clearStack = false, Object? arguments}) { 9 {bool replace = false, bool clearStack = false, Object? arguments}) {
11 unfocus(); 10 unfocus();
12 - Routes.router.navigateTo(context, path, 11 + Routes.router.navigateTo(
12 + context,
13 + path,
13 replace: replace, 14 replace: replace,
14 clearStack: clearStack, 15 clearStack: clearStack,
15 transition: TransitionType.native, 16 transition: TransitionType.native,
...@@ -19,17 +20,22 @@ class NavigatorUtils { ...@@ -19,17 +20,22 @@ class NavigatorUtils {
19 ); 20 );
20 } 21 }
21 22
22 - static void pushResult(BuildContext context, String path, Function(Object) function, 23 + static void pushResult(
24 + BuildContext context, String path, Function(Object) function,
23 {bool replace = false, bool clearStack = false, Object? arguments}) { 25 {bool replace = false, bool clearStack = false, Object? arguments}) {
24 unfocus(); 26 unfocus();
25 - Routes.router.navigateTo(context, path, 27 + Routes.router
28 + .navigateTo(
29 + context,
30 + path,
26 replace: replace, 31 replace: replace,
27 clearStack: clearStack, 32 clearStack: clearStack,
28 transition: TransitionType.native, 33 transition: TransitionType.native,
29 routeSettings: RouteSettings( 34 routeSettings: RouteSettings(
30 arguments: arguments, 35 arguments: arguments,
31 ), 36 ),
32 - ).then((Object? result) { 37 + )
38 + .then((Object? result) {
33 // 页面返回result为null 39 // 页面返回result为null
34 if (result == null) { 40 if (result == null) {
35 return; 41 return;
...@@ -55,7 +61,8 @@ class NavigatorUtils { ...@@ -55,7 +61,8 @@ class NavigatorUtils {
55 /// 跳到WebView页 61 /// 跳到WebView页
56 static void goWebViewPage(BuildContext context, String title, String url) { 62 static void goWebViewPage(BuildContext context, String title, String url) {
57 //fluro 不支持传中文,需转换 63 //fluro 不支持传中文,需转换
58 - push(context, '${Routes.webViewPage}?title=${Uri.encodeComponent(title)}&url=${Uri.encodeComponent(url)}'); 64 + push(context,
65 + '${Routes.webViewPage}?title=${Uri.encodeComponent(title)}&url=${Uri.encodeComponent(url)}');
59 } 66 }
60 67
61 static void unfocus() { 68 static void unfocus() {
...@@ -64,4 +71,50 @@ class NavigatorUtils { ...@@ -64,4 +71,50 @@ class NavigatorUtils {
64 // https://github.com/flutter/flutter/issues/47128#issuecomment-627551073 71 // https://github.com/flutter/flutter/issues/47128#issuecomment-627551073
65 FocusManager.instance.primaryFocus?.unfocus(); 72 FocusManager.instance.primaryFocus?.unfocus();
66 } 73 }
74 +
75 + ///普通打开页面的方法
76 + ///[context] 上下文对象
77 + ///[targetPage] 目标页面
78 + ///[isReplace] 是否替换当前页面 A -B
79 + ///[opaque] 是否以背景透明的方式打开页面
80 + static void pushPageByFade({
81 + required BuildContext context,
82 + required Widget targetPage,
83 + bool isReplace = false,
84 + int startMills = 400,
85 + bool opaque = false,
86 + Function(dynamic value)? dismissCallBack,
87 + }) {
88 + PageRoute pageRoute = PageRouteBuilder(
89 + //背景透明 方式打开新的页面
90 + opaque: opaque,
91 + pageBuilder: (BuildContext context, Animation<double> animation,
92 + Animation<double> secondaryAnimation) {
93 + return targetPage;
94 + },
95 + transitionDuration: Duration(milliseconds: startMills),
96 + //动画
97 + transitionsBuilder: (BuildContext context, Animation<double> animation,
98 + Animation<double> secondaryAnimation, Widget child) {
99 + return FadeTransition(
100 + opacity: animation,
101 + child: child,
102 + );
103 + },
104 + );
105 +
106 + if (isReplace) {
107 + Navigator.of(context).pushReplacement(pageRoute).then((value) {
108 + if (dismissCallBack != null) {
109 + dismissCallBack(value);
110 + }
111 + });
112 + } else {
113 + Navigator.of(context).push(pageRoute).then((value) {
114 + if (dismissCallBack != null) {
115 + dismissCallBack(value);
116 + }
117 + });
118 + }
119 + }
67 } 120 }
......
...@@ -708,6 +708,20 @@ packages: ...@@ -708,6 +708,20 @@ packages:
708 url: "https://pub.dartlang.org" 708 url: "https://pub.dartlang.org"
709 source: hosted 709 source: hosted
710 version: "1.11.1" 710 version: "1.11.1"
711 + permission_handler:
712 + dependency: "direct dev"
713 + description:
714 + name: permission_handler
715 + url: "https://pub.dartlang.org"
716 + source: hosted
717 + version: "8.3.0"
718 + permission_handler_platform_interface:
719 + dependency: transitive
720 + description:
721 + name: permission_handler_platform_interface
722 + url: "https://pub.dartlang.org"
723 + source: hosted
724 + version: "3.7.0"
711 petitparser: 725 petitparser:
712 dependency: transitive 726 dependency: transitive
713 description: 727 description:
......
...@@ -129,6 +129,8 @@ dev_dependencies: ...@@ -129,6 +129,8 @@ dev_dependencies:
129 flutter_launcher_icons: ^0.9.2 129 flutter_launcher_icons: ^0.9.2
130 flutter_native_splash: ^1.3.2 130 flutter_native_splash: ^1.3.2
131 131
132 + permission_handler: ^8.3.0
133 +
132 # For information on the generic Dart part of this file, see the 134 # For information on the generic Dart part of this file, see the
133 # following page: https://dart.dev/tools/pub/pubspec 135 # following page: https://dart.dev/tools/pub/pubspec
134 136
......