Commit 9d4f000cb75e146cb7400c2937a7e9bb04e9ae2a

Authored by wdn127929
2 parents b68e1797 e90c7662

冲突

@@ -33,6 +33,8 @@ @@ -33,6 +33,8 @@
33 android:windowSoftInputMode="adjustResize" 33 android:windowSoftInputMode="adjustResize"
34 android:exported="true" 34 android:exported="true"
35 > 35 >
  36 +
  37 +
36 <meta-data 38 <meta-data
37 android:name="io.flutter.app.android.SplashScreenUntilFirstFrame" 39 android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
38 android:value="true" /> 40 android:value="true" />
@@ -65,6 +67,40 @@ @@ -65,6 +67,40 @@
65 <meta-data 67 <meta-data
66 android:name="flutterEmbedding" 68 android:name="flutterEmbedding"
67 android:value="2" /> 69 android:value="2" />
  70 +
  71 +
  72 + <!-- <provider
  73 + android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
  74 + android:authorities="${applicationId}.flutter_downloader.provider"
  75 + android:exported="true"
  76 + android:grantUriPermissions="true">
  77 + <meta-data
  78 + android:name="android.support.FILE_PROVIDER_PATHS"
  79 + android:resource="@xml/provider_paths"/>
  80 + </provider>
  81 +
  82 +
  83 + <provider
  84 + android:name="androidx.startup.InitializationProvider"
  85 + android:authorities="${applicationId}.androidx-startup"
  86 + android:exported="true"
  87 + tools:node="merge">
  88 + <meta-data
  89 + android:name="androidx.work.WorkManagerInitializer"
  90 + android:value="androidx.startup"
  91 + tools:node="remove" />
  92 + </provider>
  93 +
  94 +
  95 + <provider
  96 + android:name="vn.hunghd.flutterdownloader.FlutterDownloaderInitializer"
  97 + android:authorities="${applicationId}.flutter-downloader-init"
  98 + android:exported="true">
  99 + <meta-data
  100 + android:name="vn.hunghd.flutterdownloader.MAX_CONCURRENT_TASKS"
  101 + android:value="5" />
  102 + </provider> -->
  103 + <!-- End FlutterDownloader customization -->
68 <meta-data 104 <meta-data
69 android:name="com.amap.api.v2.apikey" 105 android:name="com.amap.api.v2.apikey"
70 android:value="dbced781d0acd36184d5b4b54da7188d"/> 106 android:value="dbced781d0acd36184d5b4b54da7188d"/>
@@ -8,7 +8,7 @@ buildscript { @@ -8,7 +8,7 @@ buildscript {
8 } 8 }
9 9
10 dependencies { 10 dependencies {
11 - classpath 'com.android.tools.build:gradle:3.5.0' 11 + classpath 'com.android.tools.build:gradle:3.5.4'
12 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 12 classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
13 classpath 'com.huawei.agconnect:agcp:1.0.0.300' 13 classpath 'com.huawei.agconnect:agcp:1.0.0.300'
14 } 14 }
1 -#Mon Dec 20 13:10:07 CST 2021 1 +# <<<<<<< HEAD
  2 +# #Mon Dec 20 13:10:07 CST 2021
  3 +# distributionBase=GRADLE_USER_HOME
  4 +# distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip
  5 +# =======
  6 +#Thu Dec 23 01:26:57 CST 2021
2 distributionBase=GRADLE_USER_HOME 7 distributionBase=GRADLE_USER_HOME
3 -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip 8 +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
4 distributionPath=wrapper/dists 9 distributionPath=wrapper/dists
5 zipStorePath=wrapper/dists 10 zipStorePath=wrapper/dists
6 zipStoreBase=GRADLE_USER_HOME 11 zipStoreBase=GRADLE_USER_HOME
@@ -483,7 +483,7 @@ @@ -483,7 +483,7 @@
483 CODE_SIGN_IDENTITY = "iPhone Developer"; 483 CODE_SIGN_IDENTITY = "iPhone Developer";
484 "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 484 "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
485 CODE_SIGN_STYLE = Automatic; 485 CODE_SIGN_STYLE = Automatic;
486 - CURRENT_PROJECT_VERSION = 310; 486 + CURRENT_PROJECT_VERSION = 317;
487 DEVELOPMENT_TEAM = 8J59HM8B82; 487 DEVELOPMENT_TEAM = 8J59HM8B82;
488 ENABLE_BITCODE = NO; 488 ENABLE_BITCODE = NO;
489 FLUTTER_BUILD_MODE = release; 489 FLUTTER_BUILD_MODE = release;
@@ -628,7 +628,7 @@ @@ -628,7 +628,7 @@
628 CODE_SIGN_ENTITLEMENTS = "Runner/一键订Debug.entitlements"; 628 CODE_SIGN_ENTITLEMENTS = "Runner/一键订Debug.entitlements";
629 CODE_SIGN_IDENTITY = "iPhone Developer"; 629 CODE_SIGN_IDENTITY = "iPhone Developer";
630 CODE_SIGN_STYLE = Automatic; 630 CODE_SIGN_STYLE = Automatic;
631 - CURRENT_PROJECT_VERSION = 310; 631 + CURRENT_PROJECT_VERSION = 317;
632 DEVELOPMENT_TEAM = 8J59HM8B82; 632 DEVELOPMENT_TEAM = 8J59HM8B82;
633 ENABLE_BITCODE = NO; 633 ENABLE_BITCODE = NO;
634 FLUTTER_BUILD_MODE = release; 634 FLUTTER_BUILD_MODE = release;
@@ -663,7 +663,7 @@ @@ -663,7 +663,7 @@
663 CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; 663 CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
664 CODE_SIGN_IDENTITY = "iPhone Developer"; 664 CODE_SIGN_IDENTITY = "iPhone Developer";
665 CODE_SIGN_STYLE = Automatic; 665 CODE_SIGN_STYLE = Automatic;
666 - CURRENT_PROJECT_VERSION = 310; 666 + CURRENT_PROJECT_VERSION = 317;
667 DEVELOPMENT_TEAM = 8J59HM8B82; 667 DEVELOPMENT_TEAM = 8J59HM8B82;
668 ENABLE_BITCODE = NO; 668 ENABLE_BITCODE = NO;
669 FLUTTER_BUILD_MODE = release; 669 FLUTTER_BUILD_MODE = release;
@@ -13,6 +13,7 @@ import 'package:flutter_screenutil/screenutil.dart'; @@ -13,6 +13,7 @@ import 'package:flutter_screenutil/screenutil.dart';
13 import 'package:fluwx/fluwx.dart'; 13 import 'package:fluwx/fluwx.dart';
14 import 'package:one_key/pages/detail/handle_online_page.dart'; 14 import 'package:one_key/pages/detail/handle_online_page.dart';
15 import 'package:one_key/pages/home/home_page.dart'; 15 import 'package:one_key/pages/home/home_page.dart';
  16 +import 'package:one_key/pages/login/first_page.dart';
16 import 'package:one_key/provider/base_info_provider.dart'; 17 import 'package:one_key/provider/base_info_provider.dart';
17 import 'package:one_key/provider/coupon_provider.dart'; 18 import 'package:one_key/provider/coupon_provider.dart';
18 import 'package:one_key/provider/create_store_model.dart'; 19 import 'package:one_key/provider/create_store_model.dart';
@@ -71,6 +72,7 @@ Future<void> main() async { @@ -71,6 +72,7 @@ Future<void> main() async {
71 await initializeDateFormatting(); 72 await initializeDateFormatting();
72 // _requestPermissions(); 73 // _requestPermissions();
73 Utils.changeStatusColor(); 74 Utils.changeStatusColor();
  75 +
74 await App.initSp(); 76 await App.initSp();
75 SystemChrome.setPreferredOrientations( 77 SystemChrome.setPreferredOrientations(
76 [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]) 78 [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown])
@@ -133,14 +135,14 @@ class MyApp extends StatefulWidget { @@ -133,14 +135,14 @@ class MyApp extends StatefulWidget {
133 class MyAppState extends State<MyApp> { 135 class MyAppState extends State<MyApp> {
134 int xgCount = 1; //注册信鸽次数,最多5次 136 int xgCount = 1; //注册信鸽次数,最多5次
135 bool isLogin = false; 137 bool isLogin = false;
136 - 138 + bool isFirst = true;
137 @override 139 @override
138 void initState() { 140 void initState() {
139 // TODO: implement initState 141 // TODO: implement initState
140 super.initState(); 142 super.initState();
141 initDio(); 143 initDio();
142 _initFluwx(); 144 _initFluwx();
143 - _isLogin(); 145 + _isFirst();
144 Utils.changeStatusColor(); 146 Utils.changeStatusColor();
145 // 设置EasyRefresh的默认样式 147 // 设置EasyRefresh的默认样式
146 EasyRefresh.defaultHeader = MaterialHeader(); 148 EasyRefresh.defaultHeader = MaterialHeader();
@@ -173,6 +175,14 @@ class MyAppState extends State<MyApp> { @@ -173,6 +175,14 @@ class MyAppState extends State<MyApp> {
173 DioUtil().setConfig(config); 175 DioUtil().setConfig(config);
174 } 176 }
175 177
  178 +//第一次打开应用
  179 + bool _isFirst() {
  180 + isFirst = App.sp.getBool("isFirst") ?? true;
  181 + if (!isFirst) {
  182 + _isLogin();
  183 + }
  184 + }
  185 +
176 //判断是否登录 186 //判断是否登录
177 bool _isLogin() { 187 bool _isLogin() {
178 UserModel userModel = Provider.of<UserModel>(context, listen: false); 188 UserModel userModel = Provider.of<UserModel>(context, listen: false);
@@ -194,10 +204,12 @@ class MyAppState extends State<MyApp> { @@ -194,10 +204,12 @@ class MyAppState extends State<MyApp> {
194 textTheme: 204 textTheme:
195 TextTheme(overline: TextStyle(decoration: TextDecoration.none)), 205 TextTheme(overline: TextStyle(decoration: TextDecoration.none)),
196 tooltipTheme: TooltipThemeData(verticalOffset: -100000)), 206 tooltipTheme: TooltipThemeData(verticalOffset: -100000)),
197 - home: isLogin  
198 - ? HomePage(initialIndex: 1)  
199 - : ChangeNotifierProvider<OtherLoginProvider>(  
200 - create: (_) => OtherLoginProvider(), child: LoginPage()), 207 + home: isFirst
  208 + ? FirstPage()
  209 + : isLogin
  210 + ? HomePage(initialIndex: 1)
  211 + : ChangeNotifierProvider<OtherLoginProvider>(
  212 + create: (_) => OtherLoginProvider(), child: LoginPage()),
201 onGenerateRoute: App.router.generator, 213 onGenerateRoute: App.router.generator,
202 ); 214 );
203 } 215 }
  1 +import 'dart:io';
  2 +
  3 +import 'package:flutter/material.dart';
  4 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  5 +import 'package:one_key/app.dart';
  6 +import 'package:one_key/res/colors.dart';
  7 +import 'package:one_key/route/navigator_util.dart';
  8 +import 'package:one_key/utils/dialog_util.dart';
  9 +import 'package:one_key/utils/utils.dart';
  10 +import 'package:one_key/widgets/MyDivider.dart';
  11 +import 'package:one_key/widgets/round_button.dart';
  12 +import 'package:one_key/widgets/v_empty_view.dart';
  13 +
  14 +class FirstPage extends StatefulWidget {
  15 + FirstPage({Key key}) : super(key: key);
  16 +
  17 + @override
  18 + _FirstPageState createState() => _FirstPageState();
  19 +}
  20 +
  21 +class _FirstPageState extends State<FirstPage> {
  22 + @override
  23 + void initState() {
  24 + // TODO: implement initState
  25 + super.initState();
  26 + Utils.changeStatusColor(color: MyColours.color_199095);
  27 + }
  28 +
  29 + @override
  30 + Widget build(BuildContext context) {
  31 + ScreenUtil.init(context, width: 750, height: 1334);
  32 + return Scaffold(
  33 + body: Container(
  34 + color: MyColours.color_199095,
  35 + height: double.infinity,
  36 + padding: EdgeInsets.symmetric(
  37 + horizontal: ScreenUtil().setWidth(40),
  38 + vertical: ScreenUtil().setWidth(80)),
  39 + child: Center(
  40 + child: Container(
  41 + height: ScreenUtil().setWidth(690),
  42 + decoration: BoxDecoration(
  43 + color: MyColours.color_ffffff,
  44 + borderRadius: BorderRadius.circular(ScreenUtil().setWidth(20)),
  45 + ),
  46 + child: Column(
  47 + children: [
  48 + VEmptyView(40),
  49 + Text(
  50 + '温馨提示',
  51 + style: TextStyle(
  52 + color: MyColours.color_333333,
  53 + fontWeight: FontWeight.bold,
  54 + fontSize: ScreenUtil().setSp(34)),
  55 + ),
  56 + VEmptyView(40),
  57 + MyDivider(double.infinity, ScreenUtil().setWidth(1)),
  58 + Expanded(
  59 + child: SingleChildScrollView(
  60 + child: Column(children: [
  61 + VEmptyView(50),
  62 + Padding(
  63 + padding: EdgeInsets.symmetric(
  64 + horizontal: ScreenUtil().setWidth(30)),
  65 + child: Column(
  66 + crossAxisAlignment: CrossAxisAlignment.start,
  67 + children: [
  68 + Text(
  69 + '亲爱的用户,感谢您信任并使用一键订!',
  70 + style: TextStyle(
  71 + color: MyColours.color_333333,
  72 + fontSize: ScreenUtil().setSp(28),
  73 + ),
  74 + strutStyle: StrutStyle(
  75 + forceStrutHeight: true,
  76 + height: 1,
  77 + leading: 0.3),
  78 + ),
  79 + VEmptyView(16),
  80 + Wrap(
  81 + children: [
  82 + Text(
  83 + '我们制定了',
  84 + style: TextStyle(
  85 + color: MyColours.color_333333,
  86 + fontSize: ScreenUtil().setSp(28),
  87 + ),
  88 + strutStyle: StrutStyle(
  89 + forceStrutHeight: true,
  90 + height: 1,
  91 + leading: 0.3),
  92 + ),
  93 + InkWell(
  94 + onTap: () {
  95 + NavigatorUtil.goWebPage(
  96 + context, '《隐私政策》', "zc",
  97 + need: true);
  98 + },
  99 + child: Text(
  100 + '《隐私政策》',
  101 + style: TextStyle(
  102 + color: MyColours.color_2bb5b7,
  103 + fontSize: ScreenUtil().setSp(28),
  104 + ),
  105 + strutStyle: StrutStyle(
  106 + forceStrutHeight: true,
  107 + height: 1,
  108 + leading: 0.3),
  109 + ),
  110 + ),
  111 + Text(
  112 + '和',
  113 + style: TextStyle(
  114 + color: MyColours.color_333333,
  115 + fontSize: ScreenUtil().setSp(28),
  116 + ),
  117 + strutStyle: StrutStyle(
  118 + forceStrutHeight: true,
  119 + height: 1,
  120 + leading: 0.3),
  121 + ),
  122 + InkWell(
  123 + onTap: () {
  124 + NavigatorUtil.goWebPage(
  125 + context, '软件服务协议', "xy",
  126 + need: true);
  127 + },
  128 + child: Text(
  129 + '《软件服务协议》',
  130 + style: TextStyle(
  131 + color: MyColours.color_2bb5b7,
  132 + fontSize: ScreenUtil().setSp(28),
  133 + ),
  134 + strutStyle: StrutStyle(
  135 + forceStrutHeight: true,
  136 + height: 1,
  137 + leading: 0.3),
  138 + ),
  139 + ),
  140 + Text(
  141 + '请您点击同意之前仔细阅读并充分理解相关条款,其中的重点条款已为您标注,方便您了解自己的权利。',
  142 + style: TextStyle(
  143 + color: MyColours.color_333333,
  144 + fontSize: ScreenUtil().setSp(28),
  145 + ),
  146 + strutStyle: StrutStyle(
  147 + forceStrutHeight: true,
  148 + height: 1,
  149 + leading: 0.3),
  150 + ),
  151 + ],
  152 + ),
  153 + VEmptyView(16),
  154 + Text(
  155 + '我们将通过《隐私政策》向您说明:\n我们在您使用我们的产品与/或服务时如何收集、使用、保存、共享和转让这些信息,以及我们为您提供的访问、更新、控制和保护这些信息的方式。',
  156 + style: TextStyle(
  157 + color: MyColours.color_333333,
  158 + fontWeight: FontWeight.bold,
  159 + fontSize: ScreenUtil().setSp(28),
  160 + ),
  161 + strutStyle: StrutStyle(
  162 + forceStrutHeight: true,
  163 + height: 1,
  164 + leading: 0.3),
  165 + ),
  166 + ],
  167 + ),
  168 + )
  169 + ]),
  170 + )),
  171 + VEmptyView(40),
  172 + Row(
  173 + mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  174 + children: [
  175 + RoundButton(
  176 + width: ScreenUtil().setWidth(100 * 2),
  177 + height: ScreenUtil().setWidth(70),
  178 + radius: ScreenUtil().setWidth(10),
  179 + text: '拒绝',
  180 + fontSize: 28,
  181 + isBold: false,
  182 + textColor: MyColours.color_199095,
  183 + gradientStart: MyColours.color_efefef,
  184 + gradientEnd: MyColours.color_efefef,
  185 + onPressed: () {
  186 + //修改之前有内容,则弹框
  187 + DialogUtil.cupertinoAlertDialog(context,
  188 + title: "",
  189 + content: "您需要同意《一键订隐私政策》,才能继续使用我们的服务哦。",
  190 + lTitle: "暂不",
  191 + rTitle: "去同意", lCallback: () {
  192 + print("取消");
  193 + //退出应用
  194 + exit(0);
  195 + }, rCallback: () {
  196 + print("确定");
  197 + });
  198 + }),
  199 + RoundButton(
  200 + width: ScreenUtil().setWidth(100 * 2),
  201 + height: ScreenUtil().setWidth(70),
  202 + radius: ScreenUtil().setWidth(10),
  203 + text: '同意',
  204 + fontSize: 28,
  205 + isBold: false,
  206 + textColor: MyColours.color_ffffff,
  207 + gradientStart: MyColours.color_199095,
  208 + gradientEnd: MyColours.color_199095,
  209 + onPressed: () {
  210 + App.sp.setBool("isFirst", false);
  211 + //进入应用
  212 + NavigatorUtil.goLoginPage(context);
  213 + }),
  214 + ],
  215 + ),
  216 + VEmptyView(40),
  217 + ],
  218 + ),
  219 + ))),
  220 + );
  221 + }
  222 +}
@@ -19,6 +19,7 @@ import 'package:one_key/provider/user_model.dart'; @@ -19,6 +19,7 @@ import 'package:one_key/provider/user_model.dart';
19 import 'package:one_key/res/colors.dart'; 19 import 'package:one_key/res/colors.dart';
20 import 'package:one_key/route/navigate_service.dart'; 20 import 'package:one_key/route/navigate_service.dart';
21 import 'package:one_key/route/navigator_util.dart'; 21 import 'package:one_key/route/navigator_util.dart';
  22 +import 'package:one_key/utils/dialog_util.dart';
22 import 'package:one_key/utils/utils.dart'; 23 import 'package:one_key/utils/utils.dart';
23 import 'package:one_key/widgets/MyDivider.dart'; 24 import 'package:one_key/widgets/MyDivider.dart';
24 import 'package:one_key/widgets/h_empty_view.dart'; 25 import 'package:one_key/widgets/h_empty_view.dart';
@@ -60,6 +61,9 @@ class LoginState extends State<LoginPage> with WidgetsBindingObserver { @@ -60,6 +61,9 @@ class LoginState extends State<LoginPage> with WidgetsBindingObserver {
60 void initState() { 61 void initState() {
61 // TODO: implement initState 62 // TODO: implement initState
62 super.initState(); 63 super.initState();
  64 + //第一次打开应用
  65 +
  66 +
63 _checkWechat(); 67 _checkWechat();
64 isLogin(); 68 isLogin();
65 WidgetsBinding.instance.addObserver(this); 69 WidgetsBinding.instance.addObserver(this);
1 import 'dart:async'; 1 import 'dart:async';
2 2
  3 +import 'package:device_info/device_info.dart';
  4 +import 'package:dio/dio.dart';
3 import 'package:flutter/material.dart'; 5 import 'package:flutter/material.dart';
  6 +import 'package:one_key/net/dio_util.dart';
  7 +import 'package:one_key/res/colors.dart';
4 import 'package:one_key/utils/event_bus.dart'; 8 import 'package:one_key/utils/event_bus.dart';
  9 +import 'package:one_key/utils/utils.dart';
5 import 'package:one_key/widgets/system_app_bar.dart'; 10 import 'package:one_key/widgets/system_app_bar.dart';
  11 +import 'package:path_provider/path_provider.dart';
  12 +import 'package:permission_handler/permission_handler.dart';
6 import 'package:webview_flutter/webview_flutter.dart'; 13 import 'package:webview_flutter/webview_flutter.dart';
7 14
8 -class WebPage extends StatelessWidget { 15 +import 'dart:async';
  16 +import 'dart:convert';
  17 +import 'dart:io';
  18 +
  19 +import 'package:flutter/material.dart';
  20 +import 'package:one_key/utils/event_bus.dart';
  21 +import 'package:one_key/widgets/app_bar.dart';
  22 +import 'package:one_key/widgets/system_app_bar.dart';
  23 +import 'package:webview_flutter/webview_flutter.dart';
  24 +
  25 +import 'package:flutter_inappwebview/flutter_inappwebview.dart';
  26 +import 'package:url_launcher/url_launcher.dart';
  27 +import 'dart:collection';
  28 +// import 'package:open_file/open_file.dart';
  29 +// import 'package:flutter_downloader/flutter_downloader.dart';
  30 +
  31 +class WebPage extends StatefulWidget {
9 final String title; 32 final String title;
10 final String url; 33 final String url;
  34 + final bool need;
11 35
12 - const WebPage({Key key, this.title, this.url}) : super(key: key); 36 + const WebPage({Key key, this.title, this.url, this.need = false})
  37 + : super(key: key);
13 @override 38 @override
14 - Widget build(BuildContext context) {  
15 - final Completer<WebViewController> _controller =  
16 - Completer<WebViewController>();  
17 - return Scaffold(  
18 - appBar: SystemAppBar(title, onTap: () {  
19 - Navigator.of(context).pop();  
20 - }),  
21 - body: WebView(  
22 - initialUrl: "http://colorcun.com/privacy1.html",  
23 - javascriptMode: JavascriptMode.unrestricted,  
24 - onWebViewCreated: (WebViewController webViewController) {  
25 - // Loading.showLoading(context);  
26 - _controller.complete(webViewController);  
27 - },  
28 - javascriptChannels: <JavascriptChannel>[  
29 - _toasterJavascriptChannel(context),  
30 - ].toSet(),  
31 - navigationDelegate: (NavigationRequest request) {  
32 - if (request.url.startsWith('https://www.youtube.com/')) {  
33 - return NavigationDecision.prevent;  
34 - }  
35 - return NavigationDecision.navigate;  
36 - },  
37 - onPageStarted: (String url) {},  
38 - onPageFinished: (String url) {  
39 - // Loading.hideLoading(context);  
40 - },  
41 - gestureNavigationEnabled: true, 39 + _WebPageState createState() => _WebPageState();
  40 +}
  41 +
  42 +class _WebPageState extends State<WebPage> {
  43 + final GlobalKey webViewKey = GlobalKey();
  44 +
  45 + InAppWebViewController webViewController;
  46 + InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
  47 + crossPlatform: InAppWebViewOptions(
  48 + useShouldOverrideUrlLoading: true,
  49 + useOnDownloadStart: true,
  50 + mediaPlaybackRequiresUserGesture: false,
42 ), 51 ),
43 - ); 52 + android: AndroidInAppWebViewOptions(
  53 + useHybridComposition: true,
  54 + ),
  55 + ios: IOSInAppWebViewOptions(
  56 + allowsInlineMediaPlayback: true,
  57 + ));
  58 +
  59 + PullToRefreshController pullToRefreshController;
  60 + ContextMenu contextMenu;
  61 + String url = "";
  62 + double progress = 0;
  63 + final urlController = TextEditingController();
  64 + // Future<void> openFile(filePath) async {
  65 + // final _result = await OpenFile.open(filePath);
  66 + // print(_result.message);
  67 +
  68 + // // setState(() {
  69 + // // _openResult = "type=${_result.type} message=${_result.message}";
  70 + // // });
  71 + // }
  72 +
  73 + @override
  74 + void initState() {
  75 + super.initState();
  76 +
  77 + // Enable hybrid composition.
  78 + _init();
44 } 79 }
45 80
46 - JavascriptChannel _toasterJavascriptChannel(BuildContext context) {  
47 - return JavascriptChannel(  
48 - name: 'Toaster',  
49 - onMessageReceived: (JavascriptMessage message) {  
50 - Scaffold.of(context).showSnackBar(  
51 - SnackBar(content: Text(message.message)),  
52 - );  
53 - }); 81 + Future<bool> _checkPermission() async {
  82 + DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
  83 + AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
  84 + if (Platform.isAndroid && androidInfo.version.sdkInt <= 28) {
  85 + final status = await Permission.storage.status;
  86 + if (status != PermissionStatus.granted) {
  87 + final result = await Permission.storage.request();
  88 + if (result == PermissionStatus.granted) {
  89 + return true;
  90 + }
  91 + } else {
  92 + return true;
  93 + }
  94 + } else {
  95 + return true;
  96 + }
  97 + return false;
54 } 98 }
  99 +
  100 + Future<bool> checkPermissionStorage() async {
  101 + var status = await Permission.storage.status;
  102 + if (!status.isGranted) {
  103 + status = await Permission.storage.request();
  104 + if (status.isGranted) {
  105 + return true;
  106 + }
  107 + } else {
  108 + return true;
  109 + }
  110 + return false;
  111 + }
  112 +
  113 + _init() async {
  114 + // WidgetsFlutterBinding.ensureInitialized();
  115 + // await FlutterDownloader.initialize(debug: true);
  116 + if (Platform.isAndroid) {
  117 + await AndroidInAppWebViewController.setWebContentsDebuggingEnabled(true);
  118 +
  119 + var swAvailable = await AndroidWebViewFeature.isFeatureSupported(
  120 + AndroidWebViewFeature.SERVICE_WORKER_BASIC_USAGE);
  121 + var swInterceptAvailable = await AndroidWebViewFeature.isFeatureSupported(
  122 + AndroidWebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST);
  123 +
  124 + if (swAvailable && swInterceptAvailable) {
  125 + AndroidServiceWorkerController serviceWorkerController =
  126 + AndroidServiceWorkerController.instance();
  127 +
  128 + serviceWorkerController.serviceWorkerClient =
  129 + AndroidServiceWorkerClient(
  130 + shouldInterceptRequest: (request) async {
  131 + print(request);
  132 + return null;
  133 + },
  134 + );
  135 + }
  136 + }
  137 + // await FlutterDownloader.initialize(
  138 + // debug: true // optional: set false to disable printing logs to console
  139 + // );
  140 + await Permission.storage.request();
  141 + }
  142 +
  143 + @override
  144 + Widget build(BuildContext context) {
  145 + return Scaffold(
  146 + // We're using a Builder here so we have a context that is below the Scaffold
  147 + // to allow calling Scaffold.of(context) so we can show a snackbar.
  148 + appBar: SystemAppBar(
  149 + widget.title,
  150 + onTap: () {
  151 + if (widget.need) {
  152 + Utils.changeStatusColor(color: MyColours.color_199095);
  153 + }
  154 + Navigator.of(context).pop();
  155 + },
  156 + ),
  157 + body: WillPopScope(
  158 + onWillPop: () async {
  159 + if (widget.need) {
  160 + Utils.changeStatusColor(color: MyColours.color_199095);
  161 + }
  162 + return true;
  163 + },
  164 + child: Column(
  165 + children: [
  166 + Expanded(
  167 + child: InAppWebView(
  168 + key: webViewKey,
  169 + // contextMenu: contextMenu,
  170 + initialUrlRequest: URLRequest(
  171 + url: Uri.parse("http://colorcun.com/privacy1.html")),
  172 + // initialFile: "assets/index.html",
  173 + initialUserScripts: UnmodifiableListView<UserScript>([]),
  174 + initialOptions: options,
  175 + pullToRefreshController: pullToRefreshController,
  176 + onWebViewCreated: (controller) {
  177 + webViewController = controller;
  178 + },
  179 + onLoadStart: (controller, url) {
  180 + setState(() {
  181 + this.url = url.toString();
  182 + urlController.text = this.url;
  183 + });
  184 + },
  185 + androidOnPermissionRequest:
  186 + (controller, origin, resources) async {
  187 + return PermissionRequestResponse(
  188 + resources: resources,
  189 + action: PermissionRequestResponseAction.GRANT);
  190 + },
  191 + shouldOverrideUrlLoading:
  192 + (controller, navigationAction) async {
  193 + var uri = navigationAction.request.url;
  194 +
  195 + if (![
  196 + "http",
  197 + "https",
  198 + "file",
  199 + "chrome",
  200 + "data",
  201 + "javascript",
  202 + "about"
  203 + ].contains(uri.scheme)) {
  204 + if (await canLaunch(url)) {
  205 + // Launch the App
  206 + await launch(
  207 + url,
  208 + );
  209 + // and cancel the request
  210 + return NavigationActionPolicy.CANCEL;
  211 + }
  212 + }
  213 +
  214 + return NavigationActionPolicy.ALLOW;
  215 + },
  216 + onLoadStop: (controller, url) async {
  217 + pullToRefreshController.endRefreshing();
  218 + setState(() {
  219 + this.url = url.toString();
  220 + urlController.text = this.url;
  221 + });
  222 + },
  223 + onLoadError: (controller, url, code, message) {
  224 + pullToRefreshController.endRefreshing();
  225 + },
  226 + onProgressChanged: (controller, progress) {
  227 + if (progress == 100) {
  228 + pullToRefreshController.endRefreshing();
  229 + }
  230 + setState(() {
  231 + this.progress = progress / 100;
  232 + urlController.text = this.url;
  233 + });
  234 + },
  235 + onUpdateVisitedHistory: (controller, url, androidIsReload) {
  236 + setState(() {
  237 + this.url = url.toString();
  238 + urlController.text = this.url;
  239 + });
  240 + },
  241 + onConsoleMessage: (controller, consoleMessage) {
  242 + print(consoleMessage);
  243 + },
  244 + onDownloadStart: (controller, url) async {
  245 + print("onDownloadStart $url");
  246 + Utils.showToast('开始下载...');
  247 + // final taskId = await FlutterDownloader.enqueue(
  248 + // url: url.toString(),
  249 + // savedDir: (await getExternalStorageDirectory()).path,
  250 + // showNotification:
  251 + // true, // show download progress in status bar (for Android)
  252 + // openFileFromNotification:
  253 + // true, // click on notification to open downloaded file (for Android)
  254 + // );
  255 + final dir = await getExternalStorageDirectory();
  256 + String savePath = dir.path + "/one_key";
  257 +
  258 + Directory directory = new Directory(savePath);
  259 + if (directory.existsSync()) {
  260 + //删除历史apk
  261 + final List<FileSystemEntity> files = directory.listSync();
  262 + for (FileSystemEntity file in files) {
  263 + file.deleteSync();
  264 + }
  265 + }
  266 + DioUtil().download(url.toString(), savePath,
  267 + onProgress: (received, total) {
  268 + // if (_progress != 100) {
  269 + // int progress = ((received / total) * 100).round();
  270 + // _progress = progress;
  271 + // _setState(() {});
  272 + // }
  273 + if (received == total) {
  274 + print('object');
  275 + Utils.showToast('文件已保存在${savePath}');
  276 + // openFile(savePath);
  277 + //下载完成
  278 + // InstallPlugin.installApk(savePath, "com.naji.one_key");
  279 + }
  280 + });
  281 + // },
  282 + // DioUtil().download(url.toString(),
  283 + // (await getExternalStorageDirectory()).path,
  284 + // onProgress: (received, total) {
  285 + // // if (_progress != 100) {
  286 + // // int progress = ((received / total) * 100).round();
  287 + // // _progress = progress;
  288 + // // _setState(() {});
  289 + // // }
  290 + // if (received == total) {
  291 + // //下载完成
  292 + // // InstallPlugin.installApk(savePath, "com.naji.one_key");
  293 + // }
  294 + // });
  295 + },
  296 + ))
  297 + ],
  298 + )
  299 + // Builder(builder: (BuildContext context) {
  300 + // return WebView(
  301 + // initialUrl: "http://colorcun.com/privacy1.html",
  302 + // javascriptMode: JavascriptMode.unrestricted,
  303 + // onWebViewCreated: (WebViewController webViewController) {
  304 + // _controller.complete(webViewController);
  305 + // },
  306 + // // TODO(iskakaushik): Remove this when collection literals makes it to stable.
  307 + // // ignore: prefer_collection_literals
  308 + // javascriptChannels: <JavascriptChannel>[
  309 + // _toasterJavascriptChannel(context),
  310 + // ].toSet(),
  311 + // navigationDelegate: (NavigationRequest request) {
  312 + // if (request.url.startsWith('https://www.youtube.com/')) {
  313 + // print('blocking navigation to $request}');
  314 + // return NavigationDecision.prevent;
  315 + // }
  316 + // print('allowing navigation to $request');
  317 + // return NavigationDecision.navigate;
  318 + // },
  319 + // onPageStarted: (String url) {
  320 + // print('Page started loading: $url');
  321 + // },
  322 + // onPageFinished: (String url) async {
  323 + // print('Page finished loading: $url');
  324 + // // showDownloadProgress(context);
  325 + // final dir = await getExternalStorageDirectory();
  326 + // String savePath = dir.path + "/one_key";
  327 + // DioUtil().download(url, savePath,
  328 + // onProgress: (received, total) {
  329 + // // if (_progress != 100) {
  330 + // // int progress = ((received / total) * 100).round();
  331 + // // _progress = progress;
  332 + // // _setState(() {});
  333 + // // }
  334 + // if (received == total) {
  335 + // print('object');
  336 + // //下载完成
  337 + // // InstallPlugin.installApk(savePath, "com.naji.one_key");
  338 + // }
  339 + // });
  340 + // },
  341 + // gestureNavigationEnabled: true,
  342 + // );
  343 + // }),
  344 + ));
  345 + }
  346 +
  347 + // JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
  348 + // return JavascriptChannel(
  349 + // name: 'Toaster',
  350 + // onMessageReceived: (JavascriptMessage message) {
  351 + // Scaffold.of(context).showSnackBar(
  352 + // SnackBar(content: Text(message.message)),
  353 + // );
  354 + // });
  355 + // }
55 } 356 }
  357 +
  358 +// class WebPage extends StatelessWidget {
  359 +// final String title;
  360 +// final String url;
  361 +// final bool need;
  362 +
  363 +// const WebPage({Key key, this.title, this.url, this.need = false})
  364 +// : super(key: key);
  365 +// @override
  366 +// Widget build(BuildContext context) {
  367 +// final Completer<WebViewController> _controller =
  368 +// Completer<WebViewController>();
  369 +// return Scaffold(
  370 +// appBar: SystemAppBar(title, onTap: () {
  371 +// if (need) {
  372 +// Utils.changeStatusColor(color: MyColours.color_199095);
  373 +// }
  374 +// Navigator.of(context).pop();
  375 +// }),
  376 +// body: WillPopScope(
  377 +// onWillPop: () async {
  378 +// if (need) {
  379 +// Utils.changeStatusColor(color: MyColours.color_199095);
  380 +// }
  381 +// return true;
  382 +// },
  383 +// child: WebView(
  384 +// initialUrl: "http://colorcun.com/privacy1.html",
  385 +// javascriptMode: JavascriptMode.unrestricted,
  386 +// onWebViewCreated: (WebViewController webViewController) {
  387 +// // Loading.showLoading(context);
  388 +// _controller.complete(webViewController);
  389 +// },
  390 +// javascriptChannels: <JavascriptChannel>[
  391 +// _toasterJavascriptChannel(context),
  392 +// ].toSet(),
  393 +// navigationDelegate: (NavigationRequest request) {
  394 +// if (request.url.startsWith('https://www.youtube.com/')) {
  395 +// return NavigationDecision.prevent;
  396 +// }
  397 +// return NavigationDecision.navigate;
  398 +// },
  399 +// onPageStarted: (String url) {},
  400 +// onPageFinished: (String url) {
  401 +// // Loading.hideLoading(context);
  402 +// },
  403 +// gestureNavigationEnabled: true,
  404 +// )),
  405 +// );
  406 +// }
  407 +
  408 +// JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
  409 +// return JavascriptChannel(
  410 +// name: 'Toaster',
  411 +// onMessageReceived: (JavascriptMessage message) {
  412 +// Scaffold.of(context).showSnackBar(
  413 +// SnackBar(content: Text(message.message)),
  414 +// );
  415 +// });
  416 +// }
  417 +// }
@@ -559,6 +559,18 @@ class MyPageState extends State<MyPage> with WidgetsBindingObserver { @@ -559,6 +559,18 @@ class MyPageState extends State<MyPage> with WidgetsBindingObserver {
559 ScreenUtil().setHeight(1), 559 ScreenUtil().setHeight(1),
560 color: MyColours.color_f3f3f3, 560 color: MyColours.color_f3f3f3,
561 ), 561 ),
  562 + MyItem(
  563 + title: "隐私政策",
  564 + content: "",
  565 + callback: () {
  566 + NavigatorUtil.goWebPage(context, '隐私政策', "zc", need: true);
  567 + },
  568 + ),
  569 + MyDivider(
  570 + double.infinity,
  571 + ScreenUtil().setHeight(1),
  572 + color: MyColours.color_f3f3f3,
  573 + ),
562 VEmptyView(40), 574 VEmptyView(40),
563 Consumer<UserModel>( 575 Consumer<UserModel>(
564 builder: 576 builder:
@@ -139,10 +139,11 @@ class NavigatorUtil { @@ -139,10 +139,11 @@ class NavigatorUtil {
139 139
140 ///协议 140 ///协议
141 static Future<dynamic> goWebPage( 141 static Future<dynamic> goWebPage(
142 - BuildContext context, String title, String url) { 142 + BuildContext context, String title, String url,
  143 + {bool need = false}) {
143 return _navigateTo( 144 return _navigateTo(
144 context, 145 context,
145 - "${Routes.web_page}?title=${Uri.encodeComponent(title)}&url=$url", 146 + "${Routes.web_page}?title=${Uri.encodeComponent(title)}&url=$url&need=${need}",
146 ); 147 );
147 } 148 }
148 149
@@ -293,7 +293,8 @@ var webPageHandler = new Handler( @@ -293,7 +293,8 @@ var webPageHandler = new Handler(
293 handlerFunc: (BuildContext context, Map<String, List<Object>> params) { 293 handlerFunc: (BuildContext context, Map<String, List<Object>> params) {
294 String _title = params["title"].first; 294 String _title = params["title"].first;
295 String _url = params["url"].first; 295 String _url = params["url"].first;
296 - return WebPage(title: _title, url: _url); 296 + bool need = params["need"].first == "true" ? true : false;
  297 + return WebPage(title: _title, url: _url, need: need);
297 }); 298 });
298 299
299 // 跳转到变更预订 300 // 跳转到变更预订
@@ -398,6 +398,13 @@ packages: @@ -398,6 +398,13 @@ packages:
398 url: "https://pub.flutter-io.cn" 398 url: "https://pub.flutter-io.cn"
399 source: hosted 399 source: hosted
400 version: "2.2.1" 400 version: "2.2.1"
  401 + flutter_inappwebview:
  402 + dependency: "direct main"
  403 + description:
  404 + name: flutter_inappwebview
  405 + url: "https://pub.flutter-io.cn"
  406 + source: hosted
  407 + version: "5.3.2"
401 flutter_native_image: 408 flutter_native_image:
402 dependency: "direct main" 409 dependency: "direct main"
403 description: 410 description:
@@ -139,6 +139,10 @@ dependencies: @@ -139,6 +139,10 @@ dependencies:
139 flutter_staggered_grid_view: ^0.4.1 139 flutter_staggered_grid_view: ^0.4.1
140 # webview 140 # webview
141 # webview_flutter: ^2.0.13 141 # webview_flutter: ^2.0.13
  142 + flutter_inappwebview: ^5.3.2
  143 + # flutter_downloader: ^1.7.1
  144 + # open_file: ^3.2.1
  145 +
142 webview_flutter: 146 webview_flutter:
143 path: library/webview_flutter-2.0.13-copy_inappwebview_select_file_20210930 147 path: library/webview_flutter-2.0.13-copy_inappwebview_select_file_20210930
144 sendsms: 148 sendsms: