Compare commits

..

2 Commits

Author SHA1 Message Date
frank wang b5e8115365 文件上传的逻辑 2025-10-30 13:53:15 +08:00
frank wang d1deee482c 文件上传的逻辑 2025-10-15 16:33:58 +08:00
1 changed files with 201 additions and 1 deletions

View File

@ -24,6 +24,13 @@ import android.widget.Toast;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import android.app.Activity;
import android.content.Intent; // 文件选择核心类
import android.database.Cursor; // 解析文件信息
import android.provider.OpenableColumns; // 获取文件名大小
import org.json.JSONObject;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
@ -239,6 +246,19 @@ 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
private void downloadFile(String url) { private void downloadFile(String url) {
@ -275,6 +295,7 @@ 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();
currentDownloadId = dm.enqueue(request); currentDownloadId = dm.enqueue(request);
startDownloadProgressMonitor(dm, currentDownloadId); startDownloadProgressMonitor(dm, currentDownloadId);
} else { } else {
@ -298,7 +319,6 @@ public class FirstActivity extends BaseActivity {
while (downloading) { while (downloading) {
try { try {
Toast.makeText(this, "文件已开始下载,请等待", Toast.LENGTH_SHORT).show();
Thread.sleep(1000); Thread.sleep(1000);
android.database.Cursor cursor = dm.query(query); android.database.Cursor cursor = dm.query(query);
if (cursor != null && cursor.moveToFirst()) { if (cursor != null && cursor.moveToFirst()) {
@ -337,6 +357,160 @@ public class FirstActivity extends BaseActivity {
} }
} }
// ==============================
// 文件选择与上传逻辑新增部分
// ==============================
private static final int REQUEST_CODE_FILE_CHOOSER = 2001;
/**
* JS 调用此方法选择文件
*/
@JavascriptInterface
public void chooseFile() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("*/*");
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(Intent.createChooser(intent, "选择要上传的文件"), REQUEST_CODE_FILE_CHOOSER);
}
/**
* 文件选择结果回调
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_FILE_CHOOSER && resultCode == RESULT_OK && data != null) {
Uri uri = data.getData();
if (uri != null) {
Toast.makeText(this, "文件已选择,开始上传...", Toast.LENGTH_SHORT).show();
uploadFile(uri); // 自动上传文件
}
}
}
/**
* 上传文件到服务器
*/
private void uploadFile(Uri uri) {
new Thread(() -> {
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 token = getToken(); // 从本地获取前端传来的 token
if (TextUtils.isEmpty(token)) {
runOnUiThread(() -> Toast.makeText(this, "请先登录后再上传", Toast.LENGTH_SHORT).show());
return;
}
// 获取文件名
String fileName = getFileNameFromUri(uri);
if (TextUtils.isEmpty(fileName)) fileName = "upload_file";
// 读取文件内容
InputStream inputStream = getContentResolver().openInputStream(uri);
byte[] fileBytes = new byte[inputStream.available()];
inputStream.read(fileBytes);
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()
.setType(okhttp3.MultipartBody.FORM)
.addFormDataPart("file", fileName, fileBody)
.build();
okhttp3.Request request = new okhttp3.Request.Builder()
.url(uploadUrl)
.addHeader("accesstoken", token) // 添加 token 认证头
.post(requestBody)
.build();
okhttp3.Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
String result = response.body().string();
Log.d(TAG, "文件上传成功: " + result);
// 提取 fileName 与后端返回的 data
String safeResult = result.replace("'", "\\'"); // 避免 JS 语法错误
String safeFileName = fileName.replace("'", "\\'");
runOnUiThread(() -> {
Toast.makeText(this, "上传成功", Toast.LENGTH_SHORT).show();
if (webView != null) {
// fileName data 到前端
String jsCode = String.format(
"window.onFileUploadSuccess && window.onFileUploadSuccess({fileName: '%s', data: %s})",
safeFileName, safeResult
);
webView.evaluateJavascript(jsCode, null);
}
});
} else {
runOnUiThread(() ->
Toast.makeText(this, "上传失败: " + response.code(), Toast.LENGTH_LONG).show()
);
}
} catch (Exception e) {
e.printStackTrace();
runOnUiThread(() ->
Toast.makeText(this, "上传异常: " + e.getMessage(), Toast.LENGTH_LONG).show()
);
}
}).start();
}
/**
* Uri 获取文件名
*/
private String getFileNameFromUri(Uri uri) {
String result = null;
if ("content".equals(uri.getScheme())) {
try (android.database.Cursor cursor = getContentResolver().query(uri, null, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getString(cursor.getColumnIndexOrThrow(android.provider.OpenableColumns.DISPLAY_NAME));
}
}
}
if (result == null) {
result = uri.getPath();
int cut = result.lastIndexOf('/');
if (cut != -1) result = result.substring(cut + 1);
}
return result;
}
// ==============================
// 新增存储与获取 token 的方法
// ==============================
private static final String KEY_TOKEN = "USER_TOKEN";
// JS 传入 token
@JavascriptInterface
public void setToken(String token) {
if (!TextUtils.isEmpty(token)) {
SpUtils.putString(this, KEY_TOKEN, token);
Log.d(TAG, "已保存 token: " + token);
}
}
// 获取本地 token
private String getToken() {
return SpUtils.getString(this, KEY_TOKEN, "");
}
public static class JsBridge { public static class JsBridge {
private final WeakReference<FirstActivity> activityRef; private final WeakReference<FirstActivity> activityRef;
@ -370,6 +544,32 @@ public class FirstActivity extends BaseActivity {
} }
} }
// 供前端调用的文件选择方法
@JavascriptInterface
public void chooseFile() {
FirstActivity activity = activityRef.get();
if (activity != null) {
activity.runOnUiThread(activity::chooseFile);
}
}
// 供前端调用的文件选择方法
@JavascriptInterface
public void previewFile(String url) {
FirstActivity activity = activityRef.get();
if (activity != null && !TextUtils.isEmpty(url)) {
activity.runOnUiThread(() -> activity.previewFile(url));
}
}
// 供前端调用的文件选择方法
@JavascriptInterface
public void setToken(String token) {
FirstActivity activity = activityRef.get();
if (activity != null && !TextUtils.isEmpty(token)) {
activity.runOnUiThread(() -> activity.setToken(token));
}
}
@JavascriptInterface @JavascriptInterface
public void showLog(String message) { public void showLog(String message) {
FirstActivity activity = activityRef.get(); FirstActivity activity = activityRef.get();