Android 自动更新

来源:互联网 发布:网络推广方式 编辑:程序博客网 时间:2024/05/16 00:32

在网上看了很多大牛写的后,自己仿写的一个自动更新 大概步骤就是,对比版本检测更新,下载apk,安装apk 直接上代码吧

==================================

package com.example.updatetestdemo.utils;import java.io.InputStream;import java.util.ArrayList;import java.util.List;import org.xmlpull.v1.XmlPullParser;import com.example.updatetestdemo.datas.UpdateXml;import com.example.updatetestdemo.interfaces.UpdatexmlService;import android.util.Xml;/** * 更新 */public class UpdateServiceIml implements UpdatexmlService{    @Override    public List<UpdateXml> parseXMLByPull(InputStream xml) throws Exception {        List<UpdateXml> uxList = null;        UpdateXml uXml = null;        // 首先得到Pull解析器        // XmlPullParser pull=(XmlPullParser) XPathFactory.newInstance();        XmlPullParser pull = Xml.newPullParser();        pull.setInput(xml, "UTF-8");// 设置要解析XML数据源        // 解析的过程中他会把xml读取到一个字符数组中,然后一个逐个字符读取当读取到结束标志">"时,会去根据XML语法判断,若匹配了某种语法就会出发预定义的事件比如说start        // document等,当解析到了start document之后就不会主动往后解析了        int event = pull.getEventType();// 获取事件类型        while (event != XmlPullParser.END_DOCUMENT) {            switch (event) {            case XmlPullParser.START_DOCUMENT:                uxList = new ArrayList<UpdateXml>();                uXml=new UpdateXml();                break;            // 当解析到了Employee节点,触发Start_tag            case XmlPullParser.START_TAG:                if ("version".equals(pull.getName())) {                    String version = pull.nextText();                    System.out.println("version"+version);                    uXml.setVersion(version);                }                if ("name".equals(pull.getName())) {                    String name = pull.nextText();                    System.out.println("name"+name);                    uXml.setName(name);                }                if ("url".equals(pull.getName())) {                    String url = pull.nextText();                    System.out.println("url"+url);                    uXml.setUrl(url);                }                break;            // 解析到结束标志时触发            case XmlPullParser.END_TAG:                if ("update".equals(pull.getName())) {                    uxList.add(uXml);                    uXml = null;                }                break;            }            event = pull.next();// 主动去遍历下一个节点        }        xml.close();        return uxList;    }}
/** * 更新 */public interface UpdatexmlService {    // 定义解析XML文件的方法    /**     * (non-Javadoc)     * @see com.example.interfaces.IEmployeeService#parseXMLByPull(java.io.InputStream)     * 使用Pull解析XML     */    public List<UpdateXml> parseXMLByPull(InputStream xml) throws Exception;}
package com.example.updatetestdemo.utils;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.lang.ref.WeakReference;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.List;import com.example.updatetestdemo.R;import com.example.updatetestdemo.datas.UpdateXml;import com.example.updatetestdemo.interfaces.UpdatexmlService;import android.annotation.SuppressLint;import android.app.Activity;import android.app.AlertDialog;import android.app.AlertDialog.Builder;import android.app.Dialog;import android.content.Context;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.content.Intent;import android.content.pm.PackageManager.NameNotFoundException;import android.net.Uri;import android.os.Environment;import android.os.Handler;import android.os.Message;import android.os.StrictMode;import android.view.LayoutInflater;import android.view.View;import android.widget.ProgressBar;import android.widget.Toast;/** * 更新 */public class Update {    // 获取XML的Url地址    private String path = "http://XXX.XXX.X.XXX:8080/Android/version.xml";    // 获取软件版本号的路径,对应AndroidManifest.xml下android:versionCode    private String versionCodePath = "com.example.updatetestdemo";    /* 保存解析的XML信息 */    private List<UpdateXml> uxList;    /* 下载 */    private static final int DOWNLOAD = 1;    /* 下载结束 */    private static final int DOWNLOAD_FINISH = 2;    /* 显示更新对话框*/    private static final int UPDATE_YES = 3;    /* 没有更新的提示*/    private static final int UPDATE_ON = 4;    /* 下载保存路径 */    private String mSavePath;    /* 记录进度条数 */    private int progress;    /* 是否取消更新 */    private boolean cancelUpdate = false;    private Context mContext;    /* 更新进度 */    private ProgressBar mProgress;    private Dialog mDownloadDialog;    private MyHandlerUpdate myHandler = new MyHandlerUpdate(this);    static class MyHandlerUpdate extends Handler {        WeakReference<Update> mActivityReference;        MyHandlerUpdate(Update activity) {            mActivityReference = new WeakReference<Update>(activity);        }        @Override        public void handleMessage(Message msg) {            final Update activity = mActivityReference.get();            if (activity != null) {                switch (msg.what) {                // 正在下载                case DOWNLOAD:                    // 设置进度条位置                    activity.mProgress.setProgress(activity.progress);                    break;                case DOWNLOAD_FINISH:                    // 安装文件                    activity.installApk();                case UPDATE_YES:                    // 检测到有更新,显示更新对话框                    activity.showNoticeDialog();                case UPDATE_ON:                    // 已经是最新版本                    Toast.makeText(activity.mContext, "已经是最新版本",                            Toast.LENGTH_LONG).show();                    break;                default:                    break;                }            }        }    }    /**     * 2017-3-13上午9:11:37     *      * @param context     */    public Update(Context context) {        this.mContext = context;    }    /**     * 测试是否有更新     */    public void checkUpdate() {        new Thread(new Runnable() {            @Override            public void run() {                if (isUpdate()) {                    // 显示提示对话框                    myHandler.sendEmptyMessage(UPDATE_YES);                } else {                    myHandler.sendEmptyMessage(UPDATE_ON);                }            }        }).start();    }    /**     * 检查软件是否有更新版本     *      * @return     */    private boolean isUpdate() {        // 获取当前软件版本        int versionCode = getVersionCode(mContext);        URL url = null;        HttpURLConnection conn = null;        InputStream is = null;        try {            url = new URL(path);            conn = (HttpURLConnection) url.openConnection();            conn.setConnectTimeout(5000);            conn.setReadTimeout(5000);            conn.setRequestMethod("GET");            conn.setRequestProperty("accept", "*/*");            conn.setRequestProperty("connection", "Keep-Alive");            System.out.println(conn.getResponseCode() + "");            if (conn.getResponseCode() == 200) {                is = conn.getInputStream();                UpdatexmlService uXmlService = new UpdateServiceIml();                uxList = uXmlService.parseXMLByPull(is);                if (is == null) {                    L.e("TAG", " ins nullnull");                } else {                    L.e("TAG", " ins not nullnull");                }                if (uxList == null) {                    L.e("TAG", " xml nullnull");                }            } else {                throw new RuntimeException(" responseCode is not 200 ... ");            }            String version = uxList.get(0).getVersion();            int serviceCode = Integer.parseInt(version);            // 版本判断            System.out.println(serviceCode + ">>" + versionCode);            if (serviceCode > versionCode) {                return true;            }        } catch (Exception e) {            e.printStackTrace();        }        return false;    }    /**     * 获取软件版本号     *      * @param context     * @return     */    private int getVersionCode(Context context) {        int versionCode = 0;        try {            // 获取软件版本号,对应AndroidManifest.xml下android:versionCode            versionCode = context.getPackageManager().getPackageInfo(                    versionCodePath, 0).versionCode;        } catch (NameNotFoundException e) {            e.printStackTrace();        }        return versionCode;    }    /**     * 显示软件更新对话框     */    private void showNoticeDialog() {        // 对话框        AlertDialog.Builder builder = new Builder(mContext);        builder.setTitle("软件更新");        builder.setMessage("检测到新版本,立即更新吗");        // showDownloadDialog();// 直接强制更新        // 更新        builder.setPositiveButton("更新", new OnClickListener() {            public void onClick(DialogInterface dialog, int which) {                dialog.dismiss();                // 显示下载对话框                showDownloadDialog();            }        });        // 稍后更新        builder.setNegativeButton("稍后更新", new OnClickListener() {            public void onClick(DialogInterface dialog, int which) {                dialog.dismiss();            }        });        Dialog noticeDialog = builder.create();        noticeDialog.show();    }    /**     * 显示软件下载对话     */    private void showDownloadDialog() {        // 构�?�软件下载对话框        AlertDialog.Builder builder = new Builder(mContext);        builder.setTitle("正在更新");        // 给下载对话框增加进度        final LayoutInflater inflater = LayoutInflater.from(mContext);        View v = inflater.inflate(R.layout.update_progress, null);        mProgress = (ProgressBar) v.findViewById(R.id.update_pb);        builder.setView(v);        // 取消更新        builder.setNegativeButton("取消更新", new OnClickListener() {            public void onClick(DialogInterface dialog, int which) {                dialog.dismiss();                // 设置取消状态                cancelUpdate = true;            }        });        mDownloadDialog = builder.create();        mDownloadDialog.setCanceledOnTouchOutside(false);        mDownloadDialog.show();        // 现在文件        downloadApk();    }    /**     * 下载apk文件     */    private void downloadApk() {        // 启动新线程下载软件        new downloadApkThread(uxList.get(0)).start();    }    /**     * 下载文件线程     *      */    private class downloadApkThread extends Thread {        UpdateXml uXml;        public downloadApkThread(UpdateXml ux) {            this.uXml = ux;        }        @Override        public void run() {            try {                // 判断SD卡是否存在,并且是否具有读写权限                if (Environment.getExternalStorageState().equals(                        Environment.MEDIA_MOUNTED)) {                    // 获得存储卡的路径                    String sdpath = Environment.getExternalStorageDirectory()                            + "/";                    mSavePath = sdpath + "download";                    URL url = new URL(uXml.getUrl());                    // 创建连接                    HttpURLConnection conn = (HttpURLConnection) url                            .openConnection();                    conn.connect();                    // 获取文件大小                    int length = conn.getContentLength();                    // 创建输入                    InputStream is = conn.getInputStream();                    File file = new File(mSavePath);                    // 判断文件目录是否存在                    if (!file.exists()) {                        file.mkdir();                    }                    File apkFile = new File(mSavePath, uXml.getName());                    FileOutputStream fos = new FileOutputStream(apkFile);                    int count = 0;                    // 缓存                    byte buf[] = new byte[1024];                    // 写入到文件中                    do {                        int numread = is.read(buf);                        count += numread;                        // 计算进度条位置                        progress = (int) (((float) count / length) * 100);                        // 更新进度                        myHandler.sendEmptyMessage(DOWNLOAD);                        if (numread <= 0) {                            // 下载完成                            myHandler.sendEmptyMessage(DOWNLOAD_FINISH);                            break;                        }                        // 写入文件                        fos.write(buf, 0, numread);                    } while (!cancelUpdate);// 点击取消就停止下载                    fos.close();                    is.close();                }            } catch (MalformedURLException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            }            // 取消下载对话框的显示            mDownloadDialog.dismiss();        }    };    /**     * 安装APK文件     */    private void installApk() {        File apkfile = new File(mSavePath, uxList.get(0).getName());        if (!apkfile.exists()) {            return;        }        // 通过Intent安装APK文件        Intent i = new Intent(Intent.ACTION_VIEW);        i.setDataAndType(Uri.parse("file://" + apkfile.toString()),                "application/vnd.android.package-archive");        mContext.startActivity(i);        ((Activity) mContext).finish();    }}
package com.example.updatetestdemo.datas;/** * 更新 */public class UpdateXml {    private String version;//版本号    private String name;//APK名称    private String url;//下载APK的URL    public String getVersion() {        return version;    }    public void setVersion(String version) {        this.version = version;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getUrl() {        return url;    }    public void setUrl(String url) {        this.url = url;    }    @Override    public String toString() {        return "UpdataInfo [version=" + version + ", name=" + name + ", url="                + url + "]";    }    public UpdateXml(String version, String name, String url) {        super();        this.version = version;        this.name = name;        this.url = url;    }    public UpdateXml() {        super();    }}
0 0