前言:
介紹一下APP更新的流程
1 、Android App 升級執行流程
1、獲取本地版本號
2、請求服務器獲取服務器版本號
3、本地版本和服務器版本不一致提示升級,彈窗提示用戶是否更新
4、用戶確定升級,調用文件傳輸方法下載 apk 文件
5、監聽下載進度
6、下載完成打開 Apk 進行安裝
注意:在 Ios 中沒法直接下載安裝,如果版本不一致直接跳轉到 Ios 應用對應的應用市場就可以了
APP內部更新並且安裝是許多APP必備的功能,其中網上廣爲流傳的方法是利用以下4個插件來更新並安裝APP
package_info: ^0.4.0+4 #檢測版本號
path_provider: ^1.1.0 #文件路徑
open_file: ^2.0.3 #打開文件
flutter_downloader: ^1.3.2 #下載文件
這4個插件是最流行的,但是當我使用的時候,flutter_downloader
卻出現了下面這個錯誤
Unhandled Exception: 'package:flutter_downloader/src/downloader.dart': Failed assertion: line 388 pos 12: 'callbackHandle != null': callback must be a top-level or a static function
後續追加內容
關於這個問題我已在徹底解決Flutter_downloader的問題一文中解決了,如果想要繼續使用Flutter_downloader的請點擊前往
在這裏給大家介紹另外一個下載Apk文件的插件:ota_update
pub地址:https://pub.dev/packages/ota_update
gitHub地址:https://github.com/4Q-s-r-o/ota_update
當然這個插件只是替換flutter_downloader
用的,另外三個插件還是需要使用的。
準備工作:
1
、首先打開你的AndroidManifest.xml
,添加下面這些權限代碼
<provider
android:name="sk.fourq.otaupdate.OtaUpdateFileProvider"
android:authorities="${applicationId}.ota_update_provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
2
、創建xml文件夾,並創建filepaths.xml
文件
3
、將代碼複製進去,就可以了
<paths>
<external-path
name="external-path"
path="."/>
<external-cache-path
name="external-cache-path"
path="."/>
<external-files-path
name="external-files-path"
path="."/>
<files-path
name="files_path"
path="."/>
<cache-path
name="cache-path"
path="."/>
<root-path
name="name"
path="."/>
</paths>
Flutter代碼
首先:
在你需要判斷更新的頁面中引入你安裝的那4個插件
1
、
第一步裏面api.getData()
是我封裝的請求方法,讀者在套用代碼的時候,可以更換爲自己的版本請求接口,
//獲取版本號
_getPackageInfo() async{
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String appName = packageInfo.appName;
String packageName = packageInfo.packageName;
String version = packageInfo.version;
String buildNumber = packageInfo.buildNumber;
api.getData(context, 'update').then((val){
print('-------------獲取版本信息--------------');
var response = json.decode(val.toString());
// 如果當前版本比服務器小,返回-1,大返回1,相等返回0
var isUpdate = version.compareTo(response['version_no']);
setState(() {
app_url = '$base_url${response['app_path']}';
});
// 如果版本低於服務器版本就顯示更新提示
if(isUpdate.toString() == '-1'){
_showDialog();
}
});
print("App名稱:${appName}");
print("包名:${packageName}");
print("version:${version}");
print("打包次數:${buildNumber}");
}
彈框在這裏我就不佔用地方給大家寫了,直接就貼出來下載的方法了
//下載並打開文件
_downLoad()async {
// 獲取APP安裝路徑
Directory appDocDir = await getApplicationDocumentsDirectory();
String appDocPath = appDocDir.path;
if (Platform.isIOS){
String url = 'itms-apps://itunes.apple.com/cn/app/id414478124?mt=8'; //到時候換成自己的應用的地址
// 通過url_launcher插件來跳轉AppStore
// if (await canLaunch(url)){
// await launch(url);
// }else {
// throw 'Could not launch $url';
// }
}else if (Platform.isAndroid){
String url = app_url;
// String url = "http://www.ionic.wang/jdshop.apk";
print(url);
try {
OtaUpdate().execute(url).listen(
(OtaEvent event) {
print('status:${event.status},value:${event.value}');
switch(event.status){
case OtaStatus.DOWNLOADING: // 下載中
setState(() {
progress = '下載進度:${event.value}%';
});
break;
case OtaStatus.INSTALLING: //安裝中
print('-----安裝中----');
// 打開安裝文件
//這裏的這個Apk文件名可以寫,也可以不寫
//不寫的話會出現讓你選擇用瀏覽器打開,點擊取消就好了,寫了後會直接打開當前目錄下的Apk文件,名字隨便定就可以
OpenFile.open("${appDocPath}/new.apk");
break;
case OtaStatus.PERMISSION_NOT_GRANTED_ERROR: // 權限錯誤
print('更新失敗,請稍後再試');
break;
default: // 其他問題
break;
}
},
);
} catch (e) {
print('更新失敗,請稍後再試');
}
}
}
好了,全部的代碼都在這裏了,如果有什麼問題,請給我留言!