Files
Android-WaterProject/app/src/main/java/com/ckkj/water/utils/DownFileUtil.java
fengjignqi 1b1575eb8a first
2026-05-16 16:19:39 +08:00

255 lines
11 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,"图片已下载至手机");
}
}
});
}
}