(安卓) 版本更新

第一步,通过接口获取更新信息(版本号、更新内容、apk下载地址、是否强制更新)
第二步,通过接口拿到的版本号和本地的版本号进行比较,如果拿到的版本号比本地的版本号大,那就进行版本升级
第三步,版本升级分为三种情况:


1、非wifi情况下,弹出版本更新提示框,用户点击“立即升级”按钮开始下载apk,下载完成后提示安装。
2、wifi情况下,直接后台下载apk,下载完后弹出版本更新提示框,用户点击“立即安装”按钮开始安装apk。

3、强制更新为true的时候,无论是否wifi情况下,都是应该弹出更新提示框,用户点击“立即升级”按钮开始下载升级,提示框不能取消,点击“关闭”按钮直接退出app。



基本思路就是以上,接下来进入主题:



版本号:   红框里面是版本号 ,为了进行测验代码   ,版本号可更改

上代码:

MainActivity 类:
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.SeekBar;

import java.io.File;
import java.util.HashMap;

import bwie.com.day_update_1227.bean.Update;
import bwie.com.day_update_1227.http.VersionUtils;
import bwie.com.day_update_1227.presenter.UpDatePresenter;
import bwie.com.day_update_1227.view.DownLoadListener;
import bwie.com.day_update_1227.view.IView;

public class MainActivity extends AppCompatActivity implements IView{

    private static final String TAG = "MainActivity";
    private String url="http://www.wuxirui.com/";
    private Update.ResultBean result;
    private String path = "/download/";
    private UpDatePresenter upDatePresenter;
    private SeekBar seekBar;
    private ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        progressBar = (ProgressBar)findViewById(R.id.progressBar3);

        //使用工具类获取到自己的版本号
        String versionName = VersionUtils.getVersionName(this);
        //判断是否挂载
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            File externalStorageDirectory = Environment.getExternalStorageDirectory();
            // /sdcard/download/
            String absolutePath = externalStorageDirectory.getAbsolutePath();
            path = absolutePath + path;
        }

        HashMap<String,String> map = new HashMap<>();
        map.put("version",versionName);
        upDatePresenter = new UpDatePresenter();
        upDatePresenter.attachView(this);
        upDatePresenter.getUpdate(url,map);
    }

    @Override
    public void success(Object o) {
        if (o instanceof Update){
            Update news= (Update) o;
            if (news!=null){
               //请求成功   isSuccess  成功:true  。失败:false
                 if(news.isSuccess()){
                     result = news.getResult();
                    //有更新    isHas_new_version  更新
                     if (result.isHas_new_version()){
                         //isMust_update  强制更新
                         boolean isMust = result.isMust_update();
                         //显示对话框
                         AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                         builder.setTitle("更新提示")
                                 //使用三元运算判断强制更新是否为true或者fales
                                 .setMessage(isMust ? "需要立即跟新":"是否需要跟新")
                                 .setPositiveButton("更新", new DialogInterface.OnClickListener() {
                                     @Override
                                     public void onClick(DialogInterface dialogInterface, int i) {
                                         String url = result.getUrl();
                                         //contains :包含
                                         if (url.contains(".")){
                                             String typeName = url.substring(url.lastIndexOf(".") + 1);
                                             if (url.contains("/")){
                                                 String filename = url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("."));
                                                 path = path + filename + "." + typeName;
                                             }
                                         }
                                         //下载
                                  download(result.getUrl(), new File(path), new DownLoadListener() {
                                             @Override
                                             public void success(String path) {
                                                 Log.i(TAG, "success: " + path);
                                                 // 启动自动安装
                                                 installApk(new File(path));
                                             }

                                             @Override
                                             public void failes(Exception e) {
                                                 Log.e(TAG, "failed: " + e.getMessage());
                                             }

                                             @Override
                                             public void progress(long progress) {
                                                 Log.i(TAG, "progress: " + progress);
                                                 //设置进度条
                                                 progressBar.setProgress((int) progress);
                                             }
                                         });
                                     }
                                 });
                         //如果强制更新为false就走以下
                         if (!isMust){
                             builder.setNegativeButton("稍候", new DialogInterface.OnClickListener() {
                                 @Override
                                 public void onClick(DialogInterface dialogInterface, int i) {

                                 }
                             });
                         }
                         builder.create().show();
                     }

                }


            }
        }

    }

    @Override
    public void failes(Exception e) {

    }
    private void download(String url, File file, DownLoadListener listener){
        upDatePresenter.download(url,file,listener);
    }
    /**
     * 安装apk
     * @param file
     */
    private void installApk(File file) {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.addCategory("android.intent.category.DEFAULT");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        startActivity(intent);
        android.os.Process.killProcess(android.os.Process.myPid());
    }
}

view 视图接口:
 
public interface IView {

    void success(Object o);
    void failes(Exception e);
}

public interface DownLoadListener {
    void success(String path);
    void failes(Exception e);
    void progress(long progress);
}

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

Presenter层:
import android.os.Handler;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import bwie.com.day_update_1227.bean.Update;
import bwie.com.day_update_1227.model.IModel;
import bwie.com.day_update_1227.model.UpDateModel;
import bwie.com.day_update_1227.view.DownLoadListener;
import bwie.com.day_update_1227.view.IView;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subscribers.DisposableSubscriber;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * Created by 迷人的脚毛!! on 2017/12/27.
 */

public class UpDatePresenter implements  IPresenter {


    private Handler handler=new Handler();

    private static final String TAG = "UpDatePresenter";

    private IView iv;
    private DisposableSubscriber<Update> disposableSubscriber;

    public void attachView(IView iv) {
        this.iv = iv;
    }
    public void delete(){
        if (iv!=null){
            iv=null;
        }
        if (disposableSubscriber!=null){
            if (disposableSubscriber.isDisposed()){
                disposableSubscriber.dispose();
            }
        }
    }

    @Override
    public void getUpdate(String url, Map<String,String> map) {
        IModel model=new UpDateModel(this);
        model.getUpdate(url,map);

    }


    public void getUpdates(Flowable<Update> flowable){
        disposableSubscriber = flowable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(new DisposableSubscriber<Update>() {
                    @Override
                    public void onNext(Update update) {
                        if (update!=null){

                            iv.success(update);
                            Log.i(TAG, "p层: "+update.getMessage());


                        }

                    }

                    @Override
                    public void onError(Throwable t) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    public void download(String url, final File file, final DownLoadListener listener){
        // 父目录是否存在
        File parent = file.getParentFile();
        if (!parent.exists()) {
            parent.mkdir();
        }
        // 文件是否存在
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .build();

        Call call = client.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        listener.failes(e);
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                ResponseBody body = response.body();
                // 获取文件总长度
                long totalLength = body.contentLength();
                try {
                    InputStream is = body.byteStream();
                    FileOutputStream fos = new FileOutputStream(file);
                    byte[] buf = new byte[2048];
                    int length = 0;
                    int sum = 0;
                    while ((length = is.read(buf, 0, buf.length)) != -1) {
                        sum += length;
                        long progress = sum * 100 / totalLength;
                        listener.progress(progress);
                        fos.write(buf, 0, length);
                    }
                    fos.flush();
                    is.close();
                    fos.close();
                    listener.success(file.getAbsolutePath());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });


    }
}


接口:
public interface IPresenter {
    void getUpdate(String url, Map<String,String> map);

}

================================================================================
Model层:
public class UpDateModel implements IModel {

    private UpDatePresenter presenter;

    public UpDateModel(UpDatePresenter presenter) {
        this.presenter = presenter;
    }

    @Override
    public void getUpdate(String url,Map<String,String> map) {

        Flowable<Update> flowable = RetrofirUtil.getInsterent(url).getApiService().getUpdate(map);

        presenter.getUpdates(flowable);
    }


}
public interface IModel {

    void getUpdate(String url, Map<String,String> map);

}
====================================================================
接下来就是工具类:
ApiService:
public interface ApiService {
    //http://www.wuxirui.com/api/checkversion.php
    @GET("api/checkversion.php")
    Flowable<Update> getUpdate(@QueryMap Map<String,String> map);
}

RetrofirUtil类:
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

 

public class RetrofirUtil {

    private static volatile RetrofirUtil insterent;
    private final ApiService apiService;

    private RetrofirUtil(String url) {

        Retrofit retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(url)
                .build();

        apiService = retrofit.create(ApiService.class);
    }


    public static RetrofirUtil getInsterent(String url){
        if (null==insterent){
            synchronized (RetrofirUtil.class){
                if (insterent==null){
                    insterent=new RetrofirUtil(url);
                }
            }
        }
        return insterent;
    }
    public ApiService getApiService(){
        return  apiService;
    }
}

VersionUtils 类:
public class VersionUtils {
    public static String getVersionName(Context context) {
        String versionName = "";
        //拿到包管理器
        PackageManager packageManager = context.getPackageManager();
        //拿到包名
        String packageName = context.getPackageName();

        try {
            PackageInfo packageInfo = packageManager.getPackageInfo(packageName, 0);
            //版本号
            versionName = packageInfo.versionName;

        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return versionName;

    }
}

=========================================================
封装类:
public class Update {

    /**
     * success : true
     * message : 有可用的更新
     * result : {"has_new_version":true,"must_update":true,"url":"http://www.wuxirui.com/download/jinritoutiao.apk"}
     */

    private boolean success;
    private String message;
    private ResultBean result;

    public boolean isSuccess() {
        return success;
    }

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

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public ResultBean getResult() {
        return result;
    }

    public void setResult(ResultBean result) {
        this.result = result;
    }

    public static class ResultBean {
        /**
         * has_new_version : true
         * must_update : true
         * url : http://www.wuxirui.com/download/jinritoutiao.apk
         */

        private boolean has_new_version;
        private boolean must_update;
        private String url;

        public boolean isHas_new_version() {
            return has_new_version;
        }

        public void setHas_new_version(boolean has_new_version) {
            this.has_new_version = has_new_version;
        }

        public boolean isMust_update() {
            return must_update;
        }

        public void setMust_update(boolean must_update) {
            this.must_update = must_update;
        }

        public String getUrl() {
            return url;
        }

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


这样就可以简单的实现一个版本更新具体逻辑可以根据实际要求进行嵌套,在这个版本更新中,我用到了okhttp解析,
还有Retrofit+Rxjava解析,因为开始想直接用 Retrofit+Rxjava 进行解析的可后来在下载新版本apk时不得不使用okhttp来进行
解析,具体可以在写的时候体会!!!下一篇文章我会写断点续传,版本更新和断点续传有着密不可分的关系,为了更清晰,所以
分开写。
用到的依赖:

compile "io.reactivex.rxjava2:rxjava:2.1.1"
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
compile 'com.squareup.okhttp3:okhttp:3.9.1'



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值