文件上传的逻辑001

This commit is contained in:
frank wang 2025-10-30 17:52:07 +08:00
parent f8adef2a9e
commit bc79e4176c
1 changed files with 82 additions and 50 deletions

View File

@ -260,17 +260,23 @@ public class FirstActivity extends BaseActivity {
} }
private long currentDownloadId = -1; // 保存当前下载任务ID private long currentDownloadId = -1; // 保存当前下载任务ID
/**
* 下载文件并调用系统 DownloadManager
*/
private void downloadFile(String url) { private void downloadFile(String url) {
new Thread(() -> { new Thread(() -> {
try { try {
if (TextUtils.isEmpty(url)) { if (TextUtils.isEmpty(url)) {
Toast.makeText(this, "下载地址为空", Toast.LENGTH_SHORT).show(); handler.post(() ->
Toast.makeText(this, "下载地址为空", Toast.LENGTH_SHORT).show()
);
return; return;
} }
if (url.startsWith("blob:") || url.startsWith("data:")) { if (url.startsWith("blob:") || url.startsWith("data:")) {
Toast.makeText(this, "无法直接下载 Blob 文件,请检查前端下载逻辑", Toast.LENGTH_SHORT).show(); handler.post(() ->
Toast.makeText(this, "无法直接下载 Blob 文件,请检查前端下载逻辑", Toast.LENGTH_SHORT).show()
);
return; return;
} }
@ -296,16 +302,22 @@ public class FirstActivity extends BaseActivity {
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
if (dm != null) { if (dm != null) {
Toast.makeText(this, "文件已开始下载,请等待", Toast.LENGTH_SHORT).show(); handler.post(() ->
Toast.makeText(this, "文件已开始下载,请等待", Toast.LENGTH_SHORT).show()
);
currentDownloadId = dm.enqueue(request); currentDownloadId = dm.enqueue(request);
startDownloadProgressMonitor(dm, currentDownloadId); startDownloadProgressMonitor(dm, currentDownloadId);
} else { } else {
Toast.makeText(this, "系统下载服务不可用", Toast.LENGTH_SHORT).show(); handler.post(() ->
Toast.makeText(this, "系统下载服务不可用", Toast.LENGTH_SHORT).show()
);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
Toast.makeText(this, "下载失败: " + e.getMessage(), Toast.LENGTH_SHORT).show(); handler.post(() ->
Toast.makeText(this, "下载失败: " + e.getMessage(), Toast.LENGTH_SHORT).show()
);
} }
}).start(); }).start();
} }
@ -314,48 +326,69 @@ public class FirstActivity extends BaseActivity {
* 监控下载进度每秒回调一次到前端 * 监控下载进度每秒回调一次到前端
*/ */
private void startDownloadProgressMonitor(DownloadManager dm, long downloadId) { private void startDownloadProgressMonitor(DownloadManager dm, long downloadId) {
new Thread(() -> {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadId);
boolean downloading = true;
DownloadManager.Query query = new DownloadManager.Query(); while (downloading) {
query.setFilterById(downloadId); try {
boolean downloading = true; Thread.sleep(1000);
android.database.Cursor cursor = dm.query(query);
if (cursor != null && cursor.moveToFirst()) {
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
long total = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
long downloaded = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
while (downloading) { if (status == DownloadManager.STATUS_RUNNING && total > 0) {
try { int progress = (int) ((downloaded * 100L) / total);
Thread.sleep(1000); handler.post(() -> {
android.database.Cursor cursor = dm.query(query); sendProgressToJs(progress);
if (cursor != null && cursor.moveToFirst()) { // 可选减少 toast 频率比如每 20% 提示一次
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); if (progress % 20 == 0) {
long total = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); Toast.makeText(this, "下载中:" + progress + "%", Toast.LENGTH_SHORT).show();
long downloaded = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); }
if (status == DownloadManager.STATUS_RUNNING && total > 0) { });
int progress = (int) ((downloaded * 100L) / total); } else if (status == DownloadManager.STATUS_SUCCESSFUL) {
Toast.makeText(this, "下载中,当前进度为" + progress + "%", Toast.LENGTH_SHORT).show(); downloading = false;
handler.post(() -> sendProgressToJs(progress)); handler.post(() -> {
} else if (status == DownloadManager.STATUS_SUCCESSFUL) { sendProgressToJs(100);
Toast.makeText(this, "下载完成,请到文件管理查看", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "下载完成,请到文件管理查看", Toast.LENGTH_SHORT).show();
downloading = false; });
handler.post(() -> sendProgressToJs(100)); } else if (status == DownloadManager.STATUS_FAILED) {
} else if (status == DownloadManager.STATUS_FAILED) { downloading = false;
Toast.makeText(this, "下载失败" + status + "," + total + "," + downloaded, Toast.LENGTH_SHORT).show(); handler.post(() -> {
downloading = false; sendProgressToJs(-1);
handler.post(() -> sendProgressToJs(-1)); Toast.makeText(this, "下载失败", Toast.LENGTH_SHORT).show();
});
}
cursor.close();
} }
cursor.close(); } catch (Exception e) {
e.printStackTrace();
downloading = false;
handler.post(() ->
Toast.makeText(this, "监控异常:" + e.getMessage(), Toast.LENGTH_SHORT).show()
);
} }
} catch (Exception ignored) {
Toast.makeText(this, "文件已开始下载,请等待报错", Toast.LENGTH_SHORT).show();
} }
} }).start();
} }
/**
* 向前端回调进度
*/
private void sendProgressToJs(int progress) { private void sendProgressToJs(int progress) {
try { try {
if (webView != null) { if (webView != null) {
String js = String.format("if(window.onDownloadProgress){window.onDownloadProgress(%d);}", progress); String js = String.format("if(window.onDownloadProgress){window.onDownloadProgress(%d);}", progress);
webView.evaluateJavascript(js, null); webView.evaluateJavascript(js, null);
} }
} catch (Exception ignored) { } catch (Exception e) {
Toast.makeText(this, "文件已开始下载请等待报错sendProgressToJs", Toast.LENGTH_SHORT).show(); e.printStackTrace();
handler.post(() ->
Toast.makeText(this, "进度回调异常:" + e.getMessage(), Toast.LENGTH_SHORT).show()
);
} }
} }
@ -390,35 +423,34 @@ public class FirstActivity extends BaseActivity {
} }
} }
} }
/** /**
* 上传文件到服务器 * 上传文件并在上传成功后将 fileNamedatafileSize 传给前端
*/ */
private void uploadFile(Uri uri) { private void uploadFile(Uri uri) {
new Thread(() -> { new Thread(() -> {
try { try {
// 修改为你的文件上传接口地址 // 上传接口
// String uploadUrl = "http://218.92.207.242:9678/file/upload"; // TODO: 替换为后端真实接口
String uploadUrl = "http://20.47.196.98:40080/fwzx/v1.0.0/getServiceInfoByServiceId/32092423SJNB12202507111046530001/320924230000-3-0800-5CDEC9969D674E1CBB7E2F86A697B0D7/api/file/upload"; String uploadUrl = "http://20.47.196.98:40080/fwzx/v1.0.0/getServiceInfoByServiceId/32092423SJNB12202507111046530001/320924230000-3-0800-5CDEC9969D674E1CBB7E2F86A697B0D7/api/file/upload";
String token = getToken(); // 从本地获取前端传来的 token String token = getToken();
if (TextUtils.isEmpty(token)) { if (TextUtils.isEmpty(token)) {
runOnUiThread(() -> Toast.makeText(this, "请先登录后再上传", Toast.LENGTH_SHORT).show()); runOnUiThread(() -> Toast.makeText(this, "请先登录后再上传", Toast.LENGTH_SHORT).show());
return; return;
} }
// 获取文件名 // 获取文件名
String fileName = getFileNameFromUri(uri); String fileName = getFileNameFromUri(uri);
if (TextUtils.isEmpty(fileName)) fileName = "upload_file"; if (TextUtils.isEmpty(fileName)) fileName = "upload_file";
// 读取文件内容 // 读取文件内容并计算文件大小
InputStream inputStream = getContentResolver().openInputStream(uri); InputStream inputStream = getContentResolver().openInputStream(uri);
byte[] fileBytes = new byte[inputStream.available()]; byte[] fileBytes = new byte[inputStream.available()];
inputStream.read(fileBytes); inputStream.read(fileBytes);
inputStream.close(); inputStream.close();
// 使用 OkHttp 上传 long fileSize = fileBytes.length; // 文件大小字节
// 构建 OkHttp 上传请求
okhttp3.OkHttpClient client = new okhttp3.OkHttpClient(); okhttp3.OkHttpClient client = new okhttp3.OkHttpClient();
okhttp3.RequestBody fileBody = okhttp3.RequestBody.create( okhttp3.RequestBody fileBody = okhttp3.RequestBody.create(
okhttp3.MediaType.parse("application/octet-stream"), okhttp3.MediaType.parse("application/octet-stream"),
@ -431,7 +463,7 @@ public class FirstActivity extends BaseActivity {
okhttp3.Request request = new okhttp3.Request.Builder() okhttp3.Request request = new okhttp3.Request.Builder()
.url(uploadUrl) .url(uploadUrl)
.addHeader("accesstoken", token) // token 认证头 .addHeader("accesstoken", token) // token
.post(requestBody) .post(requestBody)
.build(); .build();
@ -441,18 +473,17 @@ public class FirstActivity extends BaseActivity {
String result = response.body().string(); String result = response.body().string();
Log.d(TAG, "文件上传成功: " + result); Log.d(TAG, "文件上传成功: " + result);
// 提取 fileName 与后端返回的 data String safeResult = result.replace("'", "\\'");
String safeResult = result.replace("'", "\\'"); // 避免 JS 语法错误
String safeFileName = fileName.replace("'", "\\'"); String safeFileName = fileName.replace("'", "\\'");
// JS 回调fileNamedatafileSize
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(this, "上传成功", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "上传成功", Toast.LENGTH_SHORT).show();
if (webView != null) { if (webView != null) {
// fileName data 到前端
String jsCode = String.format( String jsCode = String.format(
"window.onFileUploadSuccess && window.onFileUploadSuccess({fileName: '%s', data: %s})", "window.onFileUploadSuccess && window.onFileUploadSuccess({fileName: '%s', data: %s, fileSize: %.2f})",
safeFileName, safeResult safeFileName, safeResult, fileSize
); );
webView.evaluateJavascript(jsCode, null); webView.evaluateJavascript(jsCode, null);
} }
@ -472,6 +503,7 @@ public class FirstActivity extends BaseActivity {
}).start(); }).start();
} }
/** /**
* Uri 获取文件名 * Uri 获取文件名
*/ */