Android开发

android如何在wifi环境下 后台静默下载 新版apk?

2016-05-05  本文已影响2513人  凉了夏天宝贝

前段时间,公司有个需求,要求每次用户打开app的时候,请求后台的接口,查看是否有最新版本的包,如果有更新,则去后台偷偷的下载最新版本的apk,考虑到用户流量,要求下载apk必须是在wifi环境下下载,基于此需求,主要有如下几个方面的考虑:

一、app首页请求接口,根据后台返回的最新版本号,以及数据库存的版本号,判断是否需要开始下载,还是接着上次下载

二、下载管理器:如果需要下载,则开启service,service中开启一个线程,让线程去下载apk,注意:如果wifi断了,一定要关闭线程,关闭service

三、对wifi写个广播接收者,如果wifi断了,这时候应该停止下载,如果wifi又连上了,则继续上次的下载

四、数据库:如果此时wifi断了,然后新版本又下载了一部分了,此时需要暂停下载,将已经下载的部分,包括下载的进度,新版的版本号等信息存入数据库中,基于此考虑,第一条,还需要根据数据库存入的版本号做比对,因为如果本地是1,数据库存的是2,这时候请求接口,发现接口返回是3,则需要更新数据库,并将已经下载的本地文件删除,重新下载

贴部分代码:

一、

//请求是否需要更新,请求后台的接口

requestVersionUpdate();

//后台接口返回

@Override

public voidonDataChanged(UpdateVersion data, NetworkHelper helper) {

if(null!= data) {

intro= data.intro;//更新文案

download_link= data.download_link;//新版本的下载链接

newVersion= data.version_code;//新版本的code

mDao=newThreadDaoImpl(SplashActivity.this);//得到数据库操作对象

threadInfo=mDao.select();//查询数据库里保存的纪录,如果没有,则为空

if(null!=threadInfo) {

dbVersion=threadInfo.getVersioncode();//得到数据库里保存的,上次下载的apk的版本号

}

fileName="/ceshi.apk";

forceInstall= data.force_update;//是否强制用户安装

//当前程序的版本号

intcurrentVersionCode = CommonHelper.getVersionCode(getApplicationContext());

if(newVersion== currentVersionCode) {

//如果有文件,则删除apk所在的文件

File file =newFile(DownloadService.DOWNLOAD_PATH);

if(file.exists()) {

FileUtil.deleteFile(file);

}

}else{

DownloadHelper downloadHelper =newDownloadHelper(SplashActivity.this);

if(dbVersion== -1) {

//通知下载器去下载,并且把纪录插入数据库中

ThreadInfo info =newThreadInfo(0,download_link,0,0,0,newVersion, MySqliteHelper.UNDOWNLOAD,intro, DownloadService.DOWNLOAD_PATH,fileName);

if(!mDao.isExists(newVersion)) {

mDao.insertThread(info);

}

//如果文件已经存在,则删除文件,防止用户已经部分下载了,然后把程序卸载了,后来又重新安装,此时需要将文件删除

File file =newFile(info.getDownloadFile());

if(file.exists()) {

FileUtil.deleteFile(file);

}

downloadHelper.downloadApk(info);

}else if(newVersion>dbVersion) {

//从数据库里查询是否下载过apk,如果有则删除下载的apk文件,并且将dbversion更新为最新的版本号

File file =newFile(threadInfo.getDownloadFile() +threadInfo.getFileName());

Log.i("anru","newVersion > dbVersion:::file:"+ file.toString());

// 路径为文件且不为空则进行删除

if(file.isFile() && file.exists()) {

file.delete();

mDao.deleteThread(dbVersion);

}

//删除之后,去启动下载

//通知下载器去下载

ThreadInfo info =newThreadInfo(0,download_link,0,0,0,newVersion, MySqliteHelper.UNDOWNLOAD,intro, DownloadService.DOWNLOAD_PATH,fileName);

if(!mDao.isExists(newVersion)) {

mDao.insertThread(info);

}

downloadHelper.downloadApk(info);

}else if(newVersion==dbVersion&&dbVersion> currentVersionCode) {

//从数据库里查询是否下载过apk,如果有则删除下载的apk文件,并且将dbversion更新为最新的版本号

File file =newFile(threadInfo.getDownloadFile() +threadInfo.getFileName());

if(threadInfo.getApkstatus() != MySqliteHelper.DOWNLOAD_COM) {

//继续去下载

downloadHelper.downloadApk(threadInfo);

}else if(!MD5Helper.getMD5(file).equals(data.apk_md5)) {//如果md5值不一致,则删除原文件,重新下载

// 路径为文件且不为空则进行删除

if(file.isFile() && file.exists()) {

file.delete();

mDao.deleteThread(dbVersion);

}

//删除之后,去启动下载

//通知下载器去下载

ThreadInfo info =newThreadInfo(0,download_link,0,0,0,newVersion, MySqliteHelper.UNDOWNLOAD,intro, DownloadService.DOWNLOAD_PATH,fileName);

if(!mDao.isExists(newVersion)) {

mDao.insertThread(info);

}

}else{

//提示用户安装

isShowInstall=1;

}

}

}

}

二、下载管理器:

//开启服务

Intent intent =newIntent(context, DownloadService.class);

intent.putExtra("info",info);

DownloadTask.mIsPause=false;

context.startService(intent);

//在服务页面,开启线程

@Override

public intonStartCommand(Intent intent,intflags,intstartId) {

try{

ThreadInfo info = (ThreadInfo) intent.getSerializableExtra("info");

if(info.getApkstatus() != MySqliteHelper.DOWNLOAD_COM) {//如果暂时未下载,去下载

//判断网络状态

if(isWifiAvailable()) {

thread=newInitThread(info);

thread.start();

}

}

}catch(Exception e) {

e.printStackTrace();

Log.i("anru","download kill");

DownloadTask.mIsPause=true;

stopSelf();

}

return super.onStartCommand(intent, flags, startId);

}

//下载的线程

classDownLoadThread extends Thread {

privateThreadInfo info;

public DownLoadThread(ThreadInfo info) {

this.info= info;

}

@Override

public voidrun() {

Log.i("anru","download开始下载");

Log.i("anru","apkstatus:"+info.getApkstatus());

HttpURLConnection conn =null;

RandomAccessFile raf =null;

InputStream in =null;

try{

URL url =newURL(info.getUrl());

conn = (HttpURLConnection) url.openConnection();

conn.setConnectTimeout(3000);

conn.setDoInput(true);

conn.setRequestMethod("GET");

// 设置下载位置

int start =info.getStart() +info.getFinished();

conn.setRequestProperty("Range",

"bytes="+ start +"-"+info.getEnd());

// 设置文件写入位置

File file =new File(info.getDownloadFile(),info.getFileName());

raf =new RandomAccessFile(file,"rwd");

raf.seek(start);

//Intent intent = new Intent(DownloadService.ACTION_UPDATE);

finished+=info.getFinished();

// 开始下载

if(conn.getResponseCode() ==206|| conn.getResponseCode() ==200) {//206 Partial Content

// 读取数据

in = conn.getInputStream();

intlen = -1;

byte[] b =new byte[1024*4];

longtime = System.currentTimeMillis();

while((len = in.read(b)) != -1) {

// 写入文件

raf.write(b,0, len);

finished+= len;

Log.i("anru","finished:"+finished);

info.setFinished(finished);

if(finished==info.getEnd()) {

info.setApkstatus(MySqliteHelper.DOWNLOAD_COM);

}else if(finished>0&&finished

info.setApkstatus(MySqliteHelper.DOWNLOAD_UNCOM);

}

mDao.updateThread(info);

// 在下载暂停时,保存下载进度

if(mIsPause) {

Log.i("anru","mIsPause");

return;

}

}

}

}catch(Exception e) {

Log.e("anru","跳出来了");

}finally{

try{

raf.close();

if(null!= in) {

in.close();

}

conn.disconnect();

}catch(Exception e) {

e.printStackTrace();

}

}

}

三、wifi监听器广播

@Override

public void onReceive(Context context, Intent intent) {

//TODO Auto-generated method stub

if(intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {//wifi连接上与否

NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);

if(info.getState().equals(NetworkInfo.State.DISCONNECTED)) {

//暂停apk的下载

Intent intent1 =newIntent(context, DownloadService.class);

context.stopService(intent1);

}else if(info.getState().equals(NetworkInfo.State.CONNECTED)) {

//继续去下载

DownloadHelper downloadHelper =newDownloadHelper(context);

ThreadDaoImpl mDao =newThreadDaoImpl(context);

ThreadInfo threadInfo = mDao.select();

downloadHelper.downloadApk(threadInfo);

}

}

}

四、数据库:

public interface ThreadDao {

public void insertThread(ThreadInfo info);

public void updateThread(ThreadInfo info);

public List getThreads(String url);

public boolean isExists(intversionCode);

public ThreadInfo select();

public void deleteThread(intversionCode);

上边代码只挑了一些比较重点的贴了,如果想下载demo,链接:

点击下载demo

http://download.csdn.net/detail/forever521_/9510974

上一篇下一篇

猜你喜欢

热点阅读