Compare commits
No commits in common. "569c02516901345de71a144e1da65e5ebe8bbb9e" and "f8adef2a9e6b08f9f2cc7443ed28c84cd0338903" have entirely different histories.
569c025169
...
f8adef2a9e
|
|
@ -246,24 +246,31 @@ public class FirstActivity extends BaseActivity {
|
||||||
// || url.contains("/api/file/");
|
// || url.contains("/api/file/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void previewFile(String url) {
|
||||||
|
try {
|
||||||
|
if (webView != null) {
|
||||||
|
webView.loadUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.makeText(this, "正在打开文件预览...", Toast.LENGTH_SHORT).show();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Toast.makeText(this, "预览文件失败: " + e.getMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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)) {
|
||||||
handler.post(() ->
|
Toast.makeText(this, "下载地址为空", Toast.LENGTH_SHORT).show();
|
||||||
Toast.makeText(this, "下载地址为空", Toast.LENGTH_SHORT).show()
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.startsWith("blob:") || url.startsWith("data:")) {
|
if (url.startsWith("blob:") || url.startsWith("data:")) {
|
||||||
handler.post(() ->
|
Toast.makeText(this, "无法直接下载 Blob 文件,请检查前端下载逻辑", Toast.LENGTH_SHORT).show();
|
||||||
Toast.makeText(this, "无法直接下载 Blob 文件,请检查前端下载逻辑", Toast.LENGTH_SHORT).show()
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -289,22 +296,16 @@ public class FirstActivity extends BaseActivity {
|
||||||
|
|
||||||
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
|
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
|
||||||
if (dm != null) {
|
if (dm != null) {
|
||||||
handler.post(() ->
|
Toast.makeText(this, "文件已开始下载,请等待", Toast.LENGTH_SHORT).show();
|
||||||
Toast.makeText(this, "文件已开始下载,请等待", Toast.LENGTH_SHORT).show()
|
|
||||||
);
|
|
||||||
currentDownloadId = dm.enqueue(request);
|
currentDownloadId = dm.enqueue(request);
|
||||||
startDownloadProgressMonitor(dm, currentDownloadId);
|
startDownloadProgressMonitor(dm, currentDownloadId);
|
||||||
} else {
|
} else {
|
||||||
handler.post(() ->
|
Toast.makeText(this, "系统下载服务不可用", Toast.LENGTH_SHORT).show();
|
||||||
Toast.makeText(this, "系统下载服务不可用", Toast.LENGTH_SHORT).show()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
handler.post(() ->
|
Toast.makeText(this, "下载失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||||
Toast.makeText(this, "下载失败: " + e.getMessage(), Toast.LENGTH_SHORT).show()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
@ -313,69 +314,48 @@ 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;
|
|
||||||
|
|
||||||
while (downloading) {
|
DownloadManager.Query query = new DownloadManager.Query();
|
||||||
try {
|
query.setFilterById(downloadId);
|
||||||
Thread.sleep(1000);
|
boolean downloading = true;
|
||||||
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));
|
|
||||||
|
|
||||||
if (status == DownloadManager.STATUS_RUNNING && total > 0) {
|
while (downloading) {
|
||||||
int progress = (int) ((downloaded * 100L) / total);
|
try {
|
||||||
handler.post(() -> {
|
Thread.sleep(1000);
|
||||||
sendProgressToJs(progress);
|
android.database.Cursor cursor = dm.query(query);
|
||||||
// 可选:减少 toast 频率,比如每 20% 提示一次
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
if (progress % 20 == 0) {
|
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
|
||||||
Toast.makeText(this, "下载中:" + progress + "%", Toast.LENGTH_SHORT).show();
|
long total = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
|
||||||
}
|
long downloaded = cursor.getLong(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
|
||||||
});
|
if (status == DownloadManager.STATUS_RUNNING && total > 0) {
|
||||||
} else if (status == DownloadManager.STATUS_SUCCESSFUL) {
|
int progress = (int) ((downloaded * 100L) / total);
|
||||||
downloading = false;
|
Toast.makeText(this, "下载中,当前进度为" + progress + "%", Toast.LENGTH_SHORT).show();
|
||||||
handler.post(() -> {
|
handler.post(() -> sendProgressToJs(progress));
|
||||||
sendProgressToJs(100);
|
} else if (status == DownloadManager.STATUS_SUCCESSFUL) {
|
||||||
Toast.makeText(this, "下载完成,请到文件管理查看", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "下载完成,请到文件管理查看", Toast.LENGTH_SHORT).show();
|
||||||
});
|
downloading = false;
|
||||||
} else if (status == DownloadManager.STATUS_FAILED) {
|
handler.post(() -> sendProgressToJs(100));
|
||||||
downloading = false;
|
} else if (status == DownloadManager.STATUS_FAILED) {
|
||||||
handler.post(() -> {
|
Toast.makeText(this, "下载失败" + status + "," + total + "," + downloaded, Toast.LENGTH_SHORT).show();
|
||||||
sendProgressToJs(-1);
|
downloading = false;
|
||||||
Toast.makeText(this, "下载失败", Toast.LENGTH_SHORT).show();
|
handler.post(() -> sendProgressToJs(-1));
|
||||||
});
|
|
||||||
}
|
|
||||||
cursor.close();
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
cursor.close();
|
||||||
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 e) {
|
} catch (Exception ignored) {
|
||||||
e.printStackTrace();
|
Toast.makeText(this, "文件已开始下载,请等待报错sendProgressToJs", Toast.LENGTH_SHORT).show();
|
||||||
handler.post(() ->
|
|
||||||
Toast.makeText(this, "进度回调异常:" + e.getMessage(), Toast.LENGTH_SHORT).show()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -410,55 +390,48 @@ public class FirstActivity extends BaseActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ✅ 上传文件,并在上传成功后将 fileName、data、fileSize 传给前端
|
* 上传文件到服务器
|
||||||
*/
|
*/
|
||||||
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();
|
String token = getToken(); // ✅ 从本地获取前端传来的 token
|
||||||
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";
|
||||||
long fileSize = getFileSizeFromUri(uri);
|
|
||||||
|
|
||||||
// ✅ 使用流式读取方式构建 RequestBody(防止 OOM)
|
// 读取文件内容
|
||||||
InputStream inputStream = getContentResolver().openInputStream(uri);
|
InputStream inputStream = getContentResolver().openInputStream(uri);
|
||||||
okhttp3.RequestBody fileBody = new okhttp3.RequestBody() {
|
byte[] fileBytes = new byte[inputStream.available()];
|
||||||
@Nullable
|
inputStream.read(fileBytes);
|
||||||
@Override
|
inputStream.close();
|
||||||
public okhttp3.MediaType contentType() {
|
|
||||||
return okhttp3.MediaType.parse("application/octet-stream");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeTo(okio.BufferedSink sink) throws IOException {
|
|
||||||
byte[] buffer = new byte[4096];
|
|
||||||
int bytesRead;
|
|
||||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
||||||
sink.write(buffer, 0, bytesRead);
|
|
||||||
}
|
|
||||||
inputStream.close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// 使用 OkHttp 上传
|
||||||
|
okhttp3.OkHttpClient client = new okhttp3.OkHttpClient();
|
||||||
|
okhttp3.RequestBody fileBody = okhttp3.RequestBody.create(
|
||||||
|
okhttp3.MediaType.parse("application/octet-stream"),
|
||||||
|
fileBytes
|
||||||
|
);
|
||||||
okhttp3.MultipartBody requestBody = new okhttp3.MultipartBody.Builder()
|
okhttp3.MultipartBody requestBody = new okhttp3.MultipartBody.Builder()
|
||||||
.setType(okhttp3.MultipartBody.FORM)
|
.setType(okhttp3.MultipartBody.FORM)
|
||||||
.addFormDataPart("file", fileName, fileBody)
|
.addFormDataPart("file", fileName, fileBody)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
okhttp3.OkHttpClient client = new okhttp3.OkHttpClient();
|
|
||||||
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();
|
||||||
|
|
||||||
|
|
@ -468,16 +441,18 @@ public class FirstActivity extends BaseActivity {
|
||||||
String result = response.body().string();
|
String result = response.body().string();
|
||||||
Log.d(TAG, "文件上传成功: " + result);
|
Log.d(TAG, "文件上传成功: " + result);
|
||||||
|
|
||||||
String safeResult = result.replace("'", "\\'");
|
// ✅ 提取 fileName 与后端返回的 data
|
||||||
|
String safeResult = result.replace("'", "\\'"); // 避免 JS 语法错误
|
||||||
String safeFileName = fileName.replace("'", "\\'");
|
String safeFileName = fileName.replace("'", "\\'");
|
||||||
|
|
||||||
// ✅ JS 回调 fileName、data、fileSize
|
|
||||||
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, fileSize: %d})",
|
"window.onFileUploadSuccess && window.onFileUploadSuccess({fileName: '%s', data: %s})",
|
||||||
safeFileName, safeResult, fileSize
|
safeFileName, safeResult
|
||||||
);
|
);
|
||||||
webView.evaluateJavascript(jsCode, null);
|
webView.evaluateJavascript(jsCode, null);
|
||||||
}
|
}
|
||||||
|
|
@ -497,37 +472,6 @@ public class FirstActivity extends BaseActivity {
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ✅ 获取文件大小(兼容 content:// 与 file://)
|
|
||||||
*/
|
|
||||||
private long getFileSizeFromUri(Uri uri) {
|
|
||||||
long fileSize = 0L;
|
|
||||||
if ("content".equals(uri.getScheme())) {
|
|
||||||
try (Cursor cursor = getContentResolver().query(uri, null, null, null, null)) {
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
|
|
||||||
if (sizeIndex != -1) {
|
|
||||||
fileSize = cursor.getLong(sizeIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fileSize <= 0) {
|
|
||||||
// 尝试从 File 读取
|
|
||||||
String path = uri.getPath();
|
|
||||||
if (path != null) {
|
|
||||||
java.io.File file = new java.io.File(path);
|
|
||||||
if (file.exists()) {
|
|
||||||
fileSize = file.length();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fileSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从 Uri 获取文件名
|
* 从 Uri 获取文件名
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue