一、最开始的想法
本来最开始公司使用mui制作的app,没有系统状态栏显示下载进度的,后来突发奇想想要实现像qq等app下载更新或消息提示等在系统状态栏显示的效果,特意去研究了下。
在H5+plus api中没有发现存在有设置系统通知栏的支持,于是采取android开发的方式,实现功能。
大致功能描述:
大致就是这种操作啦,下面像大家展示插件开发的方式实现上述功能。
二、系统通知栏插件开发
1、更新操作,下载安装包等依旧使用H5+plus的方式实现
function createDownload(url) {
if(!url) {
mui.toast("获取下载路径错误");
return;
}
//事件参数单位为s
var downloadTask = plus.downloader.createDownload(url, {
//timeout: 10,
//retryInterval: 5,
//retry: 3
});
plus.notification.setNotification("新版下载", "开始下载"); //插件调用
downloadTask.start();
console.log("$$$$$$");
downloadTask.addEventListener("statechanged", function(task, status) {
//console.log("task--->"+task);
console.log("task.state--->" + task.state);
//var current = parseInt(100 * task.downloadedSize / task.totalSize);
//console.log("current-->" + current);
//console.log("status--->"+status);
switch(task.state) {
case 1: // 开始
console.log('开始');
break;
case 2: //已连接到服务器
console.log('已连接到服务器');
break;
case 3: // 已接收到数据
console.log('已接收到数据');
var current = parseInt(100 * task.downloadedSize / task.totalSize);
plus.notification.setProgress(current); //插件调用
break;
case 4: // 下载完成
console.log('下载完成 ');
plus.notification.compProgressNotification("下载完成"); //插件调用
plus.runtime.install(task.filename, {}, function() {
//成功安装回调,执行重启app操作
plus.runtime.restart();
}, function(DOMException) {
console.log(JSON.stringify(DOMException));
mui.toast("安装失败");
//alert("安装失败")
});
break;
}
});
}
2、java插件的制作
相关制作细节,有不懂的,大家可以参考之前的博客,有比官方更好懂的插件开发。传送门
采取新插件开发的方式,编写实现代码
import java.util.Timer;
import java.util.TimerTask;
import org.json.JSONArray;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.util.Log;
import cn.linkpower.dtulock.R;
import io.dcloud.common.DHInterface.IWebview;
import io.dcloud.common.DHInterface.StandardFeature;
/**
* app下载进度,状态栏显示---插件
*
* @author 76519
*
*/
public class DownloadProgress extends StandardFeature {
static final int ids = 1000;
Activity activity;
// 通知栏设备管理器
NotificationManager manager;
// 通知栏信息传递操作类
Notification.Builder builder;
//定义全局当前下载进度(需要在开启和结束后的插件调用中,实现初始化操作)
int preProgress = 0;
/**
* 初始设置
*
* @param pWebview
* @param array
*/
public void setNotification(IWebview pWebview, JSONArray array) {
Log.i("DownloadProgress-->", "setNotification");
check(pWebview);
String title = array.optString(0);
String ticker = array.optString(1);
//设置通知标题
builder.setContentTitle(title)
//设置通知栏内容
.setContentText(ticker)
//通知首次出现在通知栏,带上升动画效果的
.setTicker(ticker);
//同时初始化全局参数
preProgress = 0;
builder.setProgress(100, 0, false);
// 设置notify通知对象并发布通知,id为1000
manager.notify(ids, builder.build());
}
/**
* 进度显示
*
* @param pWebview
* @param array
* @throws Exception
*/
public void setProgress(IWebview pWebview, final JSONArray array) throws Exception {
Log.i("DownloadProgress-->", "setProgress");
check(pWebview);
//防止重复
if(preProgress < Integer.parseInt(array.optString(0)) ) {
new Thread(new Runnable() {
@Override
public void run() {
int incr = Integer.parseInt(array.optString(0));
Log.i("setProgress--->", String.valueOf(incr));
/**
* 几个参数含义:<br>
* 参数一:定义进度可以采用的最大值;<br>
* 参数二:定义默认进度值,介于0到最大值之间;<br>
* 参数三:如果设置为true,则将显示非循环动画,而不显示进度<br>
*/
builder.setProgress(100, incr, false);
// 下载进度文本显示
builder.setContentText("下载" + String.valueOf(incr) + "%");
//发送通知请求
manager.notify(ids, builder.build());
}
}).start();
preProgress = Integer.parseInt(array.optString(0));
}
}
/**
* 下载完成后
*
* @param pWebview
* @param array
*/
public void compProgressNotification(IWebview pWebview, JSONArray array) {
Log.i("DownloadProgress-->", "compProgressNotification");
check(pWebview);
String title = array.optString(0);
builder.setContentTitle(title)
//移除进度条
.setProgress(0, 0, false)
.setOngoing(false);
manager.notify(ids, builder.build());
//显示下载成功1500毫秒后 移除通知
new Timer().schedule(new TimerTask() {
@Override
public void run() {
//同时初始化全局参数
preProgress = 0;
//移除通知
manager.cancel(ids);
}
}, 1500);
}
public void check(IWebview pWebview) {
if (activity == null) {
activity = pWebview.getActivity();
manager = (NotificationManager) activity.getSystemService(Activity.NOTIFICATION_SERVICE);
builder = new Notification.Builder(activity);
// 设置通知时间
builder.setWhen(System.currentTimeMillis())
//设置优先级别
.setPriority(Notification.PRIORITY_DEFAULT)
// 设置通知标题
.setContentTitle("新版下载")
//通知首次出现在通知栏,带上升动画效果的
.setTicker("开始下载")
.setContentText("开始下载")
//ture,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
//.setOngoing(true)
// 设置默认的提示音、震动、灯光(开启震动后,下载会持续震动)
//.setDefaults(Notification.DEFAULT_ALL)
// 使用小图标
.setSmallIcon(R.drawable.icon)
// 设置要使用的振动模式
.setVibrate(null);
}
}
}
3、注册申明插件别名和native调用桥接
中追加一条新的注册信息
<!-- 20191009 增加下载进度提示插件 -->
<feature name="notification" value="cn.linkpower.plugin.download.DownloadProgress" ></feature>
4、编写桥接js
document.addEventListener("plusready", function() {
var B = window.plus.bridge;
var notification = {
setProgress: function(incr) {
return B.exec("notification", "setProgress", [incr]);
},
setNotification: function(contentTitle, ticker) {
return B.exec("notification", "setNotification", [contentTitle, ticker]);
},
compProgressNotification: function(contentTitle) {
return B.exec("notification", "compProgressNotification", [contentTitle]);
}
};
window.plus.notification = notification;
}, true);
5、需要使用的页面引入
<script src="../js/download/download.js" type="text/javascript" charset="utf-8"></script>
三、参考资料
1、H5+plus 中,针对下载操作回调有以下几种状态值返回
vaoid onCompleted(Download download, Number status) {
// Download file complete code
}
文档地址:https://www.html5plus.org/doc/zh_cn/downloader.html#plus.downloader.DownloadCompletedCallback
其中最为关键的看Download类
interface plus.downloader.Download {
readonly attribute String id;
readonly attribute String url;
readonly attribute Number state;
readonly attribute DownloadOptions options;
readonly attribute String filename;
readonly attribute Number downloadedSize;
readonly attribute Number totalSize;
function void abort();
function void addEventListener(String event, function Callback listener, Boolean capture);
function String getAllResponseHeaders();
function String getResponseHeader(String headerName);
function void pause();
function void resume();
function void setRequestHeader(String headerName, String headerValue);
function void start();
}
2、android系统通知栏相关资料查询
《ANDROID中使用NOTIFICATION实现进度通知栏(NOTIFICATION示例三)》
《Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它)》
四、注意细节
在设置进度条数据显示时,切记不要在主线程中实现设置通知,一定要开启一个子线程去实现操作,不然通知栏数据不会变更!!