Eclipse实现安卓客户端的版本更新

来源:互联网 发布:淘宝买家手机号提取 编辑:程序博客网 时间:2024/04/28 08:34
现在上线的APP大多要用到版本更新的功能,所以自己参考了有关更新代码,封装成了一个类,方便使用。该类实现加载MainActivity的时候自动检测是否是最新版本,如果不是则提示更新安装等操作。

1.权限声明

<!-- 访问网络的权限 --><uses-permission android:name="android.permission.INTERNET" /><!-- 在SDCard中创建与删除文件权限 -->  <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>  <!-- 往SDCard写入数据权限 -->  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

2.VersionUpdate类

该类只需要传递一个参数,就是Activity本身(this代替),来实现的Dialog显示等。

protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        new VersionUpdate(this);        }

3.用到的JAR包

xUtils-2.6.14.jar
主要实现访问服务器端,方便获取JSON数据等操作

4.主要方法

1.初始化,upload需要传递两个参数:1.访问网址 2.访问类型(有GETVERSION和GETAPK两个)
功能:访问接口地址,返回最新的APP版本信息

public VersionUpdate(Activity activity) {        this.activity = activity;        upload(url1, GETVERSION);    }

2.用到xUtils中httputils.send方法,根据访问类型来判断需要做的操作。因为不同的访问类型下,返回的JSON数据格式不同,不能按同一种方式解析。

public void upload(String url , final String type){        httputils = new HttpUtils();        httputils.send(HttpMethod.GET, url, new RequestCallBack<String>() {            @Override            public void onFailure(HttpException arg0, String arg1) {                Log.d("TAG", "访问失败!");            }            @Override            public void onSuccess(ResponseInfo<String> str) {                String index = str.result;                Bundle bundle = new Bundle();                bundle.putString("json", index);                Message msg = new Message();                msg.setData(bundle);                if(type.equals(GETVERSION)){                    Log.d("TAG", "版本更新访问成功,得到版本信息!");                    msg.what = 1;                    handler.sendMessage(msg);                }                if(type.equals(GETAPK)){                    Log.d("TAG", "获取APK地址!");                    msg.what = 2;                    handler.sendMessage(msg);                }            }        });    }

3.当我们获取到最新的APP版本信息时,需要知道我们当前APP的版本号,进而判断需不需要更新。
获取当前APP的版本号的代码: (就是mainfest文件中的android:versionName="1.0"

//获取当前应用的版本号    public String getVersion() {        try {            PackageManager manager = activity.getPackageManager();            PackageInfo info = manager.getPackageInfo(activity.getPackageName(), 0);            return info.versionName;        } catch (Exception e) {            e.printStackTrace();            return "无法获取版本号!";        }    }

4.Handler方法。
【判断版本号是否一致,当不一致时需要显示最新的版本信息,询问是否确定修改】
【当访问类型为GETAPK,会执行if(msg.what == 2)中的代码】

首先,为什么用handler方法?因为send方法中需要访问网路,所以是在新开的线程中去执行(因为在JAR包里,所以看不到),当需要对主线程中的控件等操作时,必须用handler回到主线程。但是本例中可以不用Handler方法。
其次,当执行到DIalog中的确定按钮后,将会再次去访问服务器段,但是传递的类型为GETAPK,之后会执行msg.what==2中的代码,执行下载APK的相关操作。

//处理网络访问版本更新后的操作    private Handler handler = new Handler(){        public void handleMessage(android.os.Message msg) {            Bundle bundle = new Bundle();            bundle = msg.getData();            String json = bundle.getString("json");            if(msg.what == 1){                try {                    JSONArray indexJsonArray = new JSONArray(json);                    JSONObject jsonobject = indexJsonArray.getJSONObject(0);                    version = jsonobject.getString("appVersion");                    first = jsonobject.getString("First");                    second = jsonobject.getString("Second");                    third = jsonobject.getString("Third");                    Log.d("TAG", version + first + second + third);                } catch (JSONException e) {                    e.printStackTrace();                }                String version1 = getVersion();                Log.d("TAG",version1);                /**                if(version.equals(version1)){                    Builder builder = new Builder(activity);                    builder.setMessage("当前版本已经是最新版");                    builder.setTitle("提示");                    builder.setPositiveButton("确定", new OnClickListener() {                        public void onClick(DialogInterface dialog,                                int which) {                            dialog.dismiss();                            // 设置你的操作事项                        }                    });                    builder.create().show();                }                */                if (!version.equals(version1)) {                    Builder builder = new Builder(activity);                    if(second.length()==0){                        builder.setMessage("有最新版本:"+version+",更新内容是:"+"\n"+first+";"+"\n"+"是否下载最新版本?");                    }else if(third.length()==0){                        builder.setMessage("有最新版本:"+version+",更新内容是:"+"\n"+first+";"+"\n"+second+";"+"\n"+"是否下载最新版本?");                    }else{                        builder.setMessage("有最新版本:"+version+",更新内容是:"+"\n"+first+";"+"\n"+second+";"+"\n"+third+";"+"\n"+"是否下载最新版本?");                    }                    builder.setTitle("提示");                    builder.setPositiveButton("确定",                            new DialogInterface.OnClickListener() {                                public void onClick(DialogInterface dialog,                                        int which) {                                    upload(url2,GETAPK);                                    dialog.dismiss();                                }                            });                    builder.setNegativeButton("取消",                            new DialogInterface.OnClickListener() {                                public void onClick(DialogInterface dialog,                                        int which) {                                    dialog.dismiss();                                }                            });                    builder.setCancelable(false);                    builder.create().show();                }             }            if(msg.what == 2){                try {                                       JSONObject jsonobject = new JSONObject(json);                    url = jsonobject.getString("appHostApk");                    Log.d("TAG", url);                } catch (JSONException e) {                    e.printStackTrace();                }                downLoadApk();            }        };    };

5.下载APK
【设置ProgressDialog pd;的显示信息,有很多功能的】

// 1.下载apk    protected void downLoadApk() {        pd = new ProgressDialog(activity);//新建一个显示在activity上的进度条对话框        pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);        pd.setCancelable(true);        pd.setCanceledOnTouchOutside(false);        pd.setMessage("正在下载更新");        pd.setProgressNumberFormat("%1d KB/%2d KB");        pd.show();        new Thread() {            @Override            public void run() {                try {                    File file = getFileFromServer(url, pd);                    sleep(1000);                    if (pd.isShowing()) {                        installApk(file);                    }                    pd.dismiss(); // 结束掉进度条对话框                } catch (Exception e) {                    e.printStackTrace();                }            }        }.start();    }

6.【下载APK文件到SD卡上】

// 3.从服务器下载APK    public  File getFileFromServer(String path, ProgressDialog pd)            throws Exception {        // 如果相等的话表示当前的sdcard挂载在手机上并且是可用的        if (Environment.getExternalStorageState().equals(                Environment.MEDIA_MOUNTED)) {            //连接下载地址,得到数据conn            URL url = new URL(path);            HttpURLConnection conn = (HttpURLConnection) url.openConnection();            conn.setConnectTimeout(5 * 60 * 1000);//5分钟的TimeOut限时            // 获取到文件的大小,设置PD显示的最大数据            pd.setMax(conn.getContentLength()/1000);            //把得到的APK文件变成输入流,存入Buffer缓存池            InputStream is = conn.getInputStream();            BufferedInputStream bis = new BufferedInputStream(is);            //新建APK文件            String ph = Environment.getExternalStorageDirectory()                    .getAbsolutePath() + "/gyz";            File file = new File(ph + File.separator + "suibian_"+version+".apk");//本地SD卡上存储            FileOutputStream fos = new FileOutputStream(file);            byte[] buffer = new byte[1024];            int len;            int total = 0;            //下载的APK文件写入新建的APK文件            while ((len = bis.read(buffer)) != -1 && pd.isShowing()) {                fos.write(buffer, 0, len);                total += len;                // 获取当前下载量                pd.setProgress(total/1000);            }            if (!pd.isShowing()) {                file.delete();            }            fos.close();            bis.close();            is.close();            return file;        } else {            return null;        }    }

7.到目前为止,已经现在好了APK文件到SD卡上了。
现在只需要把APK安装到手机上(注意下载的APK签名和自己手机上的APK签名的一致)。

// 2.安装apk    protected void installApk(File file) {        Intent intent = new Intent();        // 执行动作        intent.setAction(Intent.ACTION_VIEW);        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);        // 执行的数据类型        intent.setDataAndType(Uri.fromFile(file),                "application/vnd.android.package-archive");// 编者按:此处Android应为android,否则造成安装不了        activity.startActivity(intent);    }

8.【OVER】

1 0
原创粉丝点击