ionic3 实现app版本更新下载并打开进行安装(包括android7+无法自动安装apk问题的解决方法)

版权声明:本文为博主原创文章,未经博主允许不得转载。转载注明出处。 https://blog.csdn.net/zuoyiran520081/article/details/79317451

记录一下实现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 (<any>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" />

再进行打包即可。

猜你喜欢

转载自blog.csdn.net/zuoyiran520081/article/details/79317451
今日推荐