前言:android
Flutter的APP打開後檢測到有新版本,Android端能夠強制更新APK或者跳轉到 Google play 官網去下載,iOS端只能去 App Store 官網下載。由於咱們的應用是上架到 Google Play,因此當用戶點擊下載的按鈕,直接跳轉到 Google Play 官網或者 App Store 官網去下載APK便可。下面我簡單總結一下在Flutter中實現「版本更新」的功能。服務器
思路:網絡
1.第一次打開APP時執行"版本更新"的網絡請求;app
2.比較服務器的版本號跟當前的版本號,來判斷要不要升級APP應用程序;async
3.彈出「版本更新」對話框;ide
4.點擊"Later"把時間戳保存下來,每次打開APP獲取當前時間戳;ui
5.若是新舊時間戳的差大於或等於一天,執行網絡請求(直到點擊"DownLoad"爲止);this
6.點擊"DownLoad"直接到 Google Play 官網去下載APK。google
實現的步驟:url
1.在pubspec.yaml添加sdk
version: 1.0.2+3 #版本名稱:1.0.2 版本號:3 dependencies: ... cupertino_icons: ^0.1.0 package_info: ^0.3.2+1
2.導包
import 'package:package_info/package_info.dart';
3.第一次打開APP時執行"版本更新"的網絡請求
class UpdatePagerState extends State<UpdaterPage> { var _serviceVersionCode, _serviceVersionName, _serviceVersionPlatform, _serviceVersionApp;; @override void initState() { super.initState(); _getNewVersionAPP(); } //執行版本更新的網絡請求 _getNewVersionAPP() async { String url = IHttpService.getNewVersionApp; DioUtil.getInstance().get(context, url).then((response) { if (response != null) { setState(() { var data = response.data; _serviceVersionCode = data["versionCode"].toString(); //版本號 _serviceVersionName = data["versionName"].toString(); //版本名稱 _serviceVersionPlatform = data["versionPlatform"].toString();//版本平臺 _serviceVersionApp = data["versionApp"].toString();//下載的url _checkVersionCode(); }); } }); } }
4.比較服務器的版本號跟當前的版本號,來判斷要不要升級APP應用程序
void _checkVersionCode() { PackageInfo.fromPlatform().then((PackageInfo packageInfo) { var _currentVersionCode = packageInfo.version;//獲取當前的版本號 int serviceVersionCode = int.parse(_serviceVersionCode); //String -> int int currentVersionCode = int.parse(_currentVersionCode); //String -> int //若是獲取服務器的版本號比當前應用程序的版本號還高,那麼提示升級 if (serviceVersionCode > currentVersionCode) { _showNewVersionAppDialog();//彈出"版本更新"的對話框 } }); }
5.彈出「版本更新」對話框
Future<void> _showNewVersionAppDialog() async { if (_serviceVersionPlatform == "android") { return showDialog<void>( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( title: new Row( children: <Widget>[ new Image.asset("images/ic_launcher_icon.png", height: 35.0, width: 35.0), new Padding( padding: const EdgeInsets.fromLTRB(30.0, 0.0, 10.0, 0.0), child: new Text("項目名稱", style: dialogButtonTextStyle)) ], ), content: new Text( '版本更新', style: dialogTextStyle), actions: <Widget>[ new FlatButton( child: new Text('Later', style: dialogButtonTextStyle), onPressed: () { Navigator.of(context).pop(); }, ), new FlatButton( child: new Text('DownLoad', style: dialogButtonTextStyle), onPressed: () { //https://play.google.com/store/apps/details?id=項目包名 launch(_serviceVersionApp);//到Google Play 官網下載 Navigator.of(context).pop(); }, ) ], ); }); }else{ //iOS return showDialog<void>( context: context, barrierDismissible: false, builder: (BuildContext context) { return CupertinoAlertDialog( title: new Row( children: <Widget>[ new Image.asset("images/ic_launcher_icon.png", height: 35.0, width: 35.0), new Padding( padding: const EdgeInsets.fromLTRB(30.0, 0.0, 10.0, 0.0), child: new Text(Strings.new_version_title, style: dialogButtonTextStyle)) ], ), content: new Text( "New version v$_serviceVersionName is available. " + Strings.new_version_dialog_content, style: dialogTextStyle), actions: <Widget>[ new CupertinoDialogAction( child: new Text(Strings.new_version_button_later, style: dialogButtonTextStyle), onPressed: () { Navigator.of(context).pop(); }, ), new CupertinoDialogAction( child: new Text(Strings.new_version_button_download, style: dialogButtonTextStyle), onPressed: () { //_serviceVersionApp="http://itunes.apple.com/cn/lookup?id=項目包名" launch(_serviceVersionApp);//到APP store 官網下載 Navigator.of(context).pop(); }, ) ], ); }); } }
6.完整的代碼
class UpdaterPage extends StatefulWidget { final Widget child; const UpdaterPage(this.child); @override UpdatePagerState createState() => UpdatePagerState(); } class UpdatePagerState extends State<UpdaterPage> { var _serviceVersionCode, _serviceVersionName, _serviceVersionPlatform, _serviceVersionApp; @override void initState() { super.initState(); //每次打開APP獲取當前時間戳 var timeEnd = DateTime.now().millisecondsSinceEpoch; //獲取"Later"保存的時間戳 var timeStart = SpUtil.getInt(Constants.timeStart); if (timeStart == 0) {//第一次打開APP時執行"版本更新"的網絡請求 _getNewVersionAPP(); } else if (timeStart != 0 && timeEnd - timeStart >= 24 * 60 * 60 * 1000) { //若是新舊時間戳的差大於或等於一天,執行網絡請求 _getNewVersionAPP(); } } //執行版本更新的網絡請求 _getNewVersionAPP() async { String url = IHttpService.getNewVersionApp; DioUtil.getInstance().get(context, url).then((response) { if (response != null) { setState(() { var data = response.data; _serviceVersionCode = data["versionCode"].toString();//版本號 _serviceVersionName = data["versionName"].toString();//版本名稱 _serviceVersionPlatform = data["versionPlatform"].toString();//版本平臺 _serviceVersionApp = data["versionApp"].toString();//下載的URL _checkVersionCode(); }); } }); } //檢查版本更新的版本號 _checkVersionCode() async { PackageInfo packageInfo = await PackageInfo.fromPlatform(); String _currentVersionCode = packageInfo.version; int serviceVersionCode = int.parse(_serviceVersionCode); //String -> int int currentVersionCode = int.parse(_currentVersionCode); //String -> int if (serviceVersionCode > currentVersionCode) { _showNewVersionAppDialog();//彈出對話框 } } //彈出"版本更新"對話框 Future<void> _showNewVersionAppDialog() async { if (_serviceVersionPlatform == "android") { return showDialog<void>( context: context, barrierDismissible: false, builder: (BuildContext context) { return AlertDialog( title: new Row( children: <Widget>[ new Image.asset("images/ic_launcher_icon.png", height: 35.0, width: 35.0), new Padding( padding: const EdgeInsets.fromLTRB(30.0, 0.0, 10.0, 0.0), child: new Text("項目名稱", style: dialogButtonTextStyle)) ], ), content: new Text( '版本更新', style: dialogTextStyle), actions: <Widget>[ new FlatButton( child: new Text('Later', style: dialogButtonTextStyle), onPressed: () { Navigator.of(context).pop(); var timeStart = DateTime.now().millisecondsSinceEpoch; DataUtil.saveCurrentTimeMillis(timeStart);//保存當前的時間戳 }, ), new FlatButton( child: new Text('DownLoad', style: dialogButtonTextStyle), onPressed: () { //https://play.google.com/store/apps/details?id=項目包名 launch(_serviceVersionApp);//到Google Play 官網下載 Navigator.of(context).pop(); }, ) ], ); }); }else{ //iOS return showDialog<void>( context: context, barrierDismissible: false, builder: (BuildContext context) { return CupertinoAlertDialog( title: new Row( children: <Widget>[ new Image.asset("images/ic_launcher_icon.png", height: 35.0, width: 35.0), new Padding( padding: const EdgeInsets.fromLTRB(30.0, 0.0, 10.0, 0.0), child: new Text(Strings.new_version_title, style: dialogButtonTextStyle)) ], ), content: new Text( "New version v$_serviceVersionName is available. " + Strings.new_version_dialog_content, style: dialogTextStyle), actions: <Widget>[ new CupertinoDialogAction( child: new Text(Strings.new_version_button_later, style: dialogButtonTextStyle), onPressed: () { Navigator.of(context).pop(); var timeStart = DateTime.now().millisecondsSinceEpoch; DataUtil.saveCurrentTimeMillis(timeStart);//保存當前的時間戳 }, ), new CupertinoDialogAction( child: new Text(Strings.new_version_button_download, style: dialogButtonTextStyle), onPressed: () { //_serviceVersionApp="http://itunes.apple.com/cn/lookup?id=項目包名" launch(_serviceVersionApp);//到APP store 官網下載 Navigator.of(context).pop(); }, ) ], ); }); } } @override Widget build(BuildContext context) => widget.child; }
7.在首頁調用」版本更新」的類
class IndexPage extends StatefulWidget { @override IndexPageState createState() => IndexPageState(); } class IndexPageState extends State<IndexPage>{ @override Widget build(BuildContext context) { return UpdaterPage(Scaffold( //調用UpdaterPage appBar: _buildAppBar(), body: getScreen() )); } }
8.總結
當有新版本須要升級時,客戶端會"版本更新"彈出對話框,Android用戶跳轉到 Google Play 官網去下載APK,而iOS用戶跳轉到 App Store 官網下載。APP版本更新的功能已經實現,歡迎你們圍觀。若是有什麼疑問的話,能夠留言聯繫我哦!