1.设计思路,使用versioncode定义为版本升级参数。
android为我们定义版本提供了2个属性:
2.工程目录
为了对真实项目或者企业运用有实战指导作用,我模拟一个独立的项目,工程目录设置的合理严谨一些,而不是仅仅一个demo。
假设我们以上海地铁为项目,命名为"subway",工程结构如下,
3.版本初始化和版本号的对比。
首先定义在全局文件global.java中定义变量localversion和serverversion分别存放本地版本号和服务器版本号。
if(global.localversion < global.serverversion){
//发现新版本,提示用户更新
alertdialog.builder alert = new alertdialog.builder(this);
alert.settitle("软件升级")
.setmessage("发现新版本,建议立即更新使用.")
.setpositivebutton("更新", new dialoginterface.onclicklistener() {
public void onclick(dialoginterface dialog, int which) {
//开启更新服务updateservice
//这里为了把update更好模块化,可以传一些updateservice依赖的值
//如布局id,资源id,动态获取的标题,这里以app_name为例
intent updateintent =new intent(subwayactivity.this, updateservice.class);
updateintent.putextra("titleid",r.string.app_name);
startservice(updateintent);
}
})
.setnegativebutton("取消",new dialoginterface.onclicklistener(){
public void onclick(dialoginterface dialog, int which) {
dialog.dismiss();
}
});
alert.create().show();
}else{
//清理工作,略去
//cheanupdatefile(),文章后面我会附上代码
}
}
好,我们现在把这些东西串一下:
第一步在subwayapplication的oncreate()方法中执行initglobal()初始化版本变量。
现在入口已经打开,在checkversion方法的第18行代码中看出,当用户点击更新,我们开启更新服务,从服务器上下载最新版本。
4.使用service在后台从服务器端下载,完成后提示用户下载完成,并关闭服务。
定义一个服务updateservice.java,首先定义与下载和通知相关的变量:
//文件存储
private file updatedir = null;
private file updatefile = null;
//通知栏
private notificationmanager updatenotificationmanager = null;
private notification updatenotification = null;
//通知栏跳转intent
private intent updateintent = null;
private pendingintent updatependingintent = null;
在onstartcommand()方法中准备相关的下载工作:
this.updatenotificationmanager = (notificationmanager)getsystemservice(notification_service);
this.updatenotification = new notification();
//设置下载过程中,点击通知栏,回到主界面
updateintent = new intent(this, subwayactivity.class);
updatependingintent = pendingintent.getactivity(this,0,updateintent,0);
//设置通知栏显示内容
updatenotification.icon = r.drawable.arrow_down_float;
updatenotification.tickertext = "开始下载";
updatenotification.setlatesteventinfo(this,"上海地铁","0%",updatependingintent);
//发出通知
updatenotificationmanager.notify(0,updatenotification);
//开启一个新的线程下载,如果使用service同步下载,会导致anr问题,service本身也会阻塞
new thread(new updaterunnable()).start();//这个是下载的重点,是下载的过程
return super.onstartcommand(intent, flags, startid);
}
从代码中可以看出来,updaterunnable类才是真正下载的类,出于用户体验的考虑,这个类是我们单独一个线程后台去执行的。
下载的过程有两个工作:1.从服务器上下载数据;2.通知用户下载的进度。
线程通知,我们先定义一个空的updatehandler。
[/code]
private handler updatehandler = new handler(){
@override
public void handlemessage(message msg) {
}
};
[/code]
再来创建updaterunnable类的真正实现:
httpurlconnection httpconnection = null;
inputstream is = null;
fileoutputstream fos = null;
try {
url url = new url(downloadurl);
httpconnection = (httpurlconnection)url.openconnection();
httpconnection.setrequestproperty("user-agent", "pacifichttpclient");
if(currentsize > 0) {
httpconnection.setrequestproperty("range", "bytes=" + currentsize + "-");
}
httpconnection.setconnecttimeout(10000);
httpconnection.setreadtimeout(20000);
updatetotalsize = httpconnection.getcontentlength();
if (httpconnection.getresponsecode() == 404) {
throw new exception("fail!");
}
is = httpconnection.getinputstream();
fos = new fileoutputstream(savefile, false);
byte buffer[] = new byte[4096];
int readsize = 0;
while((readsize = is.read(buffer)) > 0){
fos.write(buffer, 0, readsize);
totalsize += readsize;
//为了防止频繁的通知导致应用吃紧,百分比增加10才通知一次
if((downloadcount == 0)||(int) (totalsize*100/updatetotalsize)-10>downloadcount){
downloadcount += 10;
updatenotification.setlatesteventinfo(updateservice.this, "正在下载", (int)totalsize*100/updatetotalsize+"%", updatependingintent);
updatenotificationmanager.notify(0, updatenotification);
}
}
} finally {
if(httpconnection != null) {
httpconnection.disconnect();
}
if(is != null) {
is.close();
}
if(fos != null) {
fos.close();
}
}
return totalsize;
}
下载完成后,我们提示用户下载完成,并且可以点击安装,那么我们来补全前面的handler吧。
先在updateservice.java定义2个常量来表示下载状态:
updatenotification.defaults = notification.default_sound;//铃声提醒
updatenotification.setlatesteventinfo(updateservice.this, "上海地铁", "下载完成,点击安装。", updatependingintent);
updatenotificationmanager.notify(0, updatenotification);
//停止服务
stopservice(updateintent);
case download_fail:
//下载失败
updatenotification.setlatesteventinfo(updateservice.this, "上海地铁", "下载完成,点击安装。", updatependingintent);
updatenotificationmanager.notify(0, updatenotification);
default:
stopservice(updateintent);
}
}
};
如对本文有疑问, 点击进行留言回复!!
Android SDK Manager 不知为什么突然打不开了?看这里
监听Android系统发出的插入SD卡并且已正确安装(识别)时发出的广播
RecyclerView三种常用效果的实现方法-android-kotlin
Android Studio app启动错误 Error running :Default Activity not found
网友评论