前言
前段时间因为项目需要写了个自动升级的功能,也就是版本升级1.0(写在了我的csdn博文中),主要使用的是ionic官方提供的插件cordova-plugin-app-update。
相比网络上的教程而已它相对简单(简单的不要太多(ノ゚▽゚)ノ),不过相对的缺点也很明显,首先就是样式很丑,不能修改(emmmm反正我是不会修改,有大佬会的话务必教教我哇)其次就是ios不能使用。所以能只好重新写了个升级版本也就是——版本升级2.0版本。
这个版本主要借鉴了小军617的ionic2实战-添加app升级功能,删减了一些项目不需要的东西,相对而言更加简单了些。
插件安装
1.File
2.Transfer
3.File Opener
4.App Version
代码块##
首先要判断是ios还是android,根据不同的系统执行不同的升级方案:
在home.ts(首页)中调用检查方法
import { Platform } from 'ionic-angular';
@Component({
selector: 'page-home',
templateUrl: 'home.html',
})
export class HomePage {
constructor(private platform: Platform){
if (this.platform.is('android')) {
this.UpdateappService.versionNumber('0');
}else if (this.platform.is('ios')) {
this.UpdateappService.versionNumber('1')
}
}
}
接着在updateapp-service.ts中调用升级方法
a.导入用到的插件
import { AlertController } from 'ionic-angular';
import { Storage } from '@ionic/storage';
import { FileTransfer, FileTransferObject } from '@ionic-native/file-transfer';
import { File } from '@ionic-native/file';
import { FileOpener } from '@ionic-native/file-opener';
import { AppVersion } from '@ionic-native/app-version';
b.比较版本号判断是否升级
versionNumber(isandroid) {
this.appVersion.getVersionNumber().then(versionNumber => {
this.storage.set('versionNumber', versionNumber);
this.versionNumber = versionNumber;//获取本地版本号
this.webVersionNumber = urlversionNumber//这里通过接口拿到服务器端的版本号
if(this.versionNumbe !== this.webVersionNumber){//本地版本号与远程服务器最新版本进行对比,如果版本号不一样则需要升级
if (response.data.forceUpd === '1') {//forceUpd=1则表示强制升级
this.alertCtrl.create({
title: '重要升级',
subTitle: '您必须升级后才能使用!',
enableBackdropDismiss: false,
buttons: [{
text: '确定', handler: () => {
this.update(isandroid, response.data.forceUpd);
}
}
]
}).present();
} else {
this.alertCtrl.create({
title: '升级',
subTitle: '发现新版本,是否立即升级?',
enableBackdropDismiss: false,
buttons: [{ text: '暂不更新' }, {
text: '立即更新', handler: () => {
this.update(isandroid, response.data.forceUpd);
}
}]
}).present();
}
}
}).catch(err => {
console.warn('Get version code error: ', err);
});
c.调用升级方法
update(and, forceUpd) {
if (and === '0') {//android升级
let backgroundProcess = false; // 是否后台下载
let alert; // 显示下载进度
let apkUrl = 'apkurl';//apk下载地址
if (forceUpd === '1') {//1表示强制更新
alert = this.alertCtrl.create({
title: '下载进度:0%',
enableBackdropDismiss: false
});
}else{
alert = this.alertCtrl.create({
title: '下载进度:0%',
enableBackdropDismiss: false,
buttons: [{
text: '后台下载', handler: () => {
backgroundProcess = true;
}
}]
});
alert.present();
}
const fileTransfer: FileTransferObject = this.transfer.create();
const apk = this.file.externalDataDirectory + 'download/' + 'yourapkname.apk'; // 下载apk保存的目录
fileTransfer.download(apkUrl, apk).then(() => {
alert && alert.dismiss();
this.fileOpener.open(apk, 'application/vnd.android.package-archive').then(() => console.log('File is opened'))
.catch(e => alert(e));
}, err => {
this.updateProgress = -1;
this.alertCtrl.create({
title: '提示',
subTitle: '本地升级失败',
buttons: [{
text: '确定'
}]
}).present();
});
let timer = null; // 由于onProgress事件调用非常频繁,所以使用setTimeout用于函数节流
fileTransfer.onProgress((event: ProgressEvent) => {
const progress = Math.floor(event.loaded / event.total * 100); // 下载进度
this.updateProgress = progress;
if (!timer) {
// 更新下载进度
timer = setTimeout(() => {
if (progress === 100) {
alert && alert.dismiss();
} else {
if (!backgroundProcess) {
const title = document.getElementsByClassName('alert-title')[0];
title && (title.innerHTML = '下载进度' + progress + '%');
}
}
clearTimeout(timer);
timer = null;
}, 500);
}
});
}
else if (and === '1'){
//ipa文件是不能直接打开安装的,一般的ios app升级都是跳到App Store中
//跳转的接口在itunes里面找到对应的app,在额外信息中获取
window.open('yourapp-url')
}
}
最后在android8.0+中可能会遇到apk更新包下载之后没办法自动安装的情况,查看官网给出的解决办法如下:
On Android 8+, your application must have the ACTION_INSTALL_PACKAGE permission. You can add it by adding this to your app's config.xml file:
不过加上似乎没有用哇(<( ̄ ﹌  ̄)> 难道是我打开的方式不对???),经过一番百度之后找到了解决办法那就是在platforms\android\AndroidManifest.xml中修改
如果有帮助的话记得点个赞哟