美文网首页Android开发
android如何在wifi环境下 后台静默下载 新版apk?

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

作者: 凉了夏天宝贝 | 来源:发表于2016-05-05 16:04 被阅读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

    相关文章

      网友评论

        本文标题:android如何在wifi环境下 后台静默下载 新版apk?

        本文链接:https://www.haomeiwen.com/subject/kludrttx.html