记录一下实现app版本一键更新下载的功能。
我的项目的总体的文件:
使用的插件列表如下:
需要纯实现该功能用到的基本上是除了后三个。
首先,安装这些插件,在app.component.ts页面上加入
import { Component, ViewChild } from '@angular/core';
import { Platform, ToastController, Nav, IonicApp } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { AppVersion } from '@ionic-native/app-version';
import { SharedDataService } from "./../providers/SharedDataService";
import { File } from '@ionic-native/file';
import { Device } from '@ionic-native/device';
import { HomeService } from "./../pages/home/HomeService";
declare var cordova: any;
@Component({
templateUrl: 'app.html',
providers: [ Device,AppVersion,HomeService,File ]
})
export class MyApp {
rootPage:any = "AdvertPage";
backButtonPressed: boolean = false; //用于判断返回键是否触发
@ViewChild('myNav') nav: Nav;
constructor(
private device: Device,
public ionicApp: IonicApp,
private appVersion: AppVersion,
private file: File,
public platform: Platform,
public statusBar: StatusBar,
public toastCtrl: ToastController,
splashScreen: SplashScreen,
private homeService: HomeService,
private Share: SharedDataService) {
/*SharedDataService是一个存放公共变量的地方
*
*/
platform.ready().then(() => {
/*储存版本信息及判断存储路径开始*/
// 读取所用的平台
//获取当前平台信息 this.device.platform
this.appVersion.getVersionNumber().then(data => {
//当前app版本号 data,存储该版本号
this.Share.appVersion = data;
}, error => console.error(error => {
//获取当前版本号失败进行的操作
}));
this.appVersion.getPackageName().then(data => {
//当前应用的packageName:data,存储该包名
this.Share.packageName = data;
}, error => console.error(error => {
//获取该APP id 失败
}));
this.Share.platform = this.device.platform;
this.Share.savePath = this.Share.platform == 'iOS' ? this.file.documentsDirectory : this.file.externalDataDirectory;
//存储的沙盒地址:this.Share.savePath
/*储存版本信息及判断存储路径结束*/
});
}
//提示弹窗
alertToast(msg){
let toast = this.toastCtrl.create({
message: msg,
cssClass:'detailToast',
duration: 2000
});
toast.present();
}
}
发送获取app信息接口的请求写在:
public getUpdateInfo(uuid, showLoading) {
if (showLoading) {
this.loading.presentLoadingDefault();
}
var url = "此地址获取app信息的接口地址" + uuid;//此处是我们项目接口所需把本地app的信息包名传到接口
return this.http.get(url).toPromise()
.then(res => {
if (this.loading) {
this.loading.dismissLoadingDefault();
}
return res.json();
})
.catch(err => {
this.handleError(err);
});
}
在相应的service(MeService.ts)里面写这样的方法:
getUpdate(showLoading: boolean) {
return this.httpService.getUpdateInfo(this.Share.packageName, showLoading);
}
在需要的页面me.ts文件中代码如下,然后在页面中直接调用update()方法即可:
import { Component, ViewChild } from '@angular/core';
import { NavController,IonicPage,ActionSheetController,AlertController } from 'ionic-angular';
import { SharedDataService } from "./../../providers/SharedDataService";
import { App,ViewController } from 'ionic-angular';
import { MeService } from "./MeService";
import { FileTransfer, FileTransferObject } from '@ionic-native/file-transfer';
import { FileOpener } from '@ionic-native/file-opener';
import { LoadingService } from "./../../providers/LoadingService";
@IonicPage()
@Component({
selector: 'page-me',
templateUrl: 'me.html',
providers: [FileOpener, FileTransfer, AlertController, MeService]
})
export class MePage {
constructor(public navCtrl: NavController,
public Share: SharedDataService,
private app:App,
private fileOpener: FileOpener,
private transfer: FileTransfer,
// private file: File,
private alertCtrl: AlertController,
private loadingService: LoadingService,
public actionSheetCtrl: ActionSheetController,
private meService: MeService,
public viewCtrl: ViewController) {
}
//退出到登录页
exitTo(){
this.app.getRootNav().setRoot("LoginPage");
delete (window).launchURL;
}
update() {
this.meService.getUpdate(true).then(data => {
console.log(data);
// 判断当前版本号否大于服务器的版本号
var serveVersion = data && data.appList && data.appList.group && data.appList.group.app && data.appList.group.app.version;
console.log(serveVersion);
console.log(this.Share.appVersion);
if (this.versionfunegt(serveVersion, this.Share.appVersion)) {
console.log("检查到新版本,是否更新APP");
let alert1 = this.alertCtrl.create({
title: '版本更新',
message: '检查到最新版本,是否进行更新',
buttons: [
{
text: '否',
role: 'cancel',
handler: () => {
console.log('不进行更新');
}
},
{
text: '是',
handler: () => {
console.log('更新APP');
var url = data && data.appList && data.appList.group && data.appList.group.app && data.appList.group.app.url;
console.log(url);
if (this.Share.platform == 'iOS') {
console.log('打开iOS下载地址----------------------------');
window.location.href = 'itms-services://?action=download-manifest&url=' + url;
} else {
console.log('开始下载Android代码----------------------------');
const fileTransfer: FileTransferObject = this.transfer.create();
fileTransfer.onProgress(progressEvent => {
var present = new Number((progressEvent.loaded / progressEvent.total) * 100);
console.log('当前进度为:' + present.toFixed(0));
var presentInt = present.toFixed(0);
this.loadingService.presentProgress(presentInt);
});
var savePath = this.Share.savePath + 'android.apk';
fileTransfer.download(encodeURI(url), savePath).then((entry) => {
console.log('保存apk包的地址为: ' + this.Share.savePath + 'Ceshiname.apk');
console.log('download complete: ' + entry.toURL());
console.log("下载成功");
this.fileOpener.open(entry.toURL(), "application/vnd.android.package-archive")
.then(() => console.log('打开apk包成功!'))
.catch(e => console.log('打开apk包失败!', e));
}, (error) => {
console.log("下载失败");
this.loadingService.presentTip('操作提醒', '由于部分手机出现异常,请您进入手机设置-应用管理-Ceshiname-权限,将存储权限打开后再进行升级,由此给您带来的不便,敬请谅解。');
for(var item in error) {
console.log(item + ":" + error[item]);
}
});
}
}
}
]
});
alert1.present();
} else {
this.loadingService.presentMsg("已是最新版本!");
}
});
}
// 比较版本号
versionfunegt (a, b) {
var _a = this.toNum(a), _b = this.toNum(b);
if(_a == _b) {
console.log("版本号相同!版本号为:"+a);
return false;
} else if(_a > _b) {
console.log("版本号"+a+"是新版本!");
return true;
} else {
console.log("版本号"+b+"是新版本!");
return false;
}
}
toNum (a) {
var a = a.toString();
//也可以这样写 var c=a.split(/\./);
var c = a.split('.');
var num_place = ["","0","00","000","0000"], r = num_place.reverse();
for (var i = 0; i< c.length; i++){
var len = c[i].length;
c[i] = r[len] + c[i];
}
var res = c.join('');
return res;
}
//字体
changeFont() {
let actionSheet = this.actionSheetCtrl.create({
title: '设置字体大小',
buttons: [
{
text: '小',
role: 'destructive',
handler: () => {
this.Share.fontSize = 'small';
}
},
{
text: '中',
handler: () => {
this.Share.fontSize = 'normal';
}
},{
text: '大',
handler: () => {
this.Share.fontSize = 'large';
}
},
{
text: '取消',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
}
]
});
actionSheet.present();
}
}
公共变量的存放区域为SharedDataService.ts:
import { Injectable } from '@angular/core';
import { HttpService } from "./HttpService";
import { LoadingService } from "./LoadingService";
@Injectable()
export class SharedDataService {
platform: string; //平台
savePath: string; //存储路径
packageName: string; //包名
appVersion: string = '1.0.18'; //版本号
//。。。写其他需要全局调用的变量。。。
constructor() {}
}
注:代码中用的插件是cordova-plugin-file-transfer,打包完成后会发现在android7版本上没有问题,但是到android7以上的版本就有问题,可以下载到本地,但是没有办法在更新下载完成时,让自动安装,这个问题的解决办法如下:
首先,添加完平台:cordova platform add android时,打开platform文件夹找到AndroidManifest.xml文件,如下图:
修改为:
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />
再进行打包即可。