1.Android自动更新

1.引入模块update-lib

1.file-new-import module
在这里插入图片描述
2.选择外部模块update-lib,finish在这里插入图片描述
3.file-project struct
在这里插入图片描述

在这里插入图片描述在这里插入图片描述

3.代码集成
在这里插入图片描述

public class MyCheckUpdate {
    
    

    private UpdateURL updateURL;
    private CheckUpdate checkUpdate;
    private VersionParseInterface myVersionParse;

    private MyCheckUpdate(Activity activity) {
    
    
        //1.构造请求地址对象
        updateURL = new UpdateURL("http://192.168.43.36:8080/app/getLastVersionCode?type=1",
                "http://192.168.43.36:8080/app/getLastApp?type=1");
        //2.重写自定义版本解析接口
        myVersionParse = new VersionParseInterface() {
    
    
            /**
             * 解析版本信息并返回服务器上最新的版本号
             * @param newVersionStr 通过调用服务器接口返回的String类型app版本信息
             * @return
             * @throws Exception
             */
            @Override
            public int getNewVersionCode(String newVersionStr) throws Exception {
    
    
                Gson gson = MyGsonBuilder.getInstance().createGsonBuilder().create();
                ResponseInfoObj<APPVersion> appVersion = gson.fromJson(newVersionStr, new TypeToken<ResponseInfoObj<APPVersion>>() {
    
    
                }.getType());
                if (appVersion.getCode() == 200) {
    
    
                    return appVersion.getData().getVersionCode();
                } else {
    
    
                    throw new Exception(appVersion.getMsg());
                }
            }

            /**
             *  解析版本信息并返回服务器上版本描述信息
             * @param newVersionStr 通过调用服务器接口返回的String类型app版本信息
             * @return
             */
            @Override
            public List<String> getDesc(String newVersionStr) {
    
    
                List<String> ret = new ArrayList<>();
                Gson gson = MyGsonBuilder.getInstance().createGsonBuilder().create();
                ResponseInfoObj<APPVersion> appVersion = gson.fromJson(newVersionStr, new TypeToken<ResponseInfoObj<APPVersion>>() {
    
    
                }.getType());

                String desc = appVersion.getData().getRemark();
                if (null != desc && !("").equals(desc)) {
    
    
                    for (String item : desc.split(";")) {
    
    
                        ret.add(item);
                    }
                }
                return ret;
            }

            /**
             * 升级过程中出现错误问题的回调
             * @param errMsg
             */
            @Override
            public void checkError(String errMsg) {
    
    
                Toast.makeText(activity, "更新版本时遇到问题:" + errMsg, Toast.LENGTH_LONG).show();
            }

            /**
             * 用户取消升级回调
             */
            @Override
            public void checkCancel() {
    
    
                Toast.makeText(activity, "请及时更新版本,否则无法使用", Toast.LENGTH_LONG).show();
            }

            /**
             * 不需要升级回调
             */
            @Override
            public void checkNoUpdate() {
    
    
                Toast.makeText(activity, "已是最新版本,不需要更新", Toast.LENGTH_LONG).show();
            }
        };
        //3.构造CheckUpdate主类
        checkUpdate = new CheckUpdate(activity, updateURL, myVersionParse);
    }

    //4.请求更新
    public void check(UpdateStyle style) {
    
    
        this.checkUpdate.check(style);
    }

}

附录1:依赖及基础类
1.引入gson
在这里插入图片描述
2.MyGsonBuilder.java


```java
import com.google.gson.GsonBuilder;

public class MyGsonBuilder {
    private static MyGsonBuilder instance;
    private GsonBuilder builder;

    private MyGsonBuilder() {
        builder = new GsonBuilder();
        builder.setDateFormat("yyyy-MM-dd HH:mm:ss");
    }

    public static MyGsonBuilder getInstance() {
        if (instance == null) {
            instance = new MyGsonBuilder();
        }
        return instance;
    }

    public GsonBuilder createGsonBuilder() {
        return instance.builder;
    }

}
3.APPVersion.java

public class APPVersion  {
    
    
    /**
     * id
     */
    private Integer id;

    /**
     * 程序类型
     */
    private String appType;

    /**
     * 版本号
     */
    private Integer versionCode;

    /**
     * apk内容
     */
    private byte[] apk;

    /**
     * 是否启用
     */
    private String enable;

    /** 备注 */
    private String remark;

    public Integer getId() {
    
    
        return id;
    }

    public void setId(Integer id) {
    
    
        this.id = id;
    }

    public String getAppType() {
    
    
        return appType;
    }

    public void setAppType(String appType) {
    
    
        this.appType = appType;
    }

    public Integer getVersionCode() {
    
    
        return versionCode;
    }

    public void setVersionCode(Integer versionCode) {
    
    
        this.versionCode = versionCode;
    }

    public byte[] getApk() {
    
    
        return apk;
    }

    public void setApk(byte[] apk) {
    
    
        this.apk = apk;
    }

    public String getEnable() {
    
    
        return enable;
    }

    public void setEnable(String enable) {
    
    
        this.enable = enable;
    }

    public String getRemark() {
    
    
        return remark;
    }

    public void setRemark(String remark) {
    
    
        this.remark = remark;
    }

    @Override
    public String toString() {
    
    
        return "APPVersion{" +
                "id=" + id +
                ", appType='" + appType + '\'' +
                ", versionCode=" + versionCode +
                ", apk=" + Arrays.toString(apk) +
                ", enable='" + enable + '\'' +
                ", remark='" + remark + '\'' +
                '}';
    }
}
4.ResponseInfoObj

```java
import java.io.Serializable;
import java.util.List;

public class ResponseInfoObj<T> implements Serializable {

    private Integer code;
    private String msg;
    private long total;
    private T data;
    private List<T> rows;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

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

    public long getTotal() {
        return total;
    }

    public void setTotal(long total) {
        this.total = total;
    }

    public T getData() {
        return data;
    }

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

    public List<T> getRows() {
        return rows;
    }

    public void setRows(List<T> rows) {
        this.rows = rows;
    }

    @Override
    public String toString() {
        return "ResponseInfoObj{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", total=" + total +
                ", data=" + data +
                ", rows=" + rows +
                '}';
    }
}

附录2:后端服务器

 @Value("${files.path}")
    String filePath;

    @GetMapping("/getLastVersionCode")
    @ApiOperation(value = "PDA端获取最新版本号",notes="不需要登录Token")
    public AjaxResult getLastVersionCode(int type) {
    
    
        try {
    
    
            AppVersion app=appVersionService.getLastAppVersionAndDescByType(type);
            if(app!=null){
    
    
                return AjaxResult.success("查询成功",app);
            }else{
    
    
                return AjaxResult.error("未查询到版本信息");
            }
        }catch (Exception e){
    
    
            return AjaxResult.error("查询出错"+e.getMessage());

        }
    }

    @GetMapping("/getLastApp")
    @ApiOperation(value = "PDA端获取最新版本",notes="不需要登录Token")
    public ResponseEntity<byte[]> getLastApp(int type, HttpServletRequest request) {
    
    
        try {
    
    
            // 获取最新版本号
            AppVersion app=appVersionService.getLastAppVersionAndDescByType(type);
            if(app==null){
    
    
                return null;
            }
            //根据类型命名文件
            String appName="";
            List<SysDictData> dictList=dictTypeService.selectDictDataByType("app_type");
            for(SysDictData temp:dictList){
    
    
                if(temp.getDictValue().equals(app.getAppType())){
    
    
                    appName=temp.getDictLabel()+"_"+app.getVersionCode()+"_"+app.getUpdateTime().getTime();
                    break;
                }
            }

            String fullFilePath = filePath + "/"+appName;
            File f = new File(fullFilePath);
            FileOutputStream fos=null;
            BufferedOutputStream bos=null;
            FileInputStream inputStream=null;
            if (!f.exists()) {
    
    
                //处理文件夹不存在的情况
                File dir=new File(filePath);
                if(!dir.exists()){
    
    
                    dir.mkdir();
                }
                app=appVersionService.getLastAppVersionByType(type);
                fos = new FileOutputStream(f);
                bos= new BufferedOutputStream(fos);
                bos.write(app.getApk());
                bos.flush();
                HttpHeaders headers = new HttpHeaders();
                headers.setContentLength(app.getApk().length);
                headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
                headers.setContentDispositionFormData("attachment", URLEncoder.encode(appName, "UTF-8"));
                return new ResponseEntity<>(app.getApk(), headers, HttpStatus.OK);
            }else{
    
    
                inputStream=new FileInputStream(f);
                final int available = inputStream.available();
                byte[] bytes=new byte[available];
                inputStream.read(bytes);
                HttpHeaders headers = new HttpHeaders();
                headers.setContentLength(bytes.length);
                headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
                headers.setContentDispositionFormData("attachment", URLEncoder.encode(appName, "UTF-8"));
                return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
            }
        }catch (Exception e){
    
    
            return null;
        }
    }

附录3:权限

 protected void onCreate(@Nullable Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        context = this;
        initView();
        app = MyApplication.newInstance();
        switch (checkPermission()) {
    
    
            //申请权限去了,不需要做任何事
            case -1:
                break;
            //权限不够,退出
            case 0:
                Toast.makeText(context, "未申请到必要的权限,程序自动退出", Toast.LENGTH_SHORT).show();
                finish();
                break;
            //权限够了,检查升级
            case 1:
                initCheckUpdate();
                break;
        }
    }
    /**
     * 检查权限
     *
     * @return
     */
    public Integer checkPermission() {
    
    
        if (ContextCompat.checkSelfPermission(LoginActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(LoginActivity.this, Manifest.permission.INTERNET)
                == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(LoginActivity.this, Manifest.permission.READ_PHONE_STATE)
                == PackageManager.PERMISSION_GRANTED) {
    
    
            return 1;
        } else {
    
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    
    
                requestPermissions(
                        new String[]{
    
    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                Manifest.permission.READ_PHONE_STATE,
                                Manifest.permission.INTERNET
                        }, REQUEST_PERMISSION_CODE);
                return -1;
            } else {
    
    
                Log.e(TAG, "sdk版本低");
                Toast.makeText(context, "sdk版本低", Toast.LENGTH_LONG).show();
                return 0;
            }

        }

    }

猜你喜欢

转载自blog.csdn.net/qq_39312230/article/details/129182089