文件上传的逻辑
This commit is contained in:
parent
d1deee482c
commit
b5e8115365
|
|
@ -29,6 +29,8 @@ import android.content.Intent; // ← 文件选择核心类
|
||||||
import android.database.Cursor; // ← 解析文件信息
|
import android.database.Cursor; // ← 解析文件信息
|
||||||
import android.provider.OpenableColumns; // ← 获取文件名、大小
|
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;
|
||||||
|
|
@ -244,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) {
|
||||||
|
|
@ -342,69 +357,158 @@ public class FirstActivity extends BaseActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在 FirstActivity.java 中添加以下代码
|
// ==============================
|
||||||
|
// 文件选择与上传逻辑(新增部分)
|
||||||
|
// ==============================
|
||||||
|
|
||||||
private static final int REQUEST_CODE_FILE_PICK = 2001;
|
private static final int REQUEST_CODE_FILE_CHOOSER = 2001;
|
||||||
private Uri selectedFileUri;
|
|
||||||
|
|
||||||
private void chooseFile() {
|
/**
|
||||||
runOnUiThread(() -> {
|
* JS 调用此方法选择文件
|
||||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
*/
|
||||||
intent.setType("*/*"); // 所有类型
|
@JavascriptInterface
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
public void chooseFile() {
|
||||||
startActivityForResult(Intent.createChooser(intent, "请选择文件"), REQUEST_CODE_FILE_PICK);
|
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||||
});
|
intent.setType("*/*");
|
||||||
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
|
startActivityForResult(Intent.createChooser(intent, "选择要上传的文件"), REQUEST_CODE_FILE_CHOOSER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 选择文件后的回调
|
* 文件选择结果回调
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
if (requestCode == REQUEST_CODE_FILE_PICK && resultCode == RESULT_OK && data != null) {
|
if (requestCode == REQUEST_CODE_FILE_CHOOSER && resultCode == RESULT_OK && data != null) {
|
||||||
selectedFileUri = data.getData();
|
Uri uri = data.getData();
|
||||||
if (selectedFileUri != null) {
|
if (uri != null) {
|
||||||
String fileName = getFileNameFromUri(selectedFileUri);
|
Toast.makeText(this, "文件已选择,开始上传...", Toast.LENGTH_SHORT).show();
|
||||||
String filePath = selectedFileUri.toString();
|
uploadFile(uri); // 自动上传文件
|
||||||
|
|
||||||
// 将选择的文件信息传回前端 JS
|
|
||||||
if (webView != null) {
|
|
||||||
String jsCode = String.format(
|
|
||||||
"if(window.onFileChosen){window.onFileChosen('%s','%s');}",
|
|
||||||
fileName.replace("'", "\\'"),
|
|
||||||
filePath.replace("'", "\\'")
|
|
||||||
);
|
|
||||||
webView.evaluateJavascript(jsCode, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
Toast.makeText(this, "已选择文件: " + fileName, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从 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) {
|
private String getFileNameFromUri(Uri uri) {
|
||||||
String result = null;
|
String result = null;
|
||||||
if ("content".equals(uri.getScheme())) {
|
if ("content".equals(uri.getScheme())) {
|
||||||
try (android.database.Cursor cursor = getContentResolver().query(uri, null, null, null, null)) {
|
try (android.database.Cursor cursor = getContentResolver().query(uri, null, null, null, null)) {
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
result = cursor.getString(cursor.getColumnIndex(android.provider.OpenableColumns.DISPLAY_NAME));
|
result = cursor.getString(cursor.getColumnIndexOrThrow(android.provider.OpenableColumns.DISPLAY_NAME));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
result = uri.getPath();
|
result = uri.getPath();
|
||||||
int cut = result.lastIndexOf('/');
|
int cut = result.lastIndexOf('/');
|
||||||
if (cut != -1) {
|
if (cut != -1) result = result.substring(cut + 1);
|
||||||
result = result.substring(cut + 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
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 {
|
||||||
|
|
@ -439,6 +543,7 @@ public class FirstActivity extends BaseActivity {
|
||||||
activity.runOnUiThread(() -> activity.downloadFile(url));
|
activity.runOnUiThread(() -> activity.downloadFile(url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ 供前端调用的文件选择方法
|
// ✅ 供前端调用的文件选择方法
|
||||||
@JavascriptInterface
|
@JavascriptInterface
|
||||||
public void chooseFile() {
|
public void chooseFile() {
|
||||||
|
|
@ -448,6 +553,23 @@ public class FirstActivity extends BaseActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ✅ 供前端调用的文件选择方法
|
||||||
|
@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();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue