content: package my.project.silisili.net;
  
  import android.os.Environment;
  import android.util.Log;
  
  import androidx.annotation.NonNull;
  
  import java.io.File;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.UnsupportedEncodingException;
  import java.net.URLDecoder;
  
  import okhttp3.Call;
  import okhttp3.Callback;
  import okhttp3.OkHttpClient;
  import okhttp3.Request;
  import okhttp3.Response;
  
  public class DownloadUtil {
      private static DownloadUtil downloadUtil;
      private final OkHttpClient okHttpClient;
      private String fileName = "";
      public static DownloadUtil get() {
          if (downloadUtil == null) {
              downloadUtil = new DownloadUtil();
          }
          return downloadUtil;
      }
  
      private DownloadUtil() {
          okHttpClient = new OkHttpClient.Builder().build();
      }
  
      public Call downloadApk(final String url, final OnDownloadListener listener) {
          Request request = new Request.Builder().url(url).get().build();
          Call call = okHttpClient.newCall(request);
          call.enqueue(new Callback() {
              @Override
              public void onFailure(Call call, IOException e) {
                  // 下载失败
                  listener.onDownloadFailed();
              }
              @Override
              public void onResponse(Call call, Response response) throws IOException {
                  InputStream is = null;
                  byte[] buf = new byte[2048];
                  int len = 0;
                  FileOutputStream fos = null;
                  // 储存下载文件的目录
  //                String savePath = isExistDir(saveDir);
                  try {
                      is = response.body().byteStream();
                      long total = response.body().contentLength();
                      Log.e("total",total+"");
                      fileName = "base.apk";
                      File file = new File(Environment.getExternalStorageDirectory(), fileName);
                      fos = new FileOutputStream(file);
                      long sum = 0;
                      while ((len = is.read(buf)) != -1) {
                          fos.write(buf, 0, len);
                          sum += len;
                          int progress = (int) (sum * 1.0f / total * 100);
                          // 下载中
                          listener.onDownloading(progress);
                      }
                      fos.flush();
                      // 下载完成
                      listener.onDownloadSuccess(fileName);
                  } catch (Exception e) {
                      listener.onDownloadFailed();
                  } finally {
                      try {
                          if (is != null)
                              is.close();
                      } catch (IOException e) {
                      }
                      try {
                          if (fos != null)
                              fos.close();
                      } catch (IOException e) {
                      }
                  }
              }
          });
          return call;
      }
  
      /**
       * @param saveDir
       * @return
       * @throws IOException
       * 判断下载目录是否存在
       */
      private String isExistDir(String saveDir) throws IOException {
          // 下载位置
          File downloadFile = new File(Environment.getExternalStorageDirectory(), saveDir);
          if (!downloadFile.mkdirs()) {
              downloadFile.createNewFile();
          }
          String savePath = downloadFile.getAbsolutePath();
          return savePath;
      }
  
      /**
       * 获取response header中Content-Disposition中的filename值
       * @param response
       * @return
       */
      private static String getFileName(Response response) {
          String contentHeader = response.header("Content-Disposition");
          try {
              contentHeader = URLDecoder.decode(contentHeader, "UTF-8");
          } catch (UnsupportedEncodingException e) {
              e.printStackTrace();
          }
          contentHeader = contentHeader.replaceAll("attachment;filename=","");
          return contentHeader;
      }
  
      /**
       * @param url
       * @return
       * 从下载连接中解析出文件名
       */
      @NonNull
      private String getNameFromUrl(String url) {
          return url.substring(url.lastIndexOf("/") + 1);
      }
  
      public interface OnDownloadListener {
          /**
           * 下载成功
           */
          void onDownloadSuccess(String fileName);
  
          /**
           * @param progress
           * 下载进度
           */
          void onDownloading(int progress);
  
          /**
           * 下载失败
           */
          void onDownloadFailed();
      }
  }
  