本人掘金文章
思路步驟:
- 獲取后台接口返回的最新版本的
vsersion
值! (這需要每次APP發版提審后,同時更新后台數據庫Appversion
); - 使用
package_info
插件獲取項目當前APP運行的 的版本號version
; - 后台返回的版本
version
大於package_info
獲取的version
!則彈出提示更新; -
ios
跳轉AppStore
進行更新;android
則App內下載更新;
說明:
-
android
版本的 apk 上傳到公司 oss, 生成的鏈接就是下載鏈接 - 可能存在的坑有, 本地開發模式下
android
下載好的apk安裝不了, 提示應用簽名不一致! (原因 本地開發模式並沒有走 keystore簽名;但是apk有; 用戶從應用商店下載不會出現這情況; 或者你通過apk安裝應用,在走流程測試就不會了
) - 使用的第三方插件有
package_info
用於獲取當前版本號;flutter_xupdate
用於android
App內下載更新; - 效果圖見尾部
具體代碼:
注: android 實現 App 內下載更新,我選用的是 flutter_xupdate
插件並且使用的是自定義JSON的格式(靈活性較好); 插件使用方式請點擊 flutter_xupdate
homePage.dart 文件
import './CheckUpdate.dart'; CheckUpdate checkUpdate = CheckUpdate(); // 獲取版本 Future<dynamic> initPackageInfo () async { PackageInfo packageInfo = await PackageInfo.fromPlatform(); version = packageInfo.version; } // 檢查是否需要版本更新 void _checkUpdateVersion () async { await initPackageInfo(); try { var response = await HttpUtil().post("app/version/detail?", 'mobile', 'json', false); if (response["code"] != 0) { setState(() { versionData = response["data"]; }); // 后台返回的版本號是帶小數點的(2.8.1)所以去除小數點用於做對比 var targetVersion = response["data"]["versionCode"].replaceAll('.', ''); // 當前App運行版本 var currentVersion = version.replaceAll('.', ''); if (int.parse(targetVersion) > int.parse(currentVersion)) { if (Platform.isAndroid) { // 安卓彈窗提示本地下載, 交由flutter_xupdate 處理,不用我們干嘛。 await checkUpdate.initXUpdate(); checkUpdate.checkUpdateByUpdateEntity(versionData); // flutter_xupdate 自定義JSON 方式, } else if (Platform.isIOS) { // IOS 跳轉 AppStore showIOSDialog(); // 彈出ios提示更新框 } } } } catch (e) { print(e); } }
CheckUpdate.dart 文件
import 'dart:convert'; import 'package:flutter_xupdate/flutter_xupdate.dart'; class CheckUpdate{ // 將自定義的json內容解析為UpdateEntity實體類 UpdateEntity customParseJson(String json) { AppInfo appInfo = AppInfo.fromJson(json); return UpdateEntity( isForce: appInfo.isForce, // 是否強制更新 hasUpdate: appInfo.hasUpdate, // 是否需要更新 默認true, 手動自行判斷 isIgnorable: appInfo.isIgnorable, // 是否顯示 “忽略該版本” versionCode: appInfo.versionCode, // 新版本號 versionName: appInfo.versionName, // 新版名稱 updateContent: appInfo.updateLog, // 新版更新日志 downloadUrl: appInfo.apkUrl, // 新版本下載鏈接 apkSize: appInfo.apkSize); // 新版本大小 } // 自定義JSON更新 checkUpdateByUpdateEntity(Map jsonData) async { var versionCode = jsonData["versionCode"].replaceAll('.', ''); var updateText = jsonData["updateLog"].split('。'); var updateLog = ''; updateText.forEach((t) { updateLog += '\r\n$t'; }); var rusultJson = { "isForce": jsonData["isForce"] == 1, "hasUpdate": true, "isIgnorable": false, "versionCode": int.parse(versionCode), "versionName": jsonData["versionName"], "updateLog": updateLog, "apkUrl": jsonData["apkUrl"], "apkSize":jsonData["apkSize"] }; FlutterXUpdate.updateByInfo(updateEntity: customParseJson(json.encode(rusultJson))); } // 初始化插件 Future<dynamic> initXUpdate () async { FlutterXUpdate.init( //是否輸出日志 debug: true, //是否使用post請求 isPost: false, //post請求是否是上傳json isPostJson: false, //是否開啟自動模式 isWifiOnly: false, ///是否開啟自動模式 isAutoMode: false, //需要設置的公共參數 supportSilentInstall: false, //在下載過程中,如果點擊了取消的話,是否彈出切換下載方式的重試提示彈窗 enableRetry: false) .then((value) { print("初始化成功: $value"); }).catchError((error) { print(error); }); FlutterXUpdate.setUpdateHandler( onUpdateError: (Map<String, dynamic> message) async { print("初始化成功: $message"); }, onUpdateParse: (String json) async { //這里是自定義json解析 return customParseJson(json); }); } } // 使用Dart Data Class Generator插件進行創建 使用命令: Generate from JSON class AppInfo { final bool isForce; final bool hasUpdate; final bool isIgnorable; final int versionCode; final String versionName; final String updateLog; final String apkUrl; final int apkSize; AppInfo({ this.isForce, this.hasUpdate, this.isIgnorable, this.versionCode, this.versionName, this.updateLog, this.apkUrl, this.apkSize, }); Map<String, dynamic> toMap() { return { 'isForce': isForce, 'hasUpdate': hasUpdate, 'isIgnorable': isIgnorable, 'versionCode': versionCode, 'versionName': versionName, 'updateLog': updateLog, 'apkUrl': apkUrl, 'apkSize': apkSize, }; } static AppInfo fromMap(Map<String, dynamic> map) { if (map == null) return null; return AppInfo( isForce: map['isForce'], hasUpdate: map['hasUpdate'], isIgnorable: map['isIgnorable'], versionCode: map['versionCode']?.toInt(), versionName: map['versionName'], updateLog: map['updateLog'], apkUrl: map['apkUrl'], apkSize: map['apkSize']?.toInt(), ); } String toJson() => json.encode(toMap()); static AppInfo fromJson(String source) => fromMap(json.decode(source)); @override String toString() { return 'AppInfo isForce: $isForce, hasUpdate: $hasUpdate, isIgnorable: $isIgnorable, versionCode: $versionCode, versionName: $versionName, updateLog: $updateLog, apkUrl: $apkUrl, apkSize: $apkSize'; } }
有疑問歡迎留言
效果圖: 左邊2張為 android, 右邊為 ios