Android 版本更新

摘要

版本更新这一块涉及的知识点比较少,但也花了一天时间,仅做记录用,为了方便大家理解,我画了一张流程图。需求比较简单,以后可以根据产品需求适当更改。

版本
以下版本更新工具类

/**
 * Created by minmin.shen
 * on 2019/1/23
 * 检查更新版本工具类
 */
public class UpdateManager {
    private String downLoadPath = "";
    private String url = "";//apk下载地址
    private boolean isforce = false;
    private String oldApkName = "";
    private String newApkName = "";
    private Context context;

    private BaseDialog updataDialog;
    private BaseDialog installDialog;
    private ProgressDialog progressDialog;
    private FragmentManager fm;
    public static UpdateManager updateManager;

    public static UpdateManager getInstance() {
        if (updateManager == null) {
            updateManager = new UpdateManager();
        }
        return updateManager;
    }

    public void start(){
        if(checkIsHaveNewAPK()){
            showInstallDialog("发现新版本,是否安装?");
        }else{
            showUpdataDialog();
        }
    }

    /**
     * 版本更新提示框
     */
    public void showUpdataDialog() {
        updataDialog = BaseDialog.getInstance().setTitle("提示").setContent("发现新版本,是否更新?")
                .setPositionText("取消", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        updataDialog.dismiss();
                        if (isforce) {
                            System.exit(0);
                        }
                    }
                })
                .setNegativeText("更新", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        updataDialog.dismiss();
                        createProgress(context);
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                downloadApk();
                            }
                        }).start();

                    }
                });
        updataDialog.show(fm, "dialog for update");
    }

    /**
     * 弹出安装Dialog
     */
    private void showInstallDialog(String content){
        installDialog = BaseDialog.getInstance().setTitle("提示").setContent(content)
                .setPositionText("取消", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        installDialog.dismiss();
                        if (isforce) {
                            System.exit(0);
                        }
                    }
                })
                .setNegativeText("安装", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        installDialog.dismiss();
                        File fileAPK = new File(downLoadPath, newApkName);
                        installApk(context, fileAPK);
                    }
                });
        installDialog.show(fm, "dialog for install");
    }

    /**
     * 检查有没有最新的APK
     */
    private boolean checkIsHaveNewAPK(){
        File file = new File(downLoadPath);
        if (!file.exists()) {
            file.mkdirs();
        }
        File fileAPK = new File(downLoadPath, newApkName);
        if(fileAPK.exists()){
            return true;
        }
        return false;
    }

    /**
     * 删除旧的apk
     */
    private void delOldApk(){
        File fileAPK = new File(downLoadPath, oldApkName);
        if(fileAPK.exists()){
            fileAPK.delete();
        }
    }

    /**
     * 下载APK
     */
    private void downloadApk() {
        try {
            final long startTime = System.currentTimeMillis();
            Log.i("DOWNLOAD", "startTime=" + startTime);
            //获取文件名
            URL myURL = new URL(url);
            URLConnection conn = myURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            int fileSize = conn.getContentLength();//根据响应获取文件大小
            Log.i("DOWNLOAD", "总大小="+fileSize);
            if (fileSize <= 0) throw new RuntimeException("无法获知文件大小 ");
            if (is == null) throw new RuntimeException("stream is null");
            File file1 = new File(downLoadPath);
            if (!file1.exists()) {
                file1.mkdirs();
            }
            //把数据存入路径+文件名
            FileOutputStream fos = new FileOutputStream(downLoadPath + "/" + newApkName);
            byte buf[] = new byte[1024];
            int downLoadFileSize = 0;
            do {
                //循环读取
                int numread = is.read(buf);
                if (numread == -1) {
                    break;
                }
                fos.write(buf, 0, numread);
                downLoadFileSize += numread;
                Log.i("DOWNLOAD", "downLoadFileSize="+downLoadFileSize);
                Log.i("DOWNLOAD", "fileSize="+fileSize);
                Log.i("DOWNLOAD", "download downLoadFileSize="+(int)((float)downLoadFileSize*100/fileSize));
                progressDialog.setProgress((int)((float)downLoadFileSize*100/fileSize));
                //更新进度条
            } while (true);
            delOldApk();
            progressDialog.dismiss();
            showInstallDialog("下载完成,是否安装?");
            Log.i("DOWNLOAD", "download success");
            Log.i("DOWNLOAD", "totalTime=" + (System.currentTimeMillis() - startTime));
            is.close();
        } catch (Exception ex) {
            Log.e("DOWNLOAD", "error: " + ex.getMessage(), ex);
        }
    }

    /**
     * 强制更新时显示在屏幕的进度条
     */
    private void createProgress(Context context) {
        progressDialog = new ProgressDialog(context);
        progressDialog.setMax(100);
        progressDialog.setCancelable(false);
        progressDialog.setMessage("正在下载...");
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.show();
    }

    /**
     * 安装apk
     */
    private void installApk(Context context, File file) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        //判断是否是AndroidN以及更高的版本
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Uri contentUri = FileProvider.getUriForFile(context, "com.baozun.book.fileProvider", file);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        }
        context.startActivity(intent);
    }

    /**
     * apk网络地址
     */
    public UpdateManager setContext(Context context) {
        this.context = context;
        return this;
    }

    /**
     * apk网络地址
     */
    public UpdateManager setUrl(String url) {
        this.url = url;
        return this;
    }

    /**
     * 新版本文件名
     */
    public UpdateManager setNewFileName(String fileName) {
        this.newApkName = fileName;
        return this;
    }

    /**
     * 旧版本文件名
     */
    public UpdateManager setOldFileName(String fileName) {
        this.oldApkName = fileName;
        return this;
    }

    /**
     * Fragment管理器
     */
    public UpdateManager setFragmentManager(FragmentManager fm) {
        this.fm = fm;
        return this;
    }

    /**
     * 下载路径
     */
    public UpdateManager setDownloadPath(String downLoadPath) {
        this.downLoadPath = downLoadPath;
        return this;
    }

    /**
     * 是否强制更新
     */
    public UpdateManager setIsforce(boolean isforce) {
        this.isforce = isforce;
        return this;
    }

}

下面是发起调用

public static void checkUpdate(Context context, android.support.v4.app.FragmentManager fm, float versionCode, String url, boolean isForced) {
   if (versionCode > Float.parseFloat(Util.getCurrentVersionName(context))) {
      String downLoadPath = context.getExternalFilesDir(null).toString() + "/download/";
           String newFileName = "U_Reading"+versionCode+".apk";
      String oldFileName = "U_Reading"+Float.parseFloat(Util.getCurrentVersionName(context))+".apk";

      //设置参数
      UpdateManager.getInstance()
            .setContext(context)
            .setFragmentManager(fm)
            .setDownloadPath(downLoadPath)
            .setNewFileName(newFileName)
            .setOldFileName(oldFileName)
            .setUrl(url)
            .setIsforce(isForced)
            .start();
   }
}

其中安装apk需要注意下,在manifest文件中加入代码

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.baozun.book.fileProvider"
    android:grantUriPermissions="true"
    android:exported="false">
             
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths"/>
</provider>

在这里插入图片描述
在资源文件中加入

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="files_root"
        path="Android/data/com.baozun.book/" />
                 
    <external-path
        name="external_storage_root"
        path="." />
</paths>

先简单写一下,待详细整理

---------------------------------------------------------------2019/4/16号更新----------------------------------------------------------------

近期发现代码安装APK的时候,在华为手机上不会弹出安装界面

需要在清单文件中配置权限

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值