通知欄顯示下載進(jìn)度—版本更新

項(xiàng)目需求:版本更新在系統(tǒng)通知欄顯示下載進(jìn)度速和,且不能阻塞頁面的正常操作歹垫。

1. 參考

(1) 使用native.js在安卓通知欄顯示下載進(jìn)度條原生通知欄下載進(jìn)度條通知概覽颠放、Android開發(fā)中Notification通知欄的基本用法排惨、8.0通知欄新增通知渠道

//通知欄中實(shí)時(shí)顯示進(jìn)度條會(huì)引起操作界面卡頓
        testNotification:function(){
            
            //Uni.Push:標(biāo)準(zhǔn)基座下可直接運(yùn)行;自定義基座或正式包碰凶,需在manifest.json添加Uni.Push模塊并配置
            // plus.push.createMessage( "下載中...", "jack",{cover:true,sound:"none",title:"標(biāo)題",subtitle:"副標(biāo)題"});
            
            var appname='杰克物聯(lián)';
            var NotificationUtil = NotifiUtil();//實(shí)例創(chuàng)建
            NotificationUtil.setNotification(appname, "開始下載! ");
            //dtask就是plus.createDownload
            var url = "https://www.uchat.com.cn/app/iot/JackIot.apk";
            var dtask = plus.downloader.createDownload(url);// POST請(qǐng)求提交數(shù)據(jù)
            dtask.start();
            dtask.addEventListener( "statechanged", async function(task,status){
                switch(task.state) {
                    case undefined: //下載任務(wù)未開始
                    case 0: //下載任務(wù)開始調(diào)度
                    case 1: //下載任務(wù)開始請(qǐng)求
                    case 2: break; //下載任務(wù)請(qǐng)求已經(jīng)接收
                    case 3: // 已接收到數(shù)據(jù)
                        NotificationUtil.setProgress(Math.round(task.downloadedSize/task.totalSize*100),appname);
                        break;
                    case 4: // 下載完成
                        console.log("Download success: " + task.filename);
                        NotificationUtil.compProgressNotification(appname,"下載完成! ");
                        // var ins = plus.runtime.install(plus.io.convertLocalFileSystemURL(task.filename), {force: force},()=>{
                        //  uni.showToast({icon:'none',title:'安裝成功暮芭!'});
                        //  NotificationUtil.clearNotification();
                        // },(e)=>{
                        //  uni.showToast({icon:'none',title:'安裝失斅雇铡!'});
                        //  NotificationUtil.clearNotification();
                        // })
                        plus.runtime.install(task.filename);  // 安裝下載的apk文件  
                        break;
                    default: //5: (Number 類型 )下載任務(wù)已暫停 -1: (Number 類型 )枚舉任務(wù)狀態(tài)
                        console.log("Download failed: " + status);
                        NotificationUtil.compProgressNotification(appname,"下載失敗! ");
                        break;
                }
            });
        },

(2) 本地消息推送的實(shí)現(xiàn)1: 使用NJS控制Android通知欄辕宏,不用個(gè)推實(shí)現(xiàn)本地消息推送(Local Notification)

var NotifyID = 1;  
            var Context = plus.android.importClass("android.content.Context");  
            var main = plus.android.runtimeMainActivity();  
            var Noti = plus.android.importClass("android.app.Notification");  
            var NotificationManager = plus.android.importClass("android.app.NotificationManager");  
            var nm = main.getSystemService(Context.NOTIFICATION_SERVICE)  
            var Notification = plus.android.importClass("android.app.Notification");  
            var mNotification = new Notification.Builder(main);  
            mNotification.setOngoing(true);  
            mNotification.setContentTitle("Hbuilder")  
            mNotification.setContentText("MUI & 5+ 大好畜晰!")  
            mNotification.setSmallIcon(17301620)  
            mNotification.setTicker("PadInfo")  
            
            mNotification.setNumber(10)  
            var mNb = mNotification.build()  
            nm.notify(NotifyID , mNb);

(3) 本地消息推送的實(shí)現(xiàn)2: 創(chuàng)建本地消息
備注:正式包需配置UniPush模塊,參考UniPush使用指南

plus.push.createMessage( "下載中...", "jack",{cover:true,sound:"none",title:"標(biāo)題",subtitle:"副標(biāo)題"});//僅在通知欄顯示開始和結(jié)束提醒:不會(huì)引起操作界面卡頓

(4) Downloader模塊管理網(wǎng)絡(luò)文件下載任務(wù)plus.downloader.createDownload和uni.downloadFile 執(zhí)行一個(gè)任務(wù)的時(shí)候 app鎖屏后重啟卡死瑞筐,導(dǎo)致app提示關(guān)閉應(yīng)用或等待凄鼻、H5+MUI,plus.downloader下載函數(shù) 會(huì)照成頁面卡頓偶爾甚至卡死無響應(yīng)的問題(附件即可下載實(shí)例代碼)

2. 實(shí)現(xiàn)需求

(1) notification.js源碼

  //js文件格式是GBK,在調(diào)用時(shí)手機(jī)上漢字會(huì)出現(xiàn)亂碼聚假,請(qǐng)大家在使用時(shí)復(fù)制粘貼一份块蚌,另存為UTF-8的文件格式,注意其中漢字顯示是否正常膘格,注釋信息無所謂
    //util.js原來是GRK格式(通知欄中會(huì)顯示亂碼)匈子,需重新復(fù)制一份,uniapp中js文件默認(rèn)是UFT-8格式:將復(fù)制后的js文件中的中文亂碼修改即可使用
    //在通知欄顯示下載進(jìn)度條
export default function NotificationUtil(){
        var defaultTitle = '通知欄標(biāo)題';
        var defaultContent = '通知內(nèi)容';
        var defaultTicker = '通知提示';
        var defaultNotifyId = 1000;
        var defaultNumber = 1;
        /**
         * @description 比較兩個(gè)版本大小
         * 比較版本大小闯袒,如果新版本nowVersion大于舊版本OldResourceVersion則返回true虎敦,否則返回false
         */
        function compareVersion(OldVersion, nowVersion) {
            if (!OldVersion || !nowVersion || OldVersion == '' || nowVersion == '') {
                return false;
            }
            //第二份參數(shù) 是 數(shù)組的最大長(zhǎng)度
            var OldVersionA = OldVersion.split(".", 4);
            var nowVersionA = nowVersion.split(".", 4);
            for (var i = 0; i < OldVersionA.length && i < nowVersionA.length; i++) {
                var strOld = OldVersionA[i];
                var numOld = parseInt(strOld);
                var strNow = nowVersionA[i];
                var numNow = parseInt(strNow);
                //小版本到高版本
                if (numNow > numOld /*||strNow.length>strOld.length*/ ) {
                    return true;
                } else if (numNow < numOld) {
                    return false;
                }
            }
            //如果是版本  如 1.6 - 1.6.1
            if (nowVersionA.length > OldVersionA.length && 0 == nowVersion.indexOf(OldVersion)) {
                return true;
            }
        };
        /**
         * @constructor 創(chuàng)建通知欄進(jìn)度條構(gòu)造函數(shù)
         */
        function NotificationCustom() {
            if (plus.os.name != 'Android') {
                return;
            }
            //當(dāng)前版本號(hào)
            var SystemVersion = plus.os.version;
            var Context = plus.android.importClass("android.content.Context");
            var main = plus.android.runtimeMainActivity();
            var NotificationManager = plus.android.importClass("android.app.NotificationManager");
            var nm = main.getSystemService(Context.NOTIFICATION_SERVICE)
            // Notification build 要android api16以上才能使用(4.1.2以上)
            var Notification = null;
            if (compareVersion('4.1.1', SystemVersion) == true) {
                Notification = plus.android.importClass("android.app.Notification");
            } else {
                Notification = plus.android.importClass("android.support.v4.app.NotificationCompat");
            }
            if (Notification) {
                this.notifyManager = nm;
                this.mNotificationBuild = new Notification.Builder(main);
                /*
                mBuilder.setContentTitle("測(cè)試標(biāo)題")//設(shè)置通知欄標(biāo)題
                        .setContentText("測(cè)試內(nèi)容") //設(shè)置通知欄顯示內(nèi)容
                        .setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL)) //設(shè)置通知欄點(diǎn)擊意圖
                        //  .setNumber(number) //設(shè)置通知集合的數(shù)量
                        .setTicker("測(cè)試通知來啦") //通知首次出現(xiàn)在通知欄,帶上升動(dòng)畫效果的
                        .setWhen(System.currentTimeMillis())//通知產(chǎn)生的時(shí)間政敢,會(huì)在通知信息里顯示其徙,一般是系統(tǒng)獲取到的時(shí)間
                        .setPriority(Notification.PRIORITY_DEFAULT) //設(shè)置該通知優(yōu)先級(jí)
                        //  .setAutoCancel(true)//設(shè)置這個(gè)標(biāo)志當(dāng)用戶單擊面板就可以讓通知將自動(dòng)取消
                        .setOngoing(false)//ture,?設(shè)置他為一個(gè)正在進(jìn)行的通知喷户。他們通常是用來表示一個(gè)后臺(tái)任務(wù),用戶積極參與(如播放音樂)或以某種方式正在等待,因此占用設(shè)備(如一個(gè)文件下載,同步操作,主動(dòng)網(wǎng)絡(luò)連接)
                        .setDefaults(Notification.DEFAULT_VIBRATE)//向通知添加聲音唾那、閃燈和振動(dòng)效果的最簡(jiǎn)單、最一致的方式是使用當(dāng)前的用戶默認(rèn)設(shè)置褪尝,使用defaults屬性闹获,可以組合
                        //Notification.DEFAULT_ALL  Notification.DEFAULT_SOUND 添加聲音 // requires VIBRATE permission
                        .setSmallIcon(R.drawable.ic_launcher);//設(shè)置通知小ICON
                */
                //設(shè)為true代表常駐狀態(tài)欄
                this.mNotificationBuild.setOngoing(false);
                this.mNotificationBuild.setContentTitle(defaultTitle);
                this.mNotificationBuild.setContentText(defaultContent);
                this.mNotificationBuild.setTicker(defaultTicker);
                //默認(rèn)的push圖標(biāo)
                // this.mNotificationBuild.setSmallIcon(17301620);//設(shè)置小圖標(biāo)
                //https://www.cnblogs.com/penghuster/p/4909930.html
                var R = plus.android.importClass("android.R");
                this.mNotificationBuild.setSmallIcon(R.drawable.stat_sys_download);
                //設(shè)置默認(rèn)聲音
                // console.log('默認(rèn):'+plus.android.importClass("android.app.Notification").DEFAULT_SOUND);
                this.mNotificationBuild.setDefaults(plus.android.importClass("android.app.Notification").DEFAULT_SOUND);
                //this.mNotificationBuild.setNumber(defaultNumber)
            }
        };
        /**
         * @description 給android通知欄發(fā)送通知
         * @param {String} title 標(biāo)題
         * @param {String} content  內(nèi)容
         * @param {String} tickerTips  提示
         * @param {Number} notifyId id,默認(rèn)為1000
         */
        NotificationCustom.prototype.setNotification = function(title, content, tickerTips,notifyId) {
            if (this.mNotificationBuild == null ||
                this.notifyManager == null) {
                return;
            }
            notifyId = (typeof(notifyId)=='number')?notifyId:defaultNotifyId;
            title = title || defaultTitle;
            content = content || defaultContent;
            tickerTips = tickerTips || defaultTicker;
            this.mNotificationBuild.setContentTitle(title);
            this.mNotificationBuild.setContentText(content);
            this.mNotificationBuild.setTicker(tickerTips);
            //默認(rèn)有聲音
            this.mNotificationBuild.setDefaults(plus.android.importClass("android.app.Notification").DEFAULT_SOUND);
            this.notifyManager.notify(notifyId, this.mNotificationBuild.build());
        };
        /**
         * @description 設(shè)置進(jìn)度條
         * @param {Number} progress
         * @param {String} title 標(biāo)題
         * @param {String} content  內(nèi)容
         * @param {String} tickerTips  提示
         * @param {Number} notifyId id,默認(rèn)為1000
         */
        NotificationCustom.prototype.setProgress = function(progress, title, content, tickerTips,notifyId) {
            if (this.mNotificationBuild == null ||
                this.notifyManager == null) {
                return;
            }
            notifyId = (typeof(notifyId)=='number')?notifyId:defaultNotifyId;
            title = title || 'APP更新包';
            content = content || '正在下載...【'+progress+'%】';
            tickerTips = tickerTips || '進(jìn)度提示';
            this.mNotificationBuild.setContentTitle(title);
            this.mNotificationBuild.setContentText(content);
            this.mNotificationBuild.setTicker(tickerTips);
            /*
            如果為確定的進(jìn)度條:調(diào)用setProgress(max, progress, false)來設(shè)置通知,在更新進(jìn)度的時(shí)候在此發(fā)起通知更新progress河哑,并且在下載完成后要移除進(jìn)度條避诽,通過調(diào)用setProgress(0, 0, false)既可。
            如果為不確定(持續(xù)活動(dòng))的進(jìn)度條璃谨,這是在處理進(jìn)度無法準(zhǔn)確獲知時(shí)顯示活動(dòng)正在持續(xù)沙庐,所以調(diào)用setProgress(0, 0, true) ,操作結(jié)束時(shí)佳吞,調(diào)用setProgress(0, 0, false)并更新通知以移除指示條
            */
            //進(jìn)度條顯示時(shí),默認(rèn)無聲音
            this.mNotificationBuild.setDefaults(0);
            this.mNotificationBuild.setProgress(100, progress, false);
            this.notifyManager.notify(notifyId, this.mNotificationBuild.build());
        };
        /**
         * @description 完成進(jìn)度條
         * @param {String} title 標(biāo)題
         * @param {String} content  內(nèi)容
         * @param {String} tickerTips  提示
         * @param {Number} notifyId id,默認(rèn)為1000
         */
        NotificationCustom.prototype.compProgressNotification = function(title, content, tickerTips,notifyId) {
            if (this.mNotificationBuild == null ||
                this.notifyManager == null) {
                return;
            }
            notifyId = (typeof(notifyId)=='number')?notifyId:defaultNotifyId;
            title = title || 'APP更新包';
            content = content || '下載完畢!';
            tickerTips = tickerTips || '進(jìn)度提示';
            
            var R = plus.android.importClass("android.R");
            this.mNotificationBuild.setSmallIcon(R.drawable.stat_sys_download_done);
            
            this.mNotificationBuild.setContentTitle(title);
            this.mNotificationBuild.setContentText(content);
            this.mNotificationBuild.setTicker(tickerTips);
            this.mNotificationBuild.setProgress(0, 0, false);//移除進(jìn)度條
            //默認(rèn)有聲音
            this.mNotificationBuild.setDefaults(plus.android.importClass("android.app.Notification").DEFAULT_SOUND);
            this.notifyManager.notify(notifyId, this.mNotificationBuild.build());
        };
        /**
         * @description 清除通知欄信息
         * @param {Number} notifyId id,默認(rèn)為1000
         */
        NotificationCustom.prototype.clearNotification = function(notifyId) {
            notifyId = (typeof(notifyId)=='number')?notifyId:defaultNotifyId;
            if(this.notifyManager){
                this.notifyManager.cancel(notifyId);
            }       
        };
        /**
         * @description 清除所有通知欄信息
         */
        NotificationCustom.prototype.clearAllNotification = function() {
            if(this.notifyManager){
                this.notifyManager.cancelAll();
            }       
        };
        return new NotificationCustom();
    }

(2) 在test.vue中使用

import NotifiUtil from '@/common/notification/notification.js'

//版本升級(jí):實(shí)現(xiàn)通知欄顯示下載進(jìn)度
        downloadApkAndShowProcessForUpdate:function(url){
            
            //Uni.Push:標(biāo)準(zhǔn)基座下可直接運(yùn)行拱雏;自定義基座或正式包,需在manifest.json添加Uni.Push模塊并配置
            // plus.push.createMessage( "下載中...", "jack",{cover:true,sound:"none",title:"標(biāo)題",subtitle:"副標(biāo)題"});//僅在通知欄顯示開始和結(jié)束提醒:不會(huì)引起操作界面卡頓
            
            var appname='杰克物聯(lián)';
            var NotificationUtil=NotifiUtil();//實(shí)例創(chuàng)建
            NotificationUtil.setNotification(appname, "開始下載! ");
            //dtask就是plus.createDownload
            //var url = "https://www.uchat.com.cn/app/iot/JackIot.apk";
            var dtask = plus.downloader.createDownload(url);// POST請(qǐng)求提交數(shù)據(jù)
            dtask.start();
            var arr = [{
                pro:1,
                isFirst:true
            },{
                pro:10,
                isFirst:true
            },{
                pro:30,
                isFirst:true
            },{
                pro:50,
                isFirst:true
            },{
                pro:70,
                isFirst:true
            },{
                pro:90,
                isFirst:true
            }]
            dtask.addEventListener( "statechanged", async function(task,status){
                switch(task.state) {
                    case undefined: //下載任務(wù)未開始
                    case 0: //下載任務(wù)開始調(diào)度
                    case 1: //下載任務(wù)開始請(qǐng)求
                    case 2: break; //下載任務(wù)請(qǐng)求已經(jīng)接收
                    case 3: // 已接收到數(shù)據(jù)
                        // NotificationUtil.setProgress(Math.round(task.downloadedSize/task.totalSize*100),appname);//通知欄中實(shí)時(shí)更新進(jìn)度條會(huì)引起操作界面卡頓:一秒執(zhí)行40多次(監(jiān)聽函數(shù))底扳,導(dǎo)致UI操作阻塞
                        var pro = parseInt(task.downloadedSize/task.totalSize*100);
                            // if(pro == 1 || pro == 10 || pro == 30 || pro == 50 || pro == 70 || pro == 90){//優(yōu)化方案一:僅在指定整數(shù)進(jìn)度時(shí)更新
                            //  console.log("進(jìn)度:" + pro);
                            //  NotificationUtil.setProgress(pro,appname);
                            // }
                            switch (pro){//優(yōu)化方案二:僅進(jìn)度第一次出現(xiàn)(1铸抑,10,30衷模,50鹊汛,70菇爪,90)時(shí)刷新
                                case arr[0].pro:
                                    if(arr[0].isFirst){
                                        // console.log("進(jìn)度:" + pro);
                                        NotificationUtil.setProgress(pro,appname);
                                        arr[0].isFirst = false;
                                    }
                                    break;
                                case arr[1].pro:
                                    if(arr[1].isFirst){
                                        // console.log("進(jìn)度:" + pro);
                                        NotificationUtil.setProgress(pro,appname);
                                        arr[1].isFirst = false;
                                    }
                                    break;
                                case arr[2].pro:
                                    if(arr[2].isFirst){
                                        // console.log("進(jìn)度:" + pro);
                                        NotificationUtil.setProgress(pro,appname);
                                        arr[2].isFirst = false;
                                    }
                                    break;
                                case arr[3].pro:
                                    if(arr[3].isFirst){
                                        // console.log("進(jìn)度:" + pro);
                                        NotificationUtil.setProgress(pro,appname);
                                        arr[3].isFirst = false;
                                    }
                                    break;
                                case arr[4].pro:
                                    if(arr[4].isFirst){
                                        // console.log("進(jìn)度:" + pro);
                                        NotificationUtil.setProgress(pro,appname);
                                        arr[4].isFirst = false;
                                    }
                                    break;
                                case arr[5].pro:
                                    if(arr[5].isFirst){
                                        // console.log("進(jìn)度:" + pro);
                                        NotificationUtil.setProgress(pro,appname);
                                        arr[5].isFirst = false;
                                    }
                                    break;
                                default:
                                    break;
                            }
                            
                        
                        break;
                    case 4: // 下載完成
                        console.log("Download success: " + task.filename);
                        NotificationUtil.compProgressNotification(appname,"下載完成! ");
                        // var ins = plus.runtime.install(plus.io.convertLocalFileSystemURL(task.filename), {force: force},()=>{
                        //  uni.showToast({icon:'none',title:'安裝成功!'});
                        //  NotificationUtil.clearNotification();
                        // },(e)=>{
                        //  uni.showToast({icon:'none',title:'安裝失斊饣琛凳宙!'});
                        //  NotificationUtil.clearNotification();
                        // })
                        plus.runtime.install(task.filename);  // 安裝下載的apk文件  
                        break;
                    default: //5: (Number 類型 )下載任務(wù)已暫停 -1: (Number 類型 )枚舉任務(wù)狀態(tài)
                        console.log("Download failed: " + status);
                        NotificationUtil.compProgressNotification(appname,"下載失敗! ");
                        break;
                }
            });
        },

3. 封裝

(1) version.js

import NotifiUtil from './notification/notification.js'

const downloadAndHandleWgtFile = function(url){
    uni.downloadFile({
        url: url,  
        success: (downloadResult) => {  
            console.log("downLoadFile:" + JSON.stringify(downloadResult));
            if (downloadResult.statusCode === 200) {  
                plus.runtime.install(downloadResult.tempFilePath, {  
                    force: false  
                }, function() {  
                    console.log('install success...');  
                    plus.runtime.restart();  
                }, function(e) {  
                    console.error('install fail...');  
                });  
            }  
        }  
    });  
}

const downloadAndHandleApkFile = function(url){ 
    // plus.nativeUI.showWaiting("下載中..."); 
    uni.showToast({
        title: '下載中...',
        icon:'none'
    });
    plus.push.createMessage( "下載中...", "jack",{cover:true,sound:"none"});
    
    var dtask = plus.downloader.createDownload( url, {}, function ( d, status ) {  
        if ( status == 200 ) { // 下載成功 
            plus.push.createMessage( "下載完成", "jack",{cover:true});
            var path = d.filename;  
            console.log("path:" + d.filename);  
            plus.runtime.install(path);  // 安裝下載的apk文件  
        } else {//下載失敗  
            alert( "Download failed: " + status );   
        }   
        // plus.nativeUI.closeWaiting(); 
        // plus.push.clear();//清空系統(tǒng)消息中心所有的推送消息
    });  
    dtask.start();
}

//版本升級(jí):實(shí)現(xiàn)通知欄顯示下載進(jìn)度
const downloadApkAndShowProgressForUpdate = function(url){
    // if(!hasNetwork()){
    //  return;
    // }
    
    // plus.push.createMessage( "下載中...", "jack",{cover:true,sound:"none",title:"標(biāo)題",subtitle:"副標(biāo)題"});//僅在通知欄顯示開始和結(jié)束提醒:不會(huì)引起操作界面卡頓
    
    var appname='杰克物聯(lián)';
    var NotificationUtil = NotifiUtil();//實(shí)例創(chuàng)建
    NotificationUtil.setNotification(appname, "開始下載! ");
    //dtask就是plus.createDownload
    // var url = "https://www.uchat.com.cn/app/iot/JackIot.apk";
    var dtask = plus.downloader.createDownload(url);// POST請(qǐng)求提交數(shù)據(jù)
    dtask.start();
    var arr = [{
        pro:1,
        isFirst:true
    },{
        pro:10,
        isFirst:true
    },{
        pro:30,
        isFirst:true
    },{
        pro:50,
        isFirst:true
    },{
        pro:70,
        isFirst:true
    },{
        pro:90,
        isFirst:true
    }]
    dtask.addEventListener( "statechanged", async function(task,status){
        switch(task.state) {
            case undefined: //下載任務(wù)未開始
            case 0: //下載任務(wù)開始調(diào)度
            case 1: //下載任務(wù)開始請(qǐng)求
            case 2: break; //下載任務(wù)請(qǐng)求已經(jīng)接收
            case 3: // 已接收到數(shù)據(jù)
                // NotificationUtil.setProgress(Math.round(task.downloadedSize/task.totalSize*100),appname);//通知欄中實(shí)時(shí)更新進(jìn)度條會(huì)引起操作界面卡頓:一秒執(zhí)行40多次(監(jiān)聽函數(shù)),導(dǎo)致UI操作阻塞
                var pro = parseInt(task.downloadedSize/task.totalSize*100);
                    // if(pro == 1 || pro == 10 || pro == 30 || pro == 50 || pro == 70 || pro == 90){//優(yōu)化方案一:僅在指定整數(shù)進(jìn)度時(shí)更新
                    //  console.log("進(jìn)度:" + pro);
                    //  NotificationUtil.setProgress(pro,appname);
                    // }
                    switch (pro){//優(yōu)化方案二:僅進(jìn)度第一次出現(xiàn)(1职祷,10氏涩,30,50有梆,70是尖,90)時(shí)刷新
                        case arr[0].pro:
                            if(arr[0].isFirst){
                                // console.log("進(jìn)度:" + pro);
                                NotificationUtil.setProgress(pro,appname);
                                arr[0].isFirst = false;
                            }
                            break;
                        case arr[1].pro:
                            if(arr[1].isFirst){
                                // console.log("進(jìn)度:" + pro);
                                NotificationUtil.setProgress(pro,appname);
                                arr[1].isFirst = false;
                            }
                            break;
                        case arr[2].pro:
                            if(arr[2].isFirst){
                                // console.log("進(jìn)度:" + pro);
                                NotificationUtil.setProgress(pro,appname);
                                arr[2].isFirst = false;
                            }
                            break;
                        case arr[3].pro:
                            if(arr[3].isFirst){
                                // console.log("進(jìn)度:" + pro);
                                NotificationUtil.setProgress(pro,appname);
                                arr[3].isFirst = false;
                            }
                            break;
                        case arr[4].pro:
                            if(arr[4].isFirst){
                                // console.log("進(jìn)度:" + pro);
                                NotificationUtil.setProgress(pro,appname);
                                arr[4].isFirst = false;
                            }
                            break;
                        case arr[5].pro:
                            if(arr[5].isFirst){
                                // console.log("進(jìn)度:" + pro);
                                NotificationUtil.setProgress(pro,appname);
                                arr[5].isFirst = false;
                            }
                            break;
                        default:
                            break;
                    }
                break;
            case 4: // 下載完成
                console.log("Download success: " + task.filename);
                NotificationUtil.compProgressNotification(appname,"下載完成! ");
                // var ins = plus.runtime.install(plus.io.convertLocalFileSystemURL(task.filename), {force: force},()=>{
                //  uni.showToast({icon:'none',title:'安裝成功!'});
                //  NotificationUtil.clearNotification();
                // },(e)=>{
                //  uni.showToast({icon:'none',title:'安裝失斈嘁饺汹!'});
                //  NotificationUtil.clearNotification();
                // })
                plus.runtime.install(task.filename);  // 安裝下載的apk文件  
                break;
            default: //5: (Number 類型 )下載任務(wù)已暫停 -1: (Number 類型 )枚舉任務(wù)狀態(tài)
                console.log("Download failed: " + status);
                NotificationUtil.compProgressNotification(appname,"下載失敗! ");
                break;
        }
    });
}


export default {
    downloadAndHandleWgtFile,
    downloadAndHandleApkFile,
    downloadApkAndShowProgressForUpdate
}

(2) main.js

import Vue from 'vue'
import App from './App'

import Version from './common/version.js'

Vue.config.productionTip = false

Vue.prototype.Version = Version 

App.mpType = 'app'

const app = new Vue({
    Version,
    ...App
})
app.$mount()

(3) 在test.vue或App.vue中調(diào)用

this.Version.downloadApkAndShowProgressForUpdate(apkUrl);

4. 解決android8.0及以上通知不顯示的問題

(1) 參考

(2) 修改notification.js(創(chuàng)建通知欄進(jìn)度條構(gòu)造函數(shù))

this.notifyManager = nm;
this.mNotificationBuild = new Notification.Builder(main);

改為:

var Build = plus.android.importClass("android.os.Build");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//android8.0及以上需設(shè)置通知渠道才能顯示通知
    //創(chuàng)建通知渠道
    var name = "渠道名稱1";
    var description = "渠道描述1";
    var channelId="channelId1";//渠道id     
    // var importance = NotificationManager.IMPORTANCE_DEFAULT;//重要性級(jí)別
    var importance = NotificationManager.IMPORTANCE_HIGH;//重要性級(jí)別
    var NotificationChannel = plus.android.importClass("android.app.NotificationChannel");
    var mChannel = new NotificationChannel(channelId, name, importance);
    // var mChannel = new NotificationChannel("channelId1", "渠道名稱1", importance);
    mChannel.setDescription(description);//渠道描述
    mChannel.setDescription("渠道描述1");//渠道描述
    mChannel.enableLights(true);//是否顯示通知指示燈
    mChannel.enableVibration(true);//是否振動(dòng)
    nm.createNotificationChannel(mChannel);//創(chuàng)建通知渠道
                        
    this.notifyManager = nm;
    this.mNotificationBuild = new Notification.Builder(main,channelId);
    // this.mNotificationBuild = new Notification.Builder(main,"channelId1");
}else{
    this.notifyManager = nm;
    this.mNotificationBuild = new Notification.Builder(main);
}

即:

/**
* @constructor 創(chuàng)建通知欄進(jìn)度條構(gòu)造函數(shù)
*/
function NotificationCustom() {
    if (plus.os.name != 'Android') {
        return;
    }
    //當(dāng)前版本號(hào)
    var SystemVersion = plus.os.version;
    var Context = plus.android.importClass("android.content.Context");
    var main = plus.android.runtimeMainActivity();
    var NotificationManager = plus.android.importClass("android.app.NotificationManager");
    var nm = main.getSystemService(Context.NOTIFICATION_SERVICE)
    // Notification build 要android api16以上才能使用(4.1.2以上)
    var Notification = null;
    if (compareVersion('4.1.1', SystemVersion) == true) {
        Notification = plus.android.importClass("android.app.Notification");
    } else {
        Notification = plus.android.importClass("android.support.v4.app.NotificationCompat");
    }
    if (Notification) {
        // this.notifyManager = nm;
        // this.mNotificationBuild = new Notification.Builder(main);
                
        var Build = plus.android.importClass("android.os.Build");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//android8.0及以上需設(shè)置通知渠道才能顯示通知
            //創(chuàng)建通知渠道
            var name = "渠道名稱1";
            var description = "渠道描述1";
            var channelId="channelId1";//渠道id     
            // var importance = NotificationManager.IMPORTANCE_DEFAULT;//重要性級(jí)別
            var importance = NotificationManager.IMPORTANCE_HIGH;//重要性級(jí)別
            var NotificationChannel = plus.android.importClass("android.app.NotificationChannel");
            var mChannel = new NotificationChannel(channelId, name, importance);
            // var mChannel = new NotificationChannel("channelId1", "渠道名稱1", importance);
            mChannel.setDescription(description);//渠道描述
            mChannel.setDescription("渠道描述1");//渠道描述
            mChannel.enableLights(true);//是否顯示通知指示燈
            mChannel.enableVibration(true);//是否振動(dòng)
            nm.createNotificationChannel(mChannel);//創(chuàng)建通知渠道
                        
            this.notifyManager = nm;
            this.mNotificationBuild = new Notification.Builder(main,channelId);
            // this.mNotificationBuild = new Notification.Builder(main,"channelId1");
        }else{
            this.notifyManager = nm;
            this.mNotificationBuild = new Notification.Builder(main);
        }
                
        /*
        mBuilder.setContentTitle("測(cè)試標(biāo)題")//設(shè)置通知欄標(biāo)題
            .setContentText("測(cè)試內(nèi)容") //設(shè)置通知欄顯示內(nèi)容
            .setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL)) //設(shè)置通知欄點(diǎn)擊意圖
            //  .setNumber(number) //設(shè)置通知集合的數(shù)量
            .setTicker("測(cè)試通知來啦") //通知首次出現(xiàn)在通知欄,帶上升動(dòng)畫效果的
            .setWhen(System.currentTimeMillis())//通知產(chǎn)生的時(shí)間痰催,會(huì)在通知信息里顯示兜辞,一般是系統(tǒng)獲取到的時(shí)間
            .setPriority(Notification.PRIORITY_DEFAULT) //設(shè)置該通知優(yōu)先級(jí)
            //  .setAutoCancel(true)//設(shè)置這個(gè)標(biāo)志當(dāng)用戶單擊面板就可以讓通知將自動(dòng)取消
            .setOngoing(false)//ture,?設(shè)置他為一個(gè)正在進(jìn)行的通知夸溶。他們通常是用來表示一個(gè)后臺(tái)任務(wù),用戶積極參與(如播放音樂)或以某種方式正在等待,因此占用設(shè)備(如一個(gè)文件下載,同步操作,主動(dòng)網(wǎng)絡(luò)連接)
            .setDefaults(Notification.DEFAULT_VIBRATE)//向通知添加聲音逸吵、閃燈和振動(dòng)效果的最簡(jiǎn)單、最一致的方式是使用當(dāng)前的用戶默認(rèn)設(shè)置缝裁,使用defaults屬性扫皱,可以組合
            //Notification.DEFAULT_ALL  Notification.DEFAULT_SOUND 添加聲音 // requires VIBRATE permission
            .setSmallIcon(R.drawable.ic_launcher);//設(shè)置通知小ICON
        */

        //設(shè)為true代表常駐狀態(tài)欄
        this.mNotificationBuild.setOngoing(false);
        this.mNotificationBuild.setContentTitle(defaultTitle);
        this.mNotificationBuild.setContentText(defaultContent);
        this.mNotificationBuild.setTicker(defaultTicker);
        //默認(rèn)的push圖標(biāo)
        // this.mNotificationBuild.setSmallIcon(17301620);//設(shè)置小圖標(biāo)
        //https://www.cnblogs.com/penghuster/p/4909930.html
        var R = plus.android.importClass("android.R");  
        this.mNotificationBuild.setSmallIcon(R.drawable.stat_sys_download);
        //設(shè)置默認(rèn)聲音
        // console.log('默認(rèn):'+plus.android.importClass("android.app.Notification").DEFAULT_SOUND);
        this.mNotificationBuild.setDefaults(plus.android.importClass("android.app.Notification").DEFAULT_SOUND);
        //this.mNotificationBuild.setNumber(defaultNumber)
    }
};

(3) 真機(jī)運(yùn)行


小米11+Android11.png

說明:目前已發(fā)布為uniapp插件,有需要請(qǐng)移步Android系統(tǒng)通知通知欄顯示進(jìn)度條捷绑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末韩脑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子粹污,更是在濱河造成了極大的恐慌段多,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厕怜,死亡現(xiàn)場(chǎng)離奇詭異衩匣,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)粥航,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來生百,“玉大人递雀,你說我怎么就攤上這事∈唇” “怎么了缀程?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵搜吧,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我杨凑,道長(zhǎng)滤奈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任撩满,我火速辦了婚禮蜒程,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘伺帘。我一直安慰自己昭躺,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布伪嫁。 她就那樣靜靜地躺著领炫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪张咳。 梳的紋絲不亂的頭發(fā)上帝洪,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音脚猾,去河邊找鬼碟狞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缰儿。 我是一名探鬼主播茉兰,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼脆淹!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起沽一,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤盖溺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后铣缠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烘嘱,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年蝗蛙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蝇庭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡捡硅,死狀恐怖哮内,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情壮韭,我是刑警寧澤北发,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布纹因,位于F島的核電站,受9級(jí)特大地震影響琳拨,放射性物質(zhì)發(fā)生泄漏瞭恰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一狱庇、第九天 我趴在偏房一處隱蔽的房頂上張望惊畏。 院中可真熱鬧,春花似錦僵井、人聲如沸陕截。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽农曲。三九已至,卻和暖如春驻债,著一層夾襖步出監(jiān)牢的瞬間乳规,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工合呐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留暮的,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓淌实,卻偏偏與公主長(zhǎng)得像冻辩,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拆祈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容