本文基于OKGO3.0.4版本编写

首先导入依赖

implementation 'com.lzy.net:okgo:3.0.4'

一.okgo跳过https验证

1.导入自定义SSLSocketClient类

public class SSLSocketClient {

    //获取这个SSLSocketFactory
    public static SSLSocketFactory getSSLSocketFactory() {
        try {
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, getTrustManager(), new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //获取TrustManager
    private static TrustManager[] getTrustManager() {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[]{};
                    }
                }
        };
        return trustAllCerts;
    }

    //获取HostnameVerifier
    public static HostnameVerifier getHostnameVerifier() {
        HostnameVerifier hostnameVerifier = new HostnameVerifier() {
            @Override
            public boolean verify(String s, SSLSession sslSession) {
                return true;
            }
        };
        return hostnameVerifier;
    }
}

2.在Application里配置

OkHttpClient  build = new OkHttpClient.Builder()
                .sslSocketFactory(SSLSocketClient.getSSLSocketFactory())
                .hostnameVerifier(SSLSocketClient.getHostnameVerifier())
                .build();
          //初始化okgo并配置给httpclient
        OkGo.getInstance().init(this).setOkHttpClient(build);

至此https配置完毕了就

接下来就去请求文件吧  

二:OKGO下载文件(本文下载的是一个apk文件)

final String destfiledir = Environment.getExternalStorageDirectory().getPath() + "/OAdownload";//下载路径
             final    String destfilename = "OA.apk";//文件名
                
                        OkGo
.tag("Download tips")//添加标记  用于取消单个请求    取消: OkGo.getInstance().cancelTag("Download tips");
                        .<File>get("http://immobile.r93535.com:8086/LN/GetExtApp/extapp/ExtApp/A/1111/LatestVersion")
                        .execute(new FileCallback(destfiledir, destfilename) {
                            @Override
                            public void onStart(Request<File, ? extends Request> request) {
                                super.onStart(request);
                                Log.e("gogogo", "正在加载中");
                            }

                            @Override
                            public void downloadProgress(Progress progress) {
                                super.downloadProgress(progress);
                                long totalSize = progress.totalSize;//总长度
                                long currentSize = progress.currentSize;//本次下载的大小
                                //进度条
                                progressBar.setMax((int) totalSize);
                                progressBar.setProgress((int) currentSize);
                               

                                textView.setText(String.valueOf(progress.fraction * 100 + "%"));  //下载进度
                            }

                            @Override
                            public void onError(Response<File> response) {
                                super.onError(response);
                                Log.e("gogogo", "下载出错");
                               
                            }

                            @Override
                            public void onSuccess(Response<File> response) {
                                Log.e("gogogo", "下载成功");
                                  // 安装apk
                                install(destfiledir + destfilename);
                            }

                            @Override
                            public void onFinish() {
                                super.onFinish();
                                Log.e("gogogo", "结束");

                            }
                        });

三:安装apk

开始安装apk:

File apkFile = new File(filePath);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
 startActivity(intent);

注意:在android 7.0之前这样写没有一点瑕疵,但是随着Android 7.0的到来引入“私有目录被限制访问”,“StrictMode API 政策”,为了进一步提高私有文件的安全性,Android不再由开发者放宽私有文件的访问权限,之前我们一直使用”file:///”绝对路径来传递文件地址的方式,在接收方访问时很容易触发SecurityException的异常。

因此,为了更好的适配Android 7.0,例如相机拍照这类涉及到文件地址传递的地方就用上了FileProvider,FileProvider也更好地进入了大家的视野。

不多bb,看代码!

1.首先在manifest里面配置provider(跟activity同级)

<provider
                android:name="android.support.v4.content.FileProvider"
                android:authorities="你的包名.fileprovider"
                android:exported="false"
                android:grantUriPermissions="true">
                <meta-data
                    android:name="android.support.FILE_PROVIDER_PATHS"
                    android:resource="@xml/file_paths" />
            </provider>

2.在res文件下建立xml文件夹然后建立file_paths文件

<resources>
    <paths>
        <external-path
            name="OA.apk"
            path="/OAdownload" />
    </paths>
</resources>

path就是文件路径,那么是文件名字  然后external-path就相当于Environment.getExternalStorageDirectory() 。 

别的路径可以参考下图:

files-path

Context.getFilesDir()

cache-path

Context.getCacheDir()

external-path

Environment.getExternalStorageDirectory()

external-files-path

Context.getExternalFilesDir(null)

external-cache-path

Context.getExternalCacheDir()

3.开始安装

private void install(String filePath) {
        Log.i("file", "开始执行安装: " + filePath);
        File apkFile = new File(filePath);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Log.w("file", "版本大于 N ,开始使用 fileProvider 进行安装");
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(
                    this
                    , "com.example.duqianlong.okdownladdemo.fileprovider"
                    , apkFile);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            Log.w("file", "正常进行安装");
            intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
        }
        startActivity(intent);
    }

至此差不多就大功告成了,当然权限是少不了的

4.添加权限(因为不是危险权限,所以不需要动态申请,添加到manifest里面就行)

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

读写权限&网络权限 是少不了的,当然这个就需要动态申请了,这个可以参考以前的博客

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />