让代码更简单

Android异步任务AsyncTask+自定义dialog版本更新

重要:本文最后更新于2022-11-08 19:26:07,某些文章具有时效性,若有错误或已失效,请在下方留言或联系代码狗

APP也是软件,是软件就要涉及更新,更新方法很多,流程一般都是获取版本更新信息,这个是用数据库还是用文件,或者用网页全看自己喜好。然后判断版本,下载新程序,安装。安卓的更新框架网上也有好几个,引入后几行代码即可完成功能,但自定义程度低,下面我以实例讲讲更新,下图是我刚刚写的更新效果。

Android异步任务AsyncTask+自定义dialog版本更新

Android异步任务AsyncTask+自定义dialog版本更新

我使用的PHP配合mysql做的后台,由于大家的验证过程不一样,这里就不讲版本验证过程了,先贴个APP版本的获取方法。

复制
public static int packageCode(Context context) {
    PackageManager manager = context.getPackageManager();
    int code = 0;
    try {
        PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
        code = info.versionCode;
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    return code;
}

然后需要一个异步任务来下载我们的新版本APP,下面是异步任务类。

复制
package com.zdhcsc.jingmizujian.hl;

import android.os.AsyncTask;
import android.os.Environment;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by Administrator on 2018/8/23.
 */

public class downloadapk extends AsyncTask<String, Integer, String> {

    public interface CallBack {
        public void start();  //任务开始这里面应该弹出进度条对话框

        public void updataProgress(int progress);//获取到更新的进度值为进度条对话框设置值

        /**
         * 下载完成,
         *
         * 1.对话框消失
         *
         * 2.启动安装apk界面,需要apk路径
         */
        public void finish(String apkPath);
    }

    CallBack cb;

    public downloadapk(CallBack cb) {
        super();
        this.cb = cb;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        if (cb != null) {
            cb.start();
        }
    }

    @Override
    protected String doInBackground(String... params) {
        // 1.HttpURLConnection
        HttpURLConnection conn = null;
        String apkPath = null;
        // 2.URL
        try {
            URL url = new URL(params[0]);
            // 3.url.openConnection
            conn = (HttpURLConnection) url.openConnection();
            // 4.InputStream
            InputStream in = conn.getInputStream();
            // 获取该文件的总长度
            int total = conn.getContentLength();
            // 5.获取保存文件的路径及文件 名/sdcard/abcdefg/tmp.apk
            String path_sdcard = Environment.getExternalStorageDirectory()
                    .getAbsolutePath() + "/abcdefg";
            File fileParent = new File(path_sdcard);
            // 判断该目录是否存在,如果不存在,创建该目录
            if (!fileParent.exists()) {
                // 创建目录
                fileParent.mkdirs();
            }
            // 6.创建File对象,再拿到OutputStream
            File file = new File(path_sdcard, "tmp.apk");
            //用来返回该apk路径
            apkPath = file.getAbsolutePath();
            OutputStream out = new FileOutputStream(file);
            // 7.创建byte[] buffer
            byte[] buffer = new byte[4096];
            // 8.inputStream==>OutputStream
            // 循环读写时,应该要把每次读入的长度进行累加,再把累加的值与总长度除一下,得到百分比用于更新进度条的值
            int sum = 0;
            int len = 0;
            while ((len = in.read(buffer)) != -1) {
                out.write(buffer, 0, len);
                // 累加
                sum = sum + len;
                // 计算百分比
                int per = (int) (sum * 100f / total);
                // 发布进度值
                publishProgress(per);
            }
            out.flush();
            // 收尾
            out.close();
            in.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        // 返回当前被保存的apk的绝对路径
        return apkPath;
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        // TODO Auto-generated method stub
        super.onProgressUpdate(values);
        if (cb != null) {
            cb.updataProgress(values[0]);
        }
    }

    /*
     * result表示的是apk的路径
     */
    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        if (cb != null) {
            cb.finish(result);
        }
    }

}

然后再写个方法使用这个异步下载类。

复制
 public void downlaod(String size,String path) {
        final String sizes=size;
        downloadapk down=new downloadapk(new downloadapk.CallBack() {
            @Override
            public void start() {
                //创建进度条对话框对象
                dialog = new ProgressDialog(getActivity());
                // 设置进度条的样式
                dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);// 设置样式
                //对话框 不终止对话框(如果它为true 代表进度条的值是0)
                dialog.setIndeterminate(false);
                //失去焦点的时候,不消失对话框
                dialog.setCancelable(false);
                // 设置消息
                dialog.setMessage("大小:"+sizes);
                // 设置标题
                dialog.setTitle("正在下载....");
                // 进度条总大小
                dialog.setMax(PROGRESS_MAX);
                dialog.show();
            }

            @Override
            public void updataProgress(int progress) {
                dialog.setProgress(progress);
            }

            @Override
            public void finish(String apkPath) {
dialog.dismiss();
                installApk(apkPath);
            }
        });
        down.execute(path);//需要下载的apk链接

    }

下载完成后的回调进行了自动安装,下面是自动安装方法。

复制
/**
 * 安装apk
 *
 * @param
 */
private void installApk(String apkFilePath) {
    File apkfile = new File(apkFilePath);
    if (!apkfile.exists()) {
        return;
    }
    Intent i = new Intent(Intent.ACTION_VIEW);
    i.setDataAndType(Uri.parse("file://" + apkfile.toString()),
            "application/vnd.android.package-archive");
    startActivity(i);
}

最后在你的验证流程的对应位置调用方法downlaod(文件大小,下载地址),即可。

感觉很棒!可以赞赏支持我哟~

0 打赏

评论 (0)

登录后评论
QQ咨询 邮件咨询 狗哥推荐