Merge remote-tracking branch 'origin/master'

# Conflicts:
#	app/src/main/AndroidManifest.xml
#	app/src/main/java/com/pxkj/jwzs/FirstActivity.java
This commit is contained in:
hanrenchun 2025-10-31 08:55:29 +08:00
commit 7b323eba41
2 changed files with 73 additions and 43 deletions

View File

@ -2,9 +2,20 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<!-- 🌐 基本网络权限 -->
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Android 10+ 不需要 WRITE_EXTERNAL_STORAGEDownloadManager 可访问 Downloads 目录 --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- 📂 文件选择/下载权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" tools:ignore="ScopedStorage" />
<!-- Android 13+ 细分权限(推荐添加) -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<application <application
android:name=".MyApplication" android:name=".MyApplication"
@ -16,18 +27,18 @@
android:theme="@style/Theme.jwzs" android:theme="@style/Theme.jwzs"
tools:replace="android:allowBackup"> tools:replace="android:allowBackup">
<!-- 🔧 应用标识配置 -->
<meta-data <meta-data
android:name="appId" android:name="appId"
android:value="${APPID}" /><!-- 应用ID,当应用在平台注册后,由平台生成的平台内唯一标识 --> android:value="${APPID}" />
<meta-data <meta-data
android:name="regionalismCode" android:name="regionalismCode"
android:value="${REGIONALISMCODE}" /><!--应用归属机构代码320000260300对于纯数字字符串请在前面增加“\0”否则将会取出null值字符串 --> android:value="${REGIONALISMCODE}" />
<meta-data <meta-data
android:name="networkAreaCode" android:name="networkAreaCode"
android:value="${NETWORKAREACODE}" /><!--应用所属网络区域也即应用类型1-2-32对于纯数字字符串请在前面增加“\0”否则将会取出null值字符串 --> android:value="${NETWORKAREACODE}" />
<!-- 添加硬件加速和屏幕方向配置 --> <!-- 🚀 主入口 -->
<activity <activity
android:name=".FirstActivity" android:name=".FirstActivity"
android:configChanges="orientation|screenSize|keyboardHidden" android:configChanges="orientation|screenSize|keyboardHidden"
@ -40,16 +51,11 @@
</intent-filter> </intent-filter>
</activity> </activity>
<!-- 非必要可移除 MainActivity --> <!-- 可选备用 Activity -->
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:exported="false" /> android:exported="false" />
</application> </application>
<!-- 添加必要权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
</manifest> </manifest>

View File

@ -246,19 +246,6 @@ 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 * 下载文件并调用系统 DownloadManager
@ -429,7 +416,7 @@ public class FirstActivity extends BaseActivity {
private void uploadFile(Uri uri) { private void uploadFile(Uri uri) {
new Thread(() -> { new Thread(() -> {
try { try {
// 上传接口 // 上传接口地址
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();
@ -438,32 +425,40 @@ public class FirstActivity extends BaseActivity {
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);
byte[] fileBytes = new byte[inputStream.available()]; okhttp3.RequestBody fileBody = new okhttp3.RequestBody() {
inputStream.read(fileBytes); @Nullable
inputStream.close(); @Override
public okhttp3.MediaType contentType() {
return okhttp3.MediaType.parse("application/octet-stream");
}
long fileSize = fileBytes.length; // 文件大小字节 @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();
@ -476,13 +471,12 @@ public class FirstActivity extends BaseActivity {
String safeResult = result.replace("'", "\\'"); String safeResult = result.replace("'", "\\'");
String safeFileName = fileName.replace("'", "\\'"); String safeFileName = fileName.replace("'", "\\'");
// JS 回调fileNamedatafileSize // JS 回调 fileNamedatafileSize
runOnUiThread(() -> { runOnUiThread(() -> {
Toast.makeText(this, "上传成功", Toast.LENGTH_SHORT).show(); Toast.makeText(this, "上传成功", Toast.LENGTH_SHORT).show();
if (webView != null) { if (webView != null) {
String jsCode = String.format( String jsCode = String.format(
"window.onFileUploadSuccess && window.onFileUploadSuccess({fileName: '%s', data: %s, fileSize: %.2f})", "window.onFileUploadSuccess && window.onFileUploadSuccess({fileName: '%s', data: %s, fileSize: %d})",
safeFileName, safeResult, fileSize safeFileName, safeResult, fileSize
); );
webView.evaluateJavascript(jsCode, null); webView.evaluateJavascript(jsCode, null);
@ -503,6 +497,36 @@ 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 获取文件名