检查版本更新,更新,断点续传

依赖:

 annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    compile 'com.android.support:recyclerview-v7:26.1.0'
//注意版本
    compile 'com.squareup.retrofit2:retrofit:2.0.1'
// Okhttp库
    compile 'com.squareup.okhttp3:okhttp:3.1.2'
    compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
// Retrofit库
    implementation 'com.squareup.retrofit2:retrofit:2.4.0'
    compile 'com.squareup.retrofit2:converter-gson:2.4.0'
    compile 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
// rxjava+rxandroid+retrofit2+okhttp
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
    implementation 'io.reactivex.rxjava2:rxjava:2.1.12'
    compile 'com.github.bumptech.glide:glide:3.7.0'
    compile 'com.google.code.gson:gson:2.2.4'
    compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
    compile 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    compile 'org.greenrobot:eventbus:3.0.0'
    compile 'com.github.bumptech.glide:glide:3.7.0'
    compile 'com.facebook.fresco:fresco:0.12.0'

//清单文件加个请求网络

bean包:

DateBean:

public class DateBean {

    /**
     * success : true
     * msg : 检查到新的版本
     * data : {"last_version":5,"last_must_update":3,"url":"http://www.xieast.com/api/new_version.apk","md5":"8a7e66aa24db642af2afbff7b6b1f359"}
     */

    private boolean success;
    private String msg;
    private DataBean data;

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public DataBean getData() {
        return data;
    }

    public void setData(DataBean data) {
        this.data = data;
    }

    public static class DataBean {
        /**
         * last_version : 5
         * last_must_update : 3
         * url : http://www.xieast.com/api/new_version.apk
         * md5 : 8a7e66aa24db642af2afbff7b6b1f359
         */

        private int last_version;
        private int last_must_update;
        private String url;
        private String md5;

        public int getLast_version() {
            return last_version;
        }

        public void setLast_version(int last_version) {
            this.last_version = last_version;
        }

        public int getLast_must_update() {
            return last_must_update;
        }

        public void setLast_must_update(int last_must_update) {
            this.last_must_update = last_must_update;
        }

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }

        public String getMd5() {
            return md5;
        }

        public void setMd5(String md5) {
            this.md5 = md5;
        }
    }
}
 
inter包:

ApiService类:

public interface ApiService {

    @GET("api/checkversion.php")
    Observable<DateBean> getData();




}
Service类:

public class ServiceUrl {
    public static final String BASE_URL="http://www.xieast.com/";

}

IPresenter类:

public interface IPresenter<T> {
    void OnReceiver(T t);
}
IView类:

public interface IView<T> {
    void OnSuccess(T t);
}
model层:

DateModel类:

public class DateModel {
    IPresenter iPresenter;
    public DateModel(IPresenter iPresenter){
        this.iPresenter=iPresenter;
    }
    public void getData(){
        HttpUtils.getInstance().getService()
                .getData()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<DateBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(DateBean dateBean) {

                        iPresenter.OnReceiver(dateBean);
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }
}

presenter包:

DatePresenter:

public class DatePresenter implements IPresenter<DateBean> {
    IView iView;
    private DatePresenter dataPresenter;
    private DateModel dataModel;

    public DatePresenter(IView iView){
        this.iView=iView;
    }
    public void getData(){
        dataModel = new DateModel(this);
        dataModel.getData();
    }
    @Override
    public void OnReceiver(DateBean dateBean) {
        iView.OnSuccess(dateBean);
    }
}

utils包:

HttpUtils类:

public class HttpUtils {
    private static  volatile HttpUtils instance;
    private final Retrofit retrofit;

    private HttpUtils(){
        //日志拦截器
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .build();
        retrofit = new Retrofit.Builder()
                .baseUrl(ServiceUrl.BASE_URL)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
    }

        public static HttpUtils getInstance(){
        if(instance==null){
            synchronized (HttpUtils.class){
                if(null==instance){
                    instance=new HttpUtils();
                }
            }
        }
        return instance;
        }

        public ApiService getService(){
        return retrofit.create(ApiService.class);
        }
}
View层:

FileMd5Utils类:

class FileMd5Utils {
    public static String getFileMD5(File file) {
        if (!file.isFile()) {
            return null;
        }
        MessageDigest digest = null;
        FileInputStream in = null;
        byte buffer[] = new byte[1024];
        int len;
        try {
            digest = MessageDigest.getInstance("MD5");
            in = new FileInputStream(file);
            while ((len = in.read(buffer, 0, 1024)) != -1) {
                digest.update(buffer, 0, len);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        BigInteger bigInt = new BigInteger(1, digest.digest());
        return bigInt.toString(16);
    }
}

MainActivity类:

public class MainActivity extends AppCompatActivity implements IView<DateBean> {

    @BindView(R.id.btone)
    Button btone;
    private DatePresenter datePresenter;
    private ProgressDialog dialog;
    private DateBean.DataBean data;
    private boolean isMust = false;
    private File file;
    private SharedPreferences sp;
    private String url = "http://www.xieast.com/";
    private Long fileLength;
    private boolean isCoun = false;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        //判断外置存储是否挂载
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            //若挂载 则创建存放位置(SDK中)
            File externalStorageDirectory = Environment.getExternalStorageDirectory();
            String path = externalStorageDirectory.getAbsolutePath() + File.separator + "new.apk";
            file = new File(path);
            //判断文件是否存在 不存在则创建
            if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //获取一个
        sp = getSharedPreferences("version", MODE_PRIVATE);

        fileLength = sp.getLong("length", 0);

        if (fileLength != 0) {
            isCoun = true;
        } else {
            isCoun = false;
        }


        datePresenter = new DatePresenter(this);
        datePresenter.getData();
        //创建进度条弹出框
        dialog = new ProgressDialog(MainActivity.this);
        //设置进度条框式为横向
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        //设置手指触摸弹出框外,触发点击事件
        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialogInterface) {
                dialog.dismiss();
                finish();
            }
        });
        initLenter();

    }


    //设置监听方法
    private void initLenter() {
        btone.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //获取更大的新版本
                int last_version = data.getLast_version();

                try {
                    PackageManager packageManager = getPackageManager();
                    PackageInfo packageInfo = packageManager.getPackageInfo(getPackageName(), 0);

                  int i=  packageInfo.versionCode;
                  if (i<last_version){
                      AlertDialog.Builder builder=new  AlertDialog.Builder(MainActivity.this);
                      builder.setTitle("更新").setMessage("检查到最新版本");
                      //判断是否要强制更新
                      if(i<data.getLast_must_update()){
                          isMust=true;
                          Toast.makeText(MainActivity.this,"版本太需要强制更新",Toast.LENGTH_SHORT).show();
                      //设置按钮并添加点击事件监听
                          builder.setPositiveButton("立刻更新", new DialogInterface.OnClickListener() {
                              @Override
                              public void onClick(DialogInterface dialogInterface, int i) {
                                  //调用下载新版本Apk
                                  setUpdateVersion(data.getUrl(), data.getMd5());
                              }
                          })//当手指触摸到弹框之外进行监听
                                  .setOnCancelListener(new DialogInterface.OnCancelListener() {
                              @Override
                              public void onCancel(DialogInterface dialogInterface) {

                                  //关闭弹框
                                  dialog.dismiss();
                                  //关闭当前程序
                                  finish();
                              }
                          });
                      }else{
                          builder.setNegativeButton("取消",null).setPositiveButton("更新", new DialogInterface.OnClickListener() {
                              @Override
                              public void onClick(DialogInterface dialogInterface, int i) {
                                  Toast.makeText(MainActivity.this,"更新版本",Toast.LENGTH_SHORT).show();
                              }
                          });
                      }
                      AlertDialog alertDialog = builder.create();
                      alertDialog.setCanceledOnTouchOutside(!isMust);
                      alertDialog.show();
                  }else{
                      Toast.makeText(MainActivity.this,"已近是最新版本",Toast.LENGTH_SHORT).show();
                  }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
//现在APK方法
    private void setUpdateVersion(String url, final String md5){
        dialog.show();
        OkHttpClient client = new OkHttpClient();
        final Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        okhttp3.Call call = client.newCall(request);
        call.enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                long l = response.body().contentLength();
                InputStream inputStream = response.body().byteStream();

                toInputString(l,inputStream,md5);
            }
        });


    }

    private void toInputString(long l, InputStream inputStream,String md5) {
        try {

            //随机储存的类
            RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");

            //定义一个byte数据 来决定一次读取多少字节
            byte[] bytes = new byte[2048];
            //
            int len = 0;

            //获取文件的长度
            long sum = file.length();

            //将获取过文件长度的变量存入 随机储存类中,
            //当sd卡中文件长度是0是,随机储存类储存的位置也是在0
            randomAccessFile.seek(sum);

            //while循环进行读取数据
            while ((len = inputStream.read(bytes, 0, bytes.length)) != -1) {

                sum += len;
                //进行写入数据
                randomAccessFile.write(bytes, 0, len);

                //移动到当前已经下载的文件大小的位置
                randomAccessFile.seek(sum);

                //算出下载进度
                int i = (int) (sum * 100 / l);

                //为进度条赋值
                dialog.setProgress(i);

                //当进度条数大于99时进行关闭
                if (i > 99) {

                    //读取完了 需要进行关闭流
                    inputStream.close();
                    //并关闭进度条的弹框
                    dialog.dismiss();

                    //调用检测 本地文件是否还和网络文件一致
                    checkAPK(file, md5);

                    //跳出循环
                    break;
                }
            }


        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void checkAPK(File file, String md5) {
        //调用工具类 算出文件的md5值
        String fileMD5 = FileMd5Utils.getFileMD5(file);

        Log.d("--", "网络md5:---" + md5 + "--本地文件的MD5:--" + fileMD5);
        //equalsIgnoreCase 实现可以忽略大小写, 由于md5是又大小写
        //判断 文件的md5值 和网络下载的md5值 是否一致
        if (fileMD5.equalsIgnoreCase(md5)) {
            insertAPK(file);
        } else {
            Toast.makeText(this, "文件出现故障 md5值不一致", Toast.LENGTH_SHORT).show();
        }

    }

    private void insertAPK(File file) {

        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        //最好添加上这个Flag
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivityForResult(intent, 1000);
        System.exit(0);

    }

    @Override
    public void OnSuccess(DateBean dateBean) {
        data = dateBean.getData();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值