android handler更新ui service android更新提示框_ide

获取版本号#

id : 驼峰式命名:   控件类型_控件的所在位置_控件表示的逻辑内容

/**
 * 获取当前应用程序的版本号
 * @return
 */
private String getVersionName(){
        //包的管理者,获取清单文件中的所有信息
        PackageManager pm = getPackageManager();
        try {
            //根据包名获取清单文件中的信息,其实就是返回一个保存有清单文件信息的javabean
            //packageName :应用程序的包名
            //flags : 指定信息的标签,0:获取基础的信息,比如包名,版本号,要想获取权限等等信息,必须通过标签来指定,才能去获取
            //GET_PERMISSIONS : 标签的含义:处理获取基础信息之外,还会额外获取权限的信息
            //getPackageName() : 获取当前应用程序的包名
            PackageInfo packageInfo = pm.getPackageInfo(getPackageName(), 0);
            //获取版本号名称
            String versionName = packageInfo.versionName;
            return versionName;
        } catch (NameNotFoundException e) {
            //包名找不到的异常
            e.printStackTrace();
        }
        return null;
    }

连接服务器

/**
 * 提醒用户更新版本
 */
private void update() {
        //1.连接服务器,查看是否有最新版本,  联网操作,耗时操作,4.0以后不允许在主线程中执行的,放到子线程中执行
        new Thread(){
            public void run() {
                try {
                    //1.1连接服务器
                    //1.1.1设置连接路径
                    //spec:连接路径
                    URL url = new URL("xxxxx");
                    //1.1.2获取连接操作
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();//http协议,httpClient
                    //1.1.3设置超时时间
                    conn.setConnectTimeout(5000);//设置连接超时时间
                    //conn.setReadTimeout(5000);//设置读取超时时间
                    //1.1.4设置请求方式
                    conn.setRequestMethod("GET");//post
                    //1.1.5获取服务器返回的状态码,200,404,500
                    int responseCode = conn.getResponseCode();
                    if (responseCode == 200) {
                        //连接成功
                    }else{
                        //连接失败
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            };
        }.start();
    }

    权限:<uses-permission android:name="android.permission.INTERNET"/>

解析json数据# ()

1.获取服务器返回的流信息
    //获取服务器返回的流信息
InputStream in = conn.getInputStream();
    2.将流信息转化成字符串
        public class StreamUtil {
            /**
             * 将流信息转化成字符串
             * @return
             * @throws IOException 
             */
            public static String parserStreamUtil(InputStream in) throws IOException{
                //字符流,读取流
                BufferedReader br = new BufferedReader(new InputStreamReader(in));
                //写入流
                StringWriter sw  = new StringWriter();
                //读写操作
                //数据缓冲区
                String str = null;
                while((str = br.readLine()) !=null){
                    //写入操作
                    sw.write(str);
                }
                //关流
                sw.close();
                br.close();
                return sw.toString();
            }
        }
3.解析json数据
    //将获取到的流信息转化成字符串
String json = StreamUtil.parserStreamUtil(in);
        //解析json数据
        JSONObject jsonObject = new JSONObject(json);
4.获取数据
    //获取数据
code = jsonObject.getString("code");
        apkurl = jsonObject.getString("apkurl");
        des = jsonObject.getString("des");

弹出对话框

1.因为在子线程不能更新主线程ui所以给handler发送一个,在handler中弹出对话框
private Handler handler = new Handler(){
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                case MSG_UPDATE_DIALOG:
                    //弹出对话框
                    showdialog();
                    break;
                }
            };
        };
2.弹出对话框
    /**
     * 弹出对话框
     */
protected void showdialog() {
            AlertDialog.Builder builder = new Builder(this);
            //设置对话框不能消失
            builder.setCancelable(false);
            //设置对话框的标题
            builder.setTitle("新版本:"+code);
            //设置对话框的图标
            builder.setIcon(R.drawable.ic_launcher);
            //设置对话框的描述信息
            builder.setMessage(des);
            //设置升级取消按钮
            builder.setPositiveButton("升级", new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                }
            });
            builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface dialog, int which) {

                }
            });
            //显示对话框
            //builder.create().show();//两种方式效果一样
            builder.show();
        }

对话框细节的处理

1.实现了取消按钮的操作
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {

            @Override
            public void onClick(DialogInterface dialog, int which) {
                //1.隐藏对话框
                dialog.dismiss();
                //2.跳转到主界面
                enterHome();
            }
        });
2.处理了在跳转到主界面,从主界面点击返回键返回的时候,返回欢迎界面的问题,解决:在跳转的是将欢迎界面移出
    /**
     * 跳转到主界面
     */
protected void enterHome() {
            Intent intent = new Intent(this,HomeActivity.class);
            startActivity(intent);
            //移出欢迎界面
            finish();
        }
3.处理对话框延迟显示的问题
    //处理连接外网连接时间的问题
    //在连接成功之后在去获取一个时间
int endTime = (int) System.currentTimeMillis();
        //比较两个时间的时间差,如果小于两秒,睡两秒,大于两秒,不睡
        int dTime = endTime-startTime;
        if (dTime<2000) {
            //睡两秒钟
            SystemClock.sleep(2000-dTime);//始终都是睡两秒钟的时间
        }
/**
 * 3.下载最新版本
 */
protected void download() {
        HttpUtils httpUtils = new HttpUtils();
        //判断SD卡是否挂载
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            //url : 新版本下载的路径 apkurl
            //target : 保存新版本的目录
            //callback : RequestCallBack
            httpUtils.download(apkurl, "/mnt/sdcard/xxxx.apk", new RequestCallBack<File>() {
                //现在成功调用的方法
                @Override
                public void onSuccess(ResponseInfo<File> arg0) {
                    // TODO Auto-generated method stub

                }
                //下载失败调用的方法
                @Override
                public void onFailure(HttpException arg0, String arg1) {
                    // TODO Auto-generated method stub

                }
                //显示当前下载进度操作
                //total : 下载总进度
                //current : 下载的当前进度
                //isUploading : 是否支持断点续传
                @Override
                public void onLoading(long total, long current, boolean isUploading) {
                    super.onLoading(total, current, isUploading);
                    //设置显示下载进度的textview可见,同时设置相应的下载进度
                    tv_spalsh_plan.setVisibility(View.VISIBLE);//设置控件是否可见
                    tv_spalsh_plan.setText(current+"/"+total);//110/200
                }

            });
        }
    }
注意问题:
    1.修改apkurl地址
    2.增加sd操作权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        3.判断sd是否挂载
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {}
4.生成2.0版本的apk
        工程的bin目录下去找
        a.将清单文件中的版本号改成2.0
        b.重新运行
        c.拷贝bin目录下的文件

/**
* 4.安装最新的版本
*/

protected void installAPK() {
        /**
         *  <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="content" /> //content : 从内容提供者中获取数据  content://
                <data android:scheme="file" /> // file : 从文件中获取数据
                <data android:mimeType="application/vnd.android.package-archive" />
            </intent-filter>
         */
        Intent intent = new Intent();
        intent.setAction("android.intent.action.VIEW");
        intent.addCategory("android.intent.category.DEFAULT");
        //单独设置会相互覆盖
        /*intent.setType("application/vnd.android.package-archive");
        intent.setData(Uri.fromFile(new File("/mnt/sdcard/mobliesafe75_2.apk")));*/
        intent.setDataAndType(Uri.fromFile(new File("/mnt/sdcard/mobliesafe75_2.apk")), "application/vnd.android.package-archive");
        //在当前activity退出的时候,会调用之前的activity的onActivityResult方法
        //requestCode : 请求码,用来标示是从哪个activity跳转过来
        //ABC  a -> c    b-> c  ,c区分intent是从哪个activity传递过来的,这时候就要用到请求码
        startActivityForResult(intent, 0);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        enterHome();
    }