From d9063453a5b9a1b5cde8dc381b8f82ad6f1a711c Mon Sep 17 00:00:00 2001 From: yushu <894295059@qq.com> Date: Tue, 27 Apr 2021 19:32:02 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=9B=B4=E6=96=B0compileSdkVersion=20null?= =?UTF-8?q?=20safe=E7=A9=BA=E5=AE=89=E5=85=A8=E8=BF=81=E7=A7=BB=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=87=AA=E5=AE=9A=E4=B9=89=E5=BC=B9=E6=A1=86?= =?UTF-8?q?UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flutter_app_upgrade/android/build.gradle | 2 +- .../FlutterAppUpgradePlugin.kt | 10 +- flutter_app_upgrade/example/lib/main.dart | 28 +++- flutter_app_upgrade/example/pubspec.yaml | 2 +- .../example/test/widget_test.dart | 4 +- flutter_app_upgrade/lib/src/app_market.dart | 4 +- flutter_app_upgrade/lib/src/app_upgrade.dart | 151 ++++++++++-------- .../lib/src/custom_app_upgrade.dart | 130 +++++++++++++++ .../lib/src/flutter_upgrade.dart | 8 +- .../lib/src/liquid_progress_indicator.dart | 45 +++--- .../lib/src/simple_app_upgrade.dart | 73 +++++---- flutter_app_upgrade/lib/src/wave.dart | 22 +-- flutter_app_upgrade/pubspec.yaml | 4 +- 13 files changed, 321 insertions(+), 162 deletions(-) create mode 100644 flutter_app_upgrade/lib/src/custom_app_upgrade.dart diff --git a/flutter_app_upgrade/android/build.gradle b/flutter_app_upgrade/android/build.gradle index d5372c6..540c5d9 100644 --- a/flutter_app_upgrade/android/build.gradle +++ b/flutter_app_upgrade/android/build.gradle @@ -25,7 +25,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 28 + compileSdkVersion 30 sourceSets { main.java.srcDirs += 'src/main/kotlin' diff --git a/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt b/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt index 2241ed1..418b626 100644 --- a/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt +++ b/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt @@ -59,7 +59,7 @@ public class FlutterAppUpgradePlugin : FlutterPlugin, MethodCallHandler, Activit if (call.method == "getAppInfo") { getAppInfo(mContext, result) } else if (call.method == "getApkDownloadPath") { - result.success(mContext.getExternalFilesDir("").absolutePath) + result.success(mContext.getExternalFilesDir("")?.absolutePath) } else if (call.method == "install") { //安装app val path = call.argument("path") @@ -124,7 +124,7 @@ public class FlutterAppUpgradePlugin : FlutterPlugin, MethodCallHandler, Activit if (nameEmpty || classEmpty) { goToMarket.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) } else { - goToMarket.setClassName(marketPackageName, marketClassName) + goToMarket.setClassName(marketPackageName!!, marketClassName!!) } context.startActivity(goToMarket) } catch (e: ActivityNotFoundException) { @@ -157,11 +157,7 @@ public class FlutterAppUpgradePlugin : FlutterPlugin, MethodCallHandler, Activit val intent = Intent().setPackage(packageName) val infos = manager.queryIntentActivities(intent, PackageManager.GET_INTENT_FILTERS) - return if (infos == null || infos.size < 1) { - false - } else { - true - } + return infos.size >= 1 } /** diff --git a/flutter_app_upgrade/example/lib/main.dart b/flutter_app_upgrade/example/lib/main.dart index 4f19a10..3f25484 100644 --- a/flutter_app_upgrade/example/lib/main.dart +++ b/flutter_app_upgrade/example/lib/main.dart @@ -1,5 +1,6 @@ -import 'package:flutter/material.dart'; import 'dart:async'; + +import 'package:flutter/material.dart'; import 'package:flutter_app_upgrade/flutter_app_upgrade.dart'; void main() => runApp(MyApp()); @@ -44,7 +45,7 @@ class Home extends StatefulWidget { } class _HomeState extends State { - AppInfo _appInfo; + AppInfo? _appInfo; List _appMarketList = []; String _installMarkets = ''; @@ -79,6 +80,27 @@ class _HomeState extends State { ); } + ///自定义界面 + _checkAppUpgrade2() { + AppUpgrade.appUpgrade(context, _checkAppInfo(), + iosAppId: 'id88888888', + downloadProgress: (count, total) { + print('count:$count,total:$total'); + }, + downloadStatusChange: (DownloadStatus status, {dynamic error}) { + print('status:$status,error:$error'); + }, + dialogBuilder: (onOk) => MaterialButton( + onPressed: onOk, + padding: EdgeInsets.symmetric(horizontal: 40, vertical: 2), + color: Colors.blueAccent, + child: Text("升级", + style: const TextStyle(color: Colors.white, fontSize: 16)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20)), + )); + } + Future _checkAppInfo() async { //这里一般访问网络接口,将返回的数据解析成如下格式 return Future.delayed(Duration(seconds: 1), () { @@ -121,4 +143,4 @@ class _HomeState extends State { ], ); } -} \ No newline at end of file +} diff --git a/flutter_app_upgrade/example/pubspec.yaml b/flutter_app_upgrade/example/pubspec.yaml index f2e8cb0..56a8ab0 100644 --- a/flutter_app_upgrade/example/pubspec.yaml +++ b/flutter_app_upgrade/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Demonstrates how to use the flutter_app_upgrade plugin. publish_to: 'none' environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: diff --git a/flutter_app_upgrade/example/test/widget_test.dart b/flutter_app_upgrade/example/test/widget_test.dart index b84635a..a3af28e 100644 --- a/flutter_app_upgrade/example/test/widget_test.dart +++ b/flutter_app_upgrade/example/test/widget_test.dart @@ -18,8 +18,8 @@ void main() { // Verify that platform version is retrieved. expect( find.byWidgetPredicate( - (Widget widget) => widget is Text && - widget.data.startsWith('Running on:'), + (Widget widget) => + widget is Text && widget.data!.startsWith('Running on:'), ), findsOneWidget, ); diff --git a/flutter_app_upgrade/lib/src/app_market.dart b/flutter_app_upgrade/lib/src/app_market.dart index 87b7925..332c76c 100644 --- a/flutter_app_upgrade/lib/src/app_market.dart +++ b/flutter_app_upgrade/lib/src/app_market.dart @@ -27,8 +27,8 @@ class AppMarket { return marketList; } - static AppMarketInfo getBuildInMarket(String packageName) { - AppMarketInfo _info; + static AppMarketInfo? getBuildInMarket(String packageName) { + AppMarketInfo? _info; buildInMarketList.forEach((f) { if (f.packageName == packageName) { _info = f; diff --git a/flutter_app_upgrade/lib/src/app_upgrade.dart b/flutter_app_upgrade/lib/src/app_upgrade.dart index b7855ed..fddb493 100644 --- a/flutter_app_upgrade/lib/src/app_upgrade.dart +++ b/flutter_app_upgrade/lib/src/app_upgrade.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_app_upgrade/flutter_app_upgrade.dart'; +import 'custom_app_upgrade.dart'; import 'download_status.dart'; import 'simple_app_upgrade.dart'; @@ -47,27 +48,28 @@ class AppUpgrade { /// /// `downloadStatusChange`:下载状态变化回调 /// - static appUpgrade( + static void appUpgrade( BuildContext context, - Future future, { - TextStyle titleStyle, - TextStyle contentStyle, - String cancelText, - TextStyle cancelTextStyle, - String okText, - TextStyle okTextStyle, - List okBackgroundColors, - Color progressBarColor, + Future future, { + TextStyle? titleStyle, + TextStyle? contentStyle, + String? cancelText, + TextStyle? cancelTextStyle, + String? okText, + TextStyle? okTextStyle, + List? okBackgroundColors, + Color? progressBarColor, double borderRadius = 20.0, - String iosAppId, - AppMarketInfo appMarketInfo, - VoidCallback onCancel, - VoidCallback onOk, - DownloadProgressCallback downloadProgress, - DownloadStatusChangeCallback downloadStatusChange, + required String iosAppId, + AppMarketInfo? appMarketInfo, + VoidCallback? onCancel, + VoidCallback? onOk, + DownloadProgressCallback? downloadProgress, + DownloadStatusChangeCallback? downloadStatusChange, + Widget Function(VoidCallback onOk)? dialogBuilder, }) { - future.then((AppUpgradeInfo appUpgradeInfo) { - if (appUpgradeInfo != null && appUpgradeInfo.title != null) { + future.then((AppUpgradeInfo? appUpgradeInfo) { + if (appUpgradeInfo != null) { _showUpgradeDialog( context, appUpgradeInfo.title, appUpgradeInfo.contents, apkDownloadUrl: appUpgradeInfo.apkDownloadUrl, @@ -86,7 +88,9 @@ class AppUpgrade { onCancel: onCancel, onOk: onOk, downloadProgress: downloadProgress, - downloadStatusChange: downloadStatusChange); + downloadStatusChange: downloadStatusChange, + //自定义升级界面 + dialogBuilder: dialogBuilder); } }).catchError((onError) { print('$onError'); @@ -96,27 +100,28 @@ class AppUpgrade { /// /// 展示app升级提示框 /// - static _showUpgradeDialog( + static void _showUpgradeDialog( BuildContext context, String title, List contents, { - String apkDownloadUrl, + String? apkDownloadUrl, bool force = false, - TextStyle titleStyle, - TextStyle contentStyle, - String cancelText, - TextStyle cancelTextStyle, - String okText, - TextStyle okTextStyle, - List okBackgroundColors, - Color progressBarColor, + TextStyle? titleStyle, + TextStyle? contentStyle, + String? cancelText, + TextStyle? cancelTextStyle, + String? okText, + TextStyle? okTextStyle, + List? okBackgroundColors, + Color? progressBarColor, double borderRadius = 20.0, - String iosAppId, - AppMarketInfo appMarketInfo, - VoidCallback onCancel, - VoidCallback onOk, - DownloadProgressCallback downloadProgress, - DownloadStatusChangeCallback downloadStatusChange, + required String iosAppId, + AppMarketInfo? appMarketInfo, + VoidCallback? onCancel, + VoidCallback? onOk, + DownloadProgressCallback? downloadProgress, + DownloadStatusChangeCallback? downloadStatusChange, + Widget Function(VoidCallback onOk)? dialogBuilder, }) { showDialog( context: context, @@ -126,42 +131,52 @@ class AppUpgrade { onWillPop: () async { return false; }, - child: Dialog( - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.all(Radius.circular(borderRadius))), - child: SimpleAppUpgradeWidget( - title: title, - titleStyle: titleStyle, - contents: contents, - contentStyle: contentStyle, - cancelText: cancelText, - cancelTextStyle: cancelTextStyle, - okText: okText, - okTextStyle: okTextStyle, - okBackgroundColors: okBackgroundColors ?? - [ - Theme.of(context).primaryColor, - Theme.of(context).primaryColor - ], - progressBarColor: progressBarColor, - borderRadius: borderRadius, - downloadUrl: apkDownloadUrl, - force: force, - iosAppId: iosAppId, - appMarketInfo: appMarketInfo, - onCancel: onCancel, - onOk: onOk, - downloadProgress: downloadProgress, - downloadStatusChange: downloadStatusChange - )), + child: dialogBuilder != null + ? Dialog( + insetPadding: + EdgeInsets.symmetric(horizontal: 0.0, vertical: 0.0), + child: CustomAppUpgradeWidget( + iosAppId: iosAppId, dialogBuilder: dialogBuilder), + backgroundColor: Colors.transparent, + ) + : Dialog( + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.all(Radius.circular(borderRadius))), + child: SimpleAppUpgradeWidget( + title: title, + titleStyle: titleStyle, + contents: contents, + contentStyle: contentStyle, + cancelText: cancelText, + cancelTextStyle: cancelTextStyle, + okText: okText, + okTextStyle: okTextStyle, + okBackgroundColors: okBackgroundColors ?? + [ + Theme.of(context).primaryColor, + Theme.of(context).primaryColor + ], + progressBarColor: progressBarColor, + borderRadius: borderRadius, + downloadUrl: apkDownloadUrl, + force: force, + iosAppId: iosAppId, + appMarketInfo: appMarketInfo, + onCancel: onCancel, + onOk: onOk, + downloadProgress: downloadProgress, + downloadStatusChange: downloadStatusChange)), ); }); } } class AppInfo { - AppInfo({this.versionName, this.versionCode, this.packageName}); + AppInfo( + {required this.versionName, + required this.versionCode, + required this.packageName}); String versionName; String versionCode; @@ -170,8 +185,8 @@ class AppInfo { class AppUpgradeInfo { AppUpgradeInfo( - {@required this.title, - @required this.contents, + {required this.title, + required this.contents, this.apkDownloadUrl, this.force = false}); @@ -188,7 +203,7 @@ class AppUpgradeInfo { /// /// apk下载url /// - final String apkDownloadUrl; + final String? apkDownloadUrl; /// /// 是否强制升级 diff --git a/flutter_app_upgrade/lib/src/custom_app_upgrade.dart b/flutter_app_upgrade/lib/src/custom_app_upgrade.dart new file mode 100644 index 0000000..bbf7f00 --- /dev/null +++ b/flutter_app_upgrade/lib/src/custom_app_upgrade.dart @@ -0,0 +1,130 @@ +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_app_upgrade/flutter_app_upgrade.dart'; +import 'package:flutter_app_upgrade/src/download_status.dart'; + +/// +/// des:自定义UI +/// +class CustomAppUpgradeWidget extends StatefulWidget { + const CustomAppUpgradeWidget( + {this.downloadUrl, + this.force = false, + required this.iosAppId, + this.appMarketInfo, + this.onOk, + required this.dialogBuilder, + this.downloadProgress, + this.downloadStatusChange}); + + /// + /// app安装包下载url,没有下载跳转到应用宝等渠道更新 + /// + final String? downloadUrl; + + /// + /// 是否强制升级,设置true没有取消按钮 + /// + final bool force; + + /// + /// ios app id,用于跳转app store + /// + final String iosAppId; + + final Widget Function(VoidCallback onOk) dialogBuilder; + + /// + /// 指定跳转的应用市场, + /// 如果不指定将会弹出提示框,让用户选择哪一个应用市场。 + /// + final AppMarketInfo? appMarketInfo; + + final VoidCallback? onOk; + final DownloadProgressCallback? downloadProgress; + final DownloadStatusChangeCallback? downloadStatusChange; + + @override + State createState() => _CustomAppUpgradeWidget(); +} + +class _CustomAppUpgradeWidget extends State { + static final String _downloadApkName = 'temp.apk'; + + /// + /// 下载进度 + /// + double _downloadProgress = 0.0; + + DownloadStatus _downloadStatus = DownloadStatus.none; + + @override + Widget build(BuildContext context) { + return widget.dialogBuilder(_onOk); + } + + void _onOk() { + _clickOk(); + } + + /// + /// 点击确定按钮 + /// + _clickOk() async { + widget.onOk?.call(); + if (Platform.isIOS) { + //ios 需要跳转到app store更新,原生实现 + FlutterUpgrade.toAppStore(widget.iosAppId); + return; + } + if (widget.downloadUrl == null || widget.downloadUrl!.isEmpty) { + //没有下载地址,跳转到第三方渠道更新,原生实现 + FlutterUpgrade.toMarket(appMarketInfo: widget.appMarketInfo); + } + String path = await FlutterUpgrade.apkDownloadPath; + _downloadApk(widget.downloadUrl!, '$path/$_downloadApkName'); + } + + /// + /// 下载apk包 + /// + _downloadApk(String url, String path) async { + if (_downloadStatus == DownloadStatus.start || + _downloadStatus == DownloadStatus.downloading || + _downloadStatus == DownloadStatus.done) { + print('当前下载状态:$_downloadStatus,不能重复下载。'); + return; + } + + _updateDownloadStatus(DownloadStatus.start); + try { + var dio = Dio(); + await dio.download(url, path, onReceiveProgress: (int count, int total) { + if (total == -1) { + _downloadProgress = 0.01; + } else { + widget.downloadProgress?.call(count, total); + _downloadProgress = count / total.toDouble(); + } + setState(() {}); + if (_downloadProgress == 1) { + //下载完成,跳转到程序安装界面 + _updateDownloadStatus(DownloadStatus.done); + Navigator.pop(context); + FlutterUpgrade.installAppForAndroid(path); + } + }); + } catch (e) { + print('$e'); + _downloadProgress = 0; + _updateDownloadStatus(DownloadStatus.error, error: e); + } + } + + _updateDownloadStatus(DownloadStatus downloadStatus, {dynamic error}) { + _downloadStatus = downloadStatus; + widget.downloadStatusChange?.call(_downloadStatus, error: error); + } +} diff --git a/flutter_app_upgrade/lib/src/flutter_upgrade.dart b/flutter_app_upgrade/lib/src/flutter_upgrade.dart index 512876e..3856e39 100644 --- a/flutter_app_upgrade/lib/src/flutter_upgrade.dart +++ b/flutter_app_upgrade/lib/src/flutter_upgrade.dart @@ -4,7 +4,8 @@ import 'package:flutter/services.dart'; import 'package:flutter_app_upgrade/flutter_app_upgrade.dart'; class FlutterUpgrade { - static const MethodChannel _channel = const MethodChannel('flutter_app_upgrade'); + static const MethodChannel _channel = + const MethodChannel('flutter_app_upgrade'); /// /// 获取app信息 @@ -43,7 +44,8 @@ class FlutterUpgrade { /// /// 获取android手机上安装的应用商店 /// - static getInstallMarket({List marketPackageNames}) async { + static Future> getInstallMarket( + {List? marketPackageNames}) async { List packageNameList = AppMarket.buildInPackageNameList; if (marketPackageNames != null && marketPackageNames.length > 0) { packageNameList.addAll(marketPackageNames); @@ -59,7 +61,7 @@ class FlutterUpgrade { /// /// 跳转到应用商店 /// - static toMarket({AppMarketInfo appMarketInfo}) async { + static toMarket({AppMarketInfo? appMarketInfo}) async { var map = { 'marketPackageName': appMarketInfo != null ? appMarketInfo.packageName : '', diff --git a/flutter_app_upgrade/lib/src/liquid_progress_indicator.dart b/flutter_app_upgrade/lib/src/liquid_progress_indicator.dart index a74139d..ff9b884 100644 --- a/flutter_app_upgrade/lib/src/liquid_progress_indicator.dart +++ b/flutter_app_upgrade/lib/src/liquid_progress_indicator.dart @@ -12,19 +12,19 @@ class LiquidLinearProgressIndicator extends ProgressIndicator { final double borderRadius; ///The widget to show in the center of the progress indicator. - final Widget center; + final Widget? center; ///The direction the liquid travels. final Axis direction; LiquidLinearProgressIndicator({ - Key key, + Key? key, double value = 0.5, - Color backgroundColor, - Animation valueColor, - this.borderWidth, - this.borderColor, - this.borderRadius, + Color? backgroundColor, + Animation? valueColor, + required this.borderWidth, + required this.borderColor, + required this.borderRadius, this.center, this.direction = Axis.horizontal, }) : super( @@ -32,12 +32,7 @@ class LiquidLinearProgressIndicator extends ProgressIndicator { value: value, backgroundColor: backgroundColor, valueColor: valueColor, - ) { - if (borderWidth != null && borderColor == null || - borderColor != null && borderWidth == null) { - throw ArgumentError("borderWidth and borderColor should both be set."); - } - } + ); Color _getBackgroundColor(BuildContext context) => backgroundColor ?? Color(0x0000BFFF); //Theme.of(context).backgroundColor; @@ -70,7 +65,7 @@ class _LiquidLinearProgressIndicatorState child: Stack( children: [ Wave( - value: widget.value, + value: widget.value ?? 0.5, color: widget._getValueColor(context), direction: widget.direction, ), @@ -86,7 +81,7 @@ class _LinearPainter extends CustomPainter { final Color color; final double radius; - _LinearPainter({@required this.color, @required this.radius}); + _LinearPainter({required this.color, required this.radius}); @override void paint(Canvas canvas, Size size) { @@ -94,7 +89,7 @@ class _LinearPainter extends CustomPainter { canvas.drawRRect( RRect.fromRectAndRadius( Rect.fromLTWH(0, 0, size.width, size.height), - Radius.circular(radius ?? 0), + Radius.circular(radius), ), paint); } @@ -109,27 +104,23 @@ class _LinearBorderPainter extends CustomPainter { final double radius; _LinearBorderPainter({ - @required this.color, - @required this.width, - @required this.radius, + required this.color, + required this.width, + required this.radius, }); @override void paint(Canvas canvas, Size size) { - if (color == null || width == null) { - return; - } - final paint = Paint() ..color = color ..style = PaintingStyle.stroke ..strokeWidth = width; - final alteredRadius = radius ?? 0; + final alteredRadius = radius; canvas.drawRRect( RRect.fromRectAndRadius( Rect.fromLTWH( width / 2, width / 2, size.width - width, size.height - width), - Radius.circular(alteredRadius - width ?? 0), + Radius.circular(alteredRadius - width), ), paint); } @@ -144,7 +135,7 @@ class _LinearBorderPainter extends CustomPainter { class _LinearClipper extends CustomClipper { final double radius; - _LinearClipper({@required this.radius}); + _LinearClipper({required this.radius}); @override Path getClip(Size size) { @@ -152,7 +143,7 @@ class _LinearClipper extends CustomClipper { ..addRRect( RRect.fromRectAndRadius( Rect.fromLTWH(0, 0, size.width, size.height), - Radius.circular(radius ?? 0), + Radius.circular(radius), ), ); return path; diff --git a/flutter_app_upgrade/lib/src/simple_app_upgrade.dart b/flutter_app_upgrade/lib/src/simple_app_upgrade.dart index d02ab25..ae3f71a 100644 --- a/flutter_app_upgrade/lib/src/simple_app_upgrade.dart +++ b/flutter_app_upgrade/lib/src/simple_app_upgrade.dart @@ -12,9 +12,9 @@ import 'liquid_progress_indicator.dart'; /// class SimpleAppUpgradeWidget extends StatefulWidget { const SimpleAppUpgradeWidget( - {@required this.title, + {required this.title, this.titleStyle, - @required this.contents, + required this.contents, this.contentStyle, this.cancelText, this.cancelTextStyle, @@ -26,7 +26,7 @@ class SimpleAppUpgradeWidget extends StatefulWidget { this.borderRadius = 10, this.downloadUrl, this.force = false, - this.iosAppId, + required this.iosAppId, this.appMarketInfo, this.onCancel, this.onOk, @@ -41,7 +41,7 @@ class SimpleAppUpgradeWidget extends StatefulWidget { /// /// 标题样式 /// - final TextStyle titleStyle; + final TextStyle? titleStyle; /// /// 升级提示内容 @@ -51,47 +51,47 @@ class SimpleAppUpgradeWidget extends StatefulWidget { /// /// 提示内容样式 /// - final TextStyle contentStyle; + final TextStyle? contentStyle; /// /// 下载进度条 /// - final Widget progressBar; + final Widget? progressBar; /// /// 进度条颜色 /// - final Color progressBarColor; + final Color? progressBarColor; /// /// 确认控件 /// - final String okText; + final String? okText; /// /// 确认控件样式 /// - final TextStyle okTextStyle; + final TextStyle? okTextStyle; /// /// 确认控件背景颜色,2种颜色左到右线性渐变 /// - final List okBackgroundColors; + final List? okBackgroundColors; /// /// 取消控件 /// - final String cancelText; + final String? cancelText; /// /// 取消控件样式 /// - final TextStyle cancelTextStyle; + final TextStyle? cancelTextStyle; /// /// app安装包下载url,没有下载跳转到应用宝等渠道更新 /// - final String downloadUrl; + final String? downloadUrl; /// /// 圆角半径 @@ -112,12 +112,12 @@ class SimpleAppUpgradeWidget extends StatefulWidget { /// 指定跳转的应用市场, /// 如果不指定将会弹出提示框,让用户选择哪一个应用市场。 /// - final AppMarketInfo appMarketInfo; + final AppMarketInfo? appMarketInfo; - final VoidCallback onCancel; - final VoidCallback onOk; - final DownloadProgressCallback downloadProgress; - final DownloadStatusChangeCallback downloadStatusChange; + final VoidCallback? onCancel; + final VoidCallback? onOk; + final DownloadProgressCallback? downloadProgress; + final DownloadStatusChangeCallback? downloadStatusChange; @override State createState() => _SimpleAppUpgradeWidget(); @@ -154,16 +154,18 @@ class _SimpleAppUpgradeWidget extends State { /// Widget _buildInfoWidget(BuildContext context) { return Container( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - //标题 - _buildTitle(), - //更新信息 - _buildAppInfo(), - //操作按钮 - _buildAction() - ], + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + //标题 + _buildTitle(), + //更新信息 + _buildAppInfo(), + //操作按钮 + _buildAction() + ], + ), ), ); } @@ -174,7 +176,7 @@ class _SimpleAppUpgradeWidget extends State { _buildTitle() { return Padding( padding: EdgeInsets.only(top: 20, bottom: 30), - child: Text(widget.title ?? '', + child: Text(widget.title, style: widget.titleStyle ?? TextStyle(fontSize: 22))); } @@ -184,7 +186,7 @@ class _SimpleAppUpgradeWidget extends State { _buildAppInfo() { return Container( padding: EdgeInsets.only(left: 15, right: 15, bottom: 30), - height: 200, + constraints: BoxConstraints(maxHeight: 150, minHeight: 120), child: ListView( children: widget.contents.map((f) { return Text( @@ -257,8 +259,7 @@ class _SimpleAppUpgradeWidget extends State { bottomLeft: Radius.circular(widget.borderRadius)); } var _okBackgroundColors = widget.okBackgroundColors; - if (widget.okBackgroundColors == null || - widget.okBackgroundColors.length != 2) { + if (_okBackgroundColors == null || _okBackgroundColors.length != 2) { _okBackgroundColors = [ Theme.of(context).primaryColor, Theme.of(context).primaryColor @@ -297,6 +298,8 @@ class _SimpleAppUpgradeWidget extends State { valueColor: AlwaysStoppedAnimation(widget.progressBarColor ?? Theme.of(context).primaryColor.withOpacity(0.4)), borderRadius: widget.borderRadius, + borderColor: Colors.transparent, + borderWidth: 0, ); } @@ -310,13 +313,13 @@ class _SimpleAppUpgradeWidget extends State { FlutterUpgrade.toAppStore(widget.iosAppId); return; } - if (widget.downloadUrl == null || widget.downloadUrl.isEmpty) { + if (widget.downloadUrl == null || widget.downloadUrl!.isEmpty) { //没有下载地址,跳转到第三方渠道更新,原生实现 FlutterUpgrade.toMarket(appMarketInfo: widget.appMarketInfo); return; } String path = await FlutterUpgrade.apkDownloadPath; - _downloadApk(widget.downloadUrl, '$path/$_downloadApkName'); + _downloadApk(widget.downloadUrl!, '$path/$_downloadApkName'); } /// @@ -351,7 +354,7 @@ class _SimpleAppUpgradeWidget extends State { } catch (e) { print('$e'); _downloadProgress = 0; - _updateDownloadStatus(DownloadStatus.error,error: e); + _updateDownloadStatus(DownloadStatus.error, error: e); } } diff --git a/flutter_app_upgrade/lib/src/wave.dart b/flutter_app_upgrade/lib/src/wave.dart index f8927e5..5d5b7c6 100644 --- a/flutter_app_upgrade/lib/src/wave.dart +++ b/flutter_app_upgrade/lib/src/wave.dart @@ -8,10 +8,10 @@ class Wave extends StatefulWidget { final Axis direction; const Wave({ - Key key, - @required this.value, - @required this.color, - @required this.direction, + Key? key, + required this.value, + required this.color, + required this.direction, }) : super(key: key); @override @@ -19,7 +19,7 @@ class Wave extends StatefulWidget { } class _WaveState extends State with SingleTickerProviderStateMixin { - AnimationController _animationController; + late AnimationController _animationController; @override void initState() { @@ -65,9 +65,9 @@ class _WaveClipper extends CustomClipper { final Axis direction; _WaveClipper({ - @required this.animationValue, - @required this.value, - @required this.direction, + required this.animationValue, + required this.value, + required this.direction, }); @override @@ -94,7 +94,7 @@ class _WaveClipper extends CustomClipper { for (int i = -2; i <= size.height.toInt() + 2; i++) { final waveHeight = (size.width / 20); final dx = math.sin((animationValue * 360 - i) % 360 * (math.pi / 180)) * - waveHeight + + waveHeight + (size.width * value); waveList.add(Offset(dx, i.toDouble())); } @@ -106,7 +106,7 @@ class _WaveClipper extends CustomClipper { for (int i = -2; i <= size.width.toInt() + 2; i++) { final waveHeight = (size.height / 20); final dy = math.sin((animationValue * 360 - i) % 360 * (math.pi / 180)) * - waveHeight + + waveHeight + (size.height - (size.height * value)); waveList.add(Offset(i.toDouble(), dy)); } @@ -116,4 +116,4 @@ class _WaveClipper extends CustomClipper { @override bool shouldReclip(_WaveClipper oldClipper) => animationValue != oldClipper.animationValue; -} \ No newline at end of file +} diff --git a/flutter_app_upgrade/pubspec.yaml b/flutter_app_upgrade/pubspec.yaml index f66d504..9800138 100644 --- a/flutter_app_upgrade/pubspec.yaml +++ b/flutter_app_upgrade/pubspec.yaml @@ -4,13 +4,13 @@ version: 1.1.0 homepage: http://laomengit.com/plugin/upgrade.html environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: sdk: flutter - dio: ^3.0.9 + dio: ^4.0.0 dev_dependencies: flutter_test: From 4112c76883555b0672226302df66e53cdac5973b Mon Sep 17 00:00:00 2001 From: ipcjs Date: Sat, 1 May 2021 18:33:44 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E9=A1=B9=E7=94=A8=E4=BA=8E=E5=8F=91=E5=B8=83=E5=88=B0GooglePla?= =?UTF-8?q?y=E6=97=B6=E7=A6=81=E7=94=A8=E4=B8=8B=E8=BD=BDAPK=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flutter_app_upgrade/android/build.gradle | 13 +++++++++++++ .../flutter_app_upgrade/FlutterAppUpgradePlugin.kt | 12 ++++++++---- .../example/android/gradle.properties | 1 + .../example/android/local.properties | 3 --- 4 files changed, 22 insertions(+), 7 deletions(-) delete mode 100644 flutter_app_upgrade/example/android/local.properties diff --git a/flutter_app_upgrade/android/build.gradle b/flutter_app_upgrade/android/build.gradle index 540c5d9..fb79bec 100644 --- a/flutter_app_upgrade/android/build.gradle +++ b/flutter_app_upgrade/android/build.gradle @@ -21,6 +21,18 @@ rootProject.allprojects { } } +def dartEnvironmentVariables = [ + // 是否是Google Play版, Google Play禁止App从第三方升级, 此时需要禁用掉插件中相关功能 + // 可用通过gradle.properties配置该属性的默认值, 若不配置, 默认为false + flutter_app_upgrade_googlePlay: project.findProperty('flutter_app_upgrade_googlePlayDefaultValue') ?: 'false', +] +if (project.hasProperty('dart-defines')) { + dartEnvironmentVariables += project.property('dart-defines').split(',').collectEntries { + def pair = new String(Base64.decoder.decode(it)).split('=') + [(pair.first()): pair.last()] + } +} + apply plugin: 'com.android.library' apply plugin: 'kotlin-android' @@ -33,6 +45,7 @@ android { defaultConfig { minSdkVersion 16 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + buildConfigField 'boolean', 'googlePlay', dartEnvironmentVariables.flutter_app_upgrade_googlePlay } lintOptions { disable 'InvalidPackage' diff --git a/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt b/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt index 418b626..78ccb72 100644 --- a/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt +++ b/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt @@ -61,10 +61,14 @@ public class FlutterAppUpgradePlugin : FlutterPlugin, MethodCallHandler, Activit } else if (call.method == "getApkDownloadPath") { result.success(mContext.getExternalFilesDir("")?.absolutePath) } else if (call.method == "install") { - //安装app - val path = call.argument("path") - path?.also { - startInstall(mContext, it) + if (BuildConfig.googlePlay) { + result.error("error", "googlePlay=true, The app installation function is disabled.", null) + } else { + // 安装app + val path = call.argument("path") + path?.also { + startInstall(mContext, it) + } } } else if (call.method == "getInstallMarket") { var packageList = getInstallMarket(call.argument>("packages")) diff --git a/flutter_app_upgrade/example/android/gradle.properties b/flutter_app_upgrade/example/android/gradle.properties index 38c8d45..623ed9d 100644 --- a/flutter_app_upgrade/example/android/gradle.properties +++ b/flutter_app_upgrade/example/android/gradle.properties @@ -2,3 +2,4 @@ org.gradle.jvmargs=-Xmx1536M android.enableR8=true android.useAndroidX=true android.enableJetifier=true +flutter_app_upgrade_googlePlayDefaultValue=false \ No newline at end of file diff --git a/flutter_app_upgrade/example/android/local.properties b/flutter_app_upgrade/example/android/local.properties deleted file mode 100644 index 397825c..0000000 --- a/flutter_app_upgrade/example/android/local.properties +++ /dev/null @@ -1,3 +0,0 @@ -sdk.dir=/Users/mengqingdong/Library/Android/sdk -flutter.sdk=/Users/mengqingdong/flutter -flutter.buildMode=debug \ No newline at end of file From 79e2f182b26ca18b320324e013ac97b687142d32 Mon Sep 17 00:00:00 2001 From: ipcjs Date: Sun, 2 May 2021 17:33:38 +0800 Subject: [PATCH 3/5] =?UTF-8?q?googlePlay=E7=89=88,=20=E7=A7=BB=E9=99=A4?= =?UTF-8?q?=E5=AE=89=E8=A3=85apk=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flutter_app_upgrade/android/build.gradle | 5 ++++- flutter_app_upgrade/android/src/google/AndroidManifest.xml | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 flutter_app_upgrade/android/src/google/AndroidManifest.xml diff --git a/flutter_app_upgrade/android/build.gradle b/flutter_app_upgrade/android/build.gradle index fb79bec..e0436a4 100644 --- a/flutter_app_upgrade/android/build.gradle +++ b/flutter_app_upgrade/android/build.gradle @@ -40,7 +40,10 @@ android { compileSdkVersion 30 sourceSets { - main.java.srcDirs += 'src/main/kotlin' + main { + java.srcDirs += 'src/main/kotlin' + manifest.srcFile Boolean.parseBoolean(dartEnvironmentVariables.flutter_app_upgrade_googlePlay) ? 'src/google/AndroidManifest.xml' : 'src/main/AndroidManifest.xml' + } } defaultConfig { minSdkVersion 16 diff --git a/flutter_app_upgrade/android/src/google/AndroidManifest.xml b/flutter_app_upgrade/android/src/google/AndroidManifest.xml new file mode 100644 index 0000000..d14dac4 --- /dev/null +++ b/flutter_app_upgrade/android/src/google/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + From 5dcb32a57cecc43d7cd6fe308eab2f2ba1d6170b Mon Sep 17 00:00:00 2001 From: ipcjs Date: Thu, 6 May 2021 14:22:51 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E8=A7=A3=E6=9E=90dart-defines=E6=94=B9?= =?UTF-8?q?=E7=94=A8url=E7=BC=96=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flutter_app_upgrade/android/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/flutter_app_upgrade/android/build.gradle b/flutter_app_upgrade/android/build.gradle index e0436a4..297016a 100644 --- a/flutter_app_upgrade/android/build.gradle +++ b/flutter_app_upgrade/android/build.gradle @@ -28,7 +28,8 @@ def dartEnvironmentVariables = [ ] if (project.hasProperty('dart-defines')) { dartEnvironmentVariables += project.property('dart-defines').split(',').collectEntries { - def pair = new String(Base64.decoder.decode(it)).split('=') + // def pair = new String(Base64.decoder.decode(it)).split('=') + def pair = URLDecoder.decode(it).split('=') [(pair.first()): pair.last()] } } From f1f6df7a24e297b999e3840af7639b08bafc3281 Mon Sep 17 00:00:00 2001 From: ipcjs Date: Tue, 7 Dec 2021 01:54:41 +0800 Subject: [PATCH 5/5] update compileSdkVersion to 31 --- flutter_app_upgrade/android/build.gradle | 2 +- .../android/src/main/AndroidManifest.xml | 2 ++ .../flutter_app_upgrade/FlutterAppUpgradePlugin.kt | 5 ++--- flutter_app_upgrade/example/android/app/build.gradle | 4 ++-- .../io/flutter/plugins/GeneratedPluginRegistrant.java | 8 +++++++- flutter_app_upgrade/lib/src/app_market.dart | 10 ++++++++++ 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/flutter_app_upgrade/android/build.gradle b/flutter_app_upgrade/android/build.gradle index 297016a..1e8d205 100644 --- a/flutter_app_upgrade/android/build.gradle +++ b/flutter_app_upgrade/android/build.gradle @@ -38,7 +38,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 30 + compileSdkVersion 31 sourceSets { main { diff --git a/flutter_app_upgrade/android/src/main/AndroidManifest.xml b/flutter_app_upgrade/android/src/main/AndroidManifest.xml index 536432d..73baed8 100644 --- a/flutter_app_upgrade/android/src/main/AndroidManifest.xml +++ b/flutter_app_upgrade/android/src/main/AndroidManifest.xml @@ -2,4 +2,6 @@ package="com.flutter.flutter_app_upgrade"> + + diff --git a/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt b/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt index 78ccb72..5b6f9fc 100644 --- a/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt +++ b/flutter_app_upgrade/android/src/main/kotlin/com/flutter/flutter_app_upgrade/FlutterAppUpgradePlugin.kt @@ -159,9 +159,8 @@ public class FlutterAppUpgradePlugin : FlutterPlugin, MethodCallHandler, Activit fun isPackageExist(context: Context, packageName: String?): Boolean { val manager = context.packageManager val intent = Intent().setPackage(packageName) - val infos = manager.queryIntentActivities(intent, - PackageManager.GET_INTENT_FILTERS) - return infos.size >= 1 + val infos = manager.queryIntentActivities(intent, 0) + return infos.size > 0 } /** diff --git a/flutter_app_upgrade/example/android/app/build.gradle b/flutter_app_upgrade/example/android/app/build.gradle index 433d295..62a20ac 100644 --- a/flutter_app_upgrade/example/android/app/build.gradle +++ b/flutter_app_upgrade/example/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 28 + compileSdkVersion 31 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -40,7 +40,7 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.flutter.flutter_app_upgrade_example" minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 31 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/flutter_app_upgrade/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java b/flutter_app_upgrade/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java index 8d57f25..f6e8a22 100644 --- a/flutter_app_upgrade/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java +++ b/flutter_app_upgrade/example/android/app/src/main/java/io/flutter/plugins/GeneratedPluginRegistrant.java @@ -2,6 +2,7 @@ import androidx.annotation.Keep; import androidx.annotation.NonNull; +import io.flutter.Log; import io.flutter.embedding.engine.FlutterEngine; @@ -12,7 +13,12 @@ */ @Keep public final class GeneratedPluginRegistrant { + private static final String TAG = "GeneratedPluginRegistrant"; public static void registerWith(@NonNull FlutterEngine flutterEngine) { - flutterEngine.getPlugins().add(new com.flutter.flutter_app_upgrade.FlutterAppUpgradePlugin()); + try { + flutterEngine.getPlugins().add(new com.flutter.flutter_app_upgrade.FlutterAppUpgradePlugin()); + } catch(Exception e) { + Log.e(TAG, "Error registering plugin flutter_app_upgrade, com.flutter.flutter_app_upgrade.FlutterAppUpgradePlugin", e); + } } } diff --git a/flutter_app_upgrade/lib/src/app_market.dart b/flutter_app_upgrade/lib/src/app_market.dart index 332c76c..6e60aa4 100644 --- a/flutter_app_upgrade/lib/src/app_market.dart +++ b/flutter_app_upgrade/lib/src/app_market.dart @@ -50,6 +50,7 @@ class AppMarket { zte, qiHoo, tencent, + coolApk, pp, wanDouJia ]; @@ -104,6 +105,15 @@ class AppMarket { "com.tencent.android.qqdownloader", "com.tencent.pangu.link.LinkProxyActivity"); + /// + /// 酷安 + /// + static final coolApk = AppMarketInfo( + 'cookApk', + 'com.coolapk.market', + 'com.coolapk.market.view.main.MainActivity', + ); + /// /// pp助手 ///