Android中版本强制更新

借鉴:http://www.cnblogs.com/shmilyGWT/p/8177961.html,这个有是否强制更新的选择,我简单的修改了一部分逻辑,看你的业务逻辑了,也就是增加一个参数来判断取消按钮是否显示,点击确认是否下载。

 一、工具类

public class UpdateManager {
    private Context mContext; //上下文
    private String apkUrl; //apk下载地址
    private List<String> list; //更新内容
    private static final String savePath = "/sdcard/updateAPK/"; //apk保存到SD卡的路径
    private static final String saveFileName = savePath + "app_feizufenqi.apk"; //完整路径名
    private static final int DOWNLOADING = 1; //表示正在下载
    private static final int DOWNLOADED = 2; //下载完毕
    private static final int DOWNLOAD_FAILED = 3; //下载失败
    private ProgressBar mProgress; //下载进度条控件
    private int progress; //下载进度
    private boolean cancelFlag = false; //取消下载标志位
    private AlertDialog alertDialog1; //表示提示对话框、进度条对话框

    /** 构造函数 */
    public UpdateManager(Context context,String apkUrl, List list) {
        this.mContext = context;
        this.apkUrl = apkUrl;
        this.list = list;
    }

    /** 显示更新对话框 */
    public void showNoticeDialog(double serverVersion,double clientVersion) {
        //如果版本最新,则不需要更新
        if (serverVersion <= clientVersion)
            return;
        AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View view = inflater.inflate(R.layout.softupdate_progress, null);
        mProgress = view.findViewById(R.id.update_progress);
        ListView lv = view.findViewById(R.id.lv);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext,R.layout.list_item,list);
        lv.setAdapter(adapter);
        view.findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mProgress.setVisibility(View.VISIBLE);
                //下载apk
                downloadAPK();
            }
        });
        dialog.setView(view);
        alertDialog1  = dialog.create();
        alertDialog1.setCancelable(false);
        alertDialog1.show();
    }

    /** 下载apk的线程 */
    public void downloadAPK() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL url = new URL(apkUrl);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    // 设置连接主机超时时间
                    conn.setConnectTimeout(5 * 1000);
                    //设置从主机读取数据超时
                    conn.setReadTimeout(5 * 1000);
                    // 设置是否使用缓存  默认是true
//                    conn.setUseCaches(true);
                    // 设置为Post请求
                    conn.setRequestMethod("GET");
                    conn.connect();
                    if (conn.getResponseCode() == 200) {
                        int length = conn.getContentLength();
                        InputStream is = conn.getInputStream();
                        File file = new File(savePath);
                        if (!file.exists()) {
                            file.mkdir();
                        }
                        String apkFile = saveFileName;
                        File ApkFile = new File(apkFile);
                        FileOutputStream fos = new FileOutputStream(ApkFile);
                        int count = 0;
                        byte buf[] = new byte[1024];

                        do {
                            int numread = is.read(buf);
                            count += numread;
                            progress = (int) (((float) count / length) * 100);
                            //更新进度
                            mHandler.sendEmptyMessage(DOWNLOADING);
                            if (numread <= 0) {
                                //下载完成通知安装
                                mHandler.sendEmptyMessage(DOWNLOADED);
                                break;
                            }
                            fos.write(buf, 0, numread);
                        } while (!cancelFlag); //点击取消就停止下载.
                        fos.close();
                        is.close();
                    }
                } catch(Exception e) {
                    mHandler.sendEmptyMessage(DOWNLOAD_FAILED);
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /** 更新UI的handler */
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case DOWNLOADING:
                    mProgress.setProgress(progress);
                    break;
                case DOWNLOADED:
                    if (alertDialog1 != null)
                        alertDialog1.dismiss();
                    installAPK();
                    break;
                case DOWNLOAD_FAILED:
                    Toast.makeText(mContext, "网络断开,请稍候再试", Toast.LENGTH_LONG).show();
                    break;
                default:
                    break;
            }
        }
    };

    /** 下载完成后自动安装apk */
    public void installAPK() {
        File apkFile = new File(saveFileName);
        if (!apkFile.exists()) {
            return;
        }

        Intent intent = new Intent(Intent.ACTION_VIEW);
        // 由于没有在Activity环境下启动Activity,设置下面的标签
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //版本在7.0以上是不能直接通过uri访问的
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致   参数3  共享的文件
            Uri apkUri = FileProvider.getUriForFile(mContext, "com.example.myversionupdate.fileprovider", apkFile);
            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        } else {
            Uri uri = Uri.fromFile(apkFile);
            intent.setDataAndType(uri, "application/vnd.android.package-archive");
        }
        mContext.startActivity(intent);

    }
}

二、使用方法

UpdateManager() mUpdateManager = new UpdateManager(SplashActivity.this, "下载地址","更新内容集合");                                        
mUpdateManager.showNoticeDialog("后台版本号", "本地版本号");

三、配置内容

1. 在res下创建一个名字为xml的文件夹,在此文件夹下创建一个名字为file_paths.xml的文件。内容如下:

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
    <paths>
        <external-path
            name="external_files"
            path="." />
        <root-path
            name="root_path"
            path="." />
    </paths>
</resources>

2. 创建一个类MyFileProvider继承FileProvider。

3.在清单文件AndroidManifest中引用MyFileProvider。

        <!-- 解决apk安装失败的问题 -->
        <provider android:name=".MyFileProvider"
            android:authorities="com.example.myversionupdate.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

四、注意事项

1. 在清单文件和工具类中的的authorities值一定是你的包名+fileprovider,不然下载失败。

2. 在使用前记得调用动态权限Manifest.permission.WRITE_EXTERNAL_STORAGE。

猜你喜欢

转载自blog.csdn.net/qq_40441190/article/details/84976131
今日推荐