package com.ckkj.water.utils; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.net.Uri; import android.os.Build; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; import com.ckkj.water.utils.show.ToastUtil; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class DownFileUtil { private DownFileCallback mCallback; public interface DownFileCallback{ void downSuccess(String msg); } public DownFileUtil(Context context,String fileUrl,DownFileCallback callback) { new Thread(){ @Override public void run() { super.run(); String fileName = null; try { // 找到最后一个"/"的位置 int lastSlashIndex = fileUrl.lastIndexOf("/"); int firstQuestionIndex = -1; fileName = ""; if(fileUrl.contains("?")){ firstQuestionIndex = fileUrl.indexOf("?"); fileName = fileUrl.substring(lastSlashIndex + 1,firstQuestionIndex); }else{ // 截取最后一个"/"之后的内容 fileName = fileUrl.substring(lastSlashIndex + 1); } } catch (Exception e) { } // 检查 Android 版本 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // 1. 获取公共下载目录的 URI(适用于 Android 10 及以上) Uri downloadUri = getDownloadDirectoryUri(); // 2. 获取 "ChaoYueCang" 文件夹的路径 Uri folderUri = getFolderUri(downloadUri, "ChaoYueCang"); if (folderUri == null) { // 文件夹不存在,创建该文件夹 createFolderInDownloads(downloadUri, context,"ChaoYueCang"); } // 1. 获取 MediaStore 的下载目录 URI ContentResolver resolver = context.getContentResolver(); Uri collection = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); // 2. 创建用于保存文件的 ContentValues ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName); // 文件名 values.put(MediaStore.MediaColumns.MIME_TYPE, getMimeType(fileName)); // 根据文件扩展名设置 MIME 类型 values.put(MediaStore.MediaColumns.RELATIVE_PATH, "Download/ChaoYueCang"); // 保存到 Downloads 目录 // 3. 使用 resolver 插入文件 Uri fileUri = resolver.insert(collection, values); if (fileUri == null) { Log.e("FileDownload", "Failed to create new file in Downloads directory."); return; } File sourceFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/ChaoYueCang/"+ fileName); String sourceFilePath = sourceFile.getAbsolutePath(); // 4. 打开输出流,将文件内容写入公共 Downloads 目录 try (InputStream inputStream = downloadFileFromUrl(fileUrl); OutputStream outputStream = resolver.openOutputStream(fileUri)) { if (outputStream == null) { Log.e("FileDownload", "Failed to open output stream for file."); return; } byte[] buffer = new byte[8192]; // 缓冲区 int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.close(); inputStream.close(); callback.downSuccess("成功下载至Download文件目录中"); } catch (IOException e) { Log.e("FileDownload", "Error writing to file", e); } } else { // 1. 获取公共下载目录路径 File downloadsDirectory = new File(Environment.getExternalStorageDirectory(), "Download/ChaoYueCang"); if (!downloadsDirectory.exists()) { downloadsDirectory.mkdirs(); // 如果目录不存在,创建目录 } // 2. 创建目标文件路径 File targetFile = new File(downloadsDirectory, fileName); // 3. 下载文件并保存到公共下载目录 try (InputStream inputStream = downloadFileFromUrl(fileUrl); OutputStream outputStream = new FileOutputStream(targetFile)) { byte[] buffer = new byte[4096]; // 缓冲区 int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } outputStream.close(); inputStream.close(); callback.downSuccess("成功下载至Download文件目录中"); } catch (IOException e) { Log.e("FileDownload", "Error downloading file", e); } } } }.start(); } // 获取文件的 MIME 类型 private String getMimeType(String fileName) { if (fileName.endsWith(".xlsx")) { return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; } else if (fileName.endsWith(".xls")) { return "application/vnd.ms-excel"; }else if (fileName.endsWith(".doc")) { return "application/msword"; }else if (fileName.endsWith(".pdf")) { return "application/pdf"; }else if (fileName.endsWith(".png")) { return "image/png"; }else if (fileName.endsWith(".jpg")) { return "image/jpeg"; }else if (fileName.endsWith(".jpeg")) { return "image/jpeg"; } return "application/octet-stream"; // 默认 MIME 类型 } // 从 URL 下载文件并返回输入流 private InputStream downloadFileFromUrl(String fileUrl) throws IOException { URL url = new URL(fileUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(10000); // 设置连接超时 connection.setReadTimeout(10000); // 设置读取超时 connection.connect(); return new BufferedInputStream(connection.getInputStream()); } // 获取公共存储的 Downloads 目录 URI(适配 Android 10 及以上) private Uri getDownloadDirectoryUri() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { return MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); } else { return Uri.parse("file://" + Environment.getExternalStorageDirectory() + "/Download"); } } // 获取指定文件夹的 URI private Uri getFolderUri(Uri baseUri, String folderName) { Uri folderUri = baseUri.buildUpon().appendPath(folderName).build(); File folder = new File(folderUri.getPath()); if (folder.exists()) { return folderUri; } else { return null; } } // 在 Downloads 目录中创建一个新文件夹 private void createFolderInDownloads(Uri baseUri, Context context, String folderName) { try { ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.DISPLAY_NAME, folderName); values.put(MediaStore.MediaColumns.RELATIVE_PATH, "Download/" + folderName); ContentResolver resolver = context.getContentResolver(); Uri folderUri = resolver.insert(baseUri, values); if (folderUri == null) { } else { } } catch (Exception e) { } } public static void downloadImage(Context context, String imageUrl) { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url(imageUrl) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); // 失败处理 } @Override public void onResponse(Call call, Response response) throws IOException { if (!response.isSuccessful()) { // 下载失败处理 return; } byte[] imageData = response.body().bytes(); // 获取图片文件名 String fileName = "IMG_" + System.currentTimeMillis() + ".jpg"; // 保存到 MediaStore ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName); values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg"); values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES + "/DingDingCar"); // 自定义子目录 values.put(MediaStore.Images.Media.IS_PENDING, 1); ContentResolver resolver = context.getContentResolver(); Uri collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY); Uri item = resolver.insert(collection, values); if (item != null) { try (OutputStream out = resolver.openOutputStream(item)) { out.write(imageData); } // 更新状态为可见 values.clear(); values.put(MediaStore.Images.Media.IS_PENDING, 0); resolver.update(item, values, null, null); ToastUtil.showShort(context,"图片已下载至手机"); } } }); } }