您的位置:首页 > 移动开发 > Android开发

andriod 自动更新开发

2016-07-09 20:08 495 查看
前几天抽空搞了一下android的自动更新功能,没想到很快就被我搞定了! 很有成就感,现在来回顾一下自动更新的开发流程!

      自动更新首先肯定需要服务器,于是在公司的测试服务器上的tomcat中部署了一个文件夹! 里面有两个文件,一个是xml 记录版本号信息,另一个自然就是最新的更新包了!  这是服务器上所必须的!

      有了服务器,就可以开始着手开发客户的代码了,代码在我的小猪音乐里面!  

第一步: 

       更新程序,在第一个activity的onCreate中 调用 检查更新的办法 因为在主线程不允许执行长耗时操作,所以要新建线程

       new Thread(new CheckVersionTask()).start();

       private class CheckVersionTask implements Runnable {

            @Override

            public void run() {

                Looper.prepare();

                Message msg = new Message();

                UpdateManager manager = new UpdateManager(MusicMainActivity.this);

                versionCode=manager.getVersionCode(MusicMainActivity.this);

                if(manager.isUpdate()){//需要更新就更新

                    msg.what = UPDATA_CLIENT;

                    handler.sendMessage(msg);

                }else{

                    msg.what = UPDATA_NONEED;

                    handler.sendMessage(msg);

                }

             

                //manager.checkUpdate();

               

            }

        }

相应的handler 如下:

Handler handler = new Handler() {

        @Override

        public void handleMessage(Message msg) {

        // TODO Auto-generated method stub

        super.handleMessage(msg);

        switch (msg.what) {

            case UPDATA_NONEED:

                Toast.makeText(MusicMainActivity.this,"当前版本号为:"+String.valueOf(versionCode)+ " 不需要更新",

                        Toast.LENGTH_SHORT).show();

                break;

            case UPDATA_CLIENT:

        //对话框通知用户升级程序

                showUpdataDialog();

                break;

            case GET_UNDATAINFO_ERROR:

        //服务器超时

                Toast.makeText(MusicMainActivity.this, "获取服务器更新信息失败", 1).show();

                break;

            case DOWN_ERROR:

        //下载apk失败

                Toast.makeText(MusicMainActivity.this, "下载新版本失败", 1).show();

            break;

            }

        }

    };

        联网去访问服务器里面的那个xml文件,读取里面的版本号,和当前版本号对比,如果服务器的版本号高于当前程序版本号,则 出现提示框 提示用户是否 更新!

    //提示是否更新对话框

     private void showUpdataDialog()

        {

         AlertDialog.Builder builder=new AlertDialog.Builder(this);

            builder.setTitle("发现新版本,是否更新?");  //设置标题

            //builder.setIcon(R.drawable.ic_launcher); //设置图标

            builder.setPositiveButton("更新",new DialogInterface.OnClickListener() {

               

                @Override

                public void onClick(DialogInterface arg0, int arg1) {

                    // TODO Auto-generated method stub

                    //Toast.makeText(MusicMainActivity.this, "马上更新", 1).show();

                    downLoadApk();

                }

            }

            ); //设置确定按钮

           

            builder.setNegativeButton("下次再说", new DialogInterface.OnClickListener() {

               

                @Override

                public void onClick(DialogInterface arg0, int arg1) {

                    // TODO Auto-generated method stub

                    //Toast.makeText(MusicMainActivity.this, "好的", 1).show();

                  

                }

            }); //设置取消按钮

            //builder.setView(diaview); //设置自定义的样式

            alertDialog=builder.create(); //生成Alertdialog对话框

            alertDialog.show(); //显示对话框

        }

       当用户选择了开始更新的时候,前台页面需要用到进度条等更新界面,所以用到handler来操作进度条的更新,一边下载,一边更新下载进度当下载完成的时候,就关闭掉进度条的对话框,开始自动安装!安装完后要出现 “完成” 和“打开” 窗口!

 protected void downLoadApk() {

        final ProgressDialog pd; //进度条对话框

        pd = new ProgressDialog(this);

        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

        pd.setMessage("正在下载更新");

        pd.show();

        new Thread(){

            public void run() {

                try {

                    File file = DownLoadManager.getFileFromServer(updateurl, pd);

                    sleep(2000);

                     installApk(file);

                     pd.dismiss(); //结束掉进度条对话框  } catch (Exception e) {

                }

               catch (Exception e) {

                  Message msg = new Message();

                  msg.what = DOWN_ERROR;

                  handler.sendMessage(msg);

                  e.printStackTrace();

               }

            }

        }.start();

       

    }

 

//安装apk  

     protected void installApk(File file) {

         Intent intent = new Intent();//执行动作  

         intent.setAction(Intent.ACTION_VIEW);//执行的数据类型 

         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
//这句话非常关键,没有这句话安装完不会出现完成 和打开页面

         intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");

        // intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

         startActivity(intent);

       

     }

到这里 ,自动更新的功能就完成了,上面用到了两个工具类 ,这里也贴出来吧!

UpdateManager 类

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.MalformedURLException;

import java.net.URL;

import java.util.HashMap;

import com.example.mymusic.R;

import android.app.AlertDialog;

import android.app.Dialog;

import android.app.AlertDialog.Builder;

import android.content.Context;

import android.content.DialogInterface;

import android.content.Intent;

import android.content.DialogInterface.OnClickListener;

import android.content.pm.PackageManager.NameNotFoundException;

import android.net.Uri;

import android.os.Environment;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.view.LayoutInflater;

import android.view.View;

import android.widget.ProgressBar;

import android.widget.Toast;

/**

 * @author coolszy

 * @date 2012-4-26

 * @blog http://blog.92coding.com

 */

public class UpdateManager {

    /* 保存解析的XML信息 */

    HashMap<String, String> mHashMap;

    // 服务器地址apk

    private String updateurl = "http://apptest.erke.com:8504/testVersion/MyMusic.apk";

    private String versionurl = "http://apptest.erke.com:8504/testVersion/updateVersion.xml";

    private Context mContext;

    public UpdateManager(Context context) {

        this.mContext = context;

    }

    /**

     * 检查软件是否有更新版本

     *

     * @return

     */

    public boolean isUpdate() {

        // 获取当前软件版本

        int versionCode = getVersionCode(mContext);

        // 把version.
afab
xml放到网络上,然后获取文件信息

        System.out.println("当前版本:" + versionCode);

        // InputStream inStream =

        // ParseXmlService.class.getClassLoader().getResourceAsStream("version.xml");

        URL url = null;

        try {

            url = new URL(versionurl);

        } catch (MalformedURLException e1) {

            // TODO Auto-generated catch block

            e1.printStackTrace();

        }

        HttpURLConnection conn = null;

        try {

            conn = (HttpURLConnection) url.openConnection();

        } catch (IOException e1) {

            // TODO Auto-generated catch block

            e1.printStackTrace();

        }

        conn.setConnectTimeout(5000);

        InputStream inStream = null;

        try {

            inStream = conn.getInputStream();

        } catch (IOException e1) {

            // TODO Auto-generated catch block

            e1.printStackTrace();

        }

        // 解析XML文件。 由于XML文件比较小,因此使用DOM方式进行解析

        ParseXmlService service = new ParseXmlService();

        try {

            mHashMap = service.parseXml(inStream);

        } catch (Exception e) {

            e.printStackTrace();

        }

        if (null != mHashMap) {

            int serviceCode = Integer.valueOf(mHashMap.get("version"));

            // 版本判断

            if (serviceCode > versionCode) {

                System.out.println("检查更新--最新版本" + serviceCode);

                return true;

            }

        }

        return false;

    }

    /**

     * 获取软件版本号

     *

     * @param context

     * @return

     */

    public int getVersionCode(Context context) {

        int versionCode = 0;

        try {

            // 获取软件版本号,对应AndroidManifest.xml下android:versionCode

            versionCode = context.getPackageManager().getPackageInfo(

                    "com.example.mymusic", 0).versionCode;

        } catch (NameNotFoundException e) {

            e.printStackTrace();

        }

        return versionCode;

    }

}

DownLoadManager 类

  

import java.io.BufferedInputStream;

import java.io.File;

import java.io.FileOutputStream;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.URL;

import android.app.ProgressDialog;

import android.os.Environment;

public class DownLoadManager {

    public static File getFileFromServer(String path, ProgressDialog pd)

            throws Exception {

        // 如果相等的话表示当前的sdcard挂载在手机上并且是可用的

        if (Environment.getExternalStorageState().equals(

                Environment.MEDIA_MOUNTED)) {

            URL url = new URL(path);

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setConnectTimeout(5000);

            // 获取到文件的大小

            pd.setMax(conn.getContentLength());

            InputStream is = conn.getInputStream();

            File file = new File(Environment.getExternalStorageDirectory(),

                    "updata.apk");

            FileOutputStream fos = new FileOutputStream(file);

            BufferedInputStream bis = new BufferedInputStream(is);

            byte[] buffer = new byte[1024];

            int len;

            int total = 0;

            while ((len = bis.read(buffer)) != -1) {

                fos.write(buffer, 0, len);

                total += len;

                // 获取当前下载量

                pd.setProgress(total);

            }

            fos.close();

            bis.close();

            is.close();

            return file;

        } else {

            return null;

        }

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android