上传文件至 /
This commit is contained in:
parent
114ccbd02d
commit
aa30677d15
|
@ -0,0 +1,70 @@
|
||||||
|
package com.example.myapplication.Tool;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
//测试时使用
|
||||||
|
public class ErrorDisplayUtil {
|
||||||
|
|
||||||
|
// 显示全量错误信息的对话框
|
||||||
|
public static void showErrorDialog(Activity activity, String title, String errorDetail) {
|
||||||
|
activity.runOnUiThread(() -> {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||||
|
builder.setTitle(title)
|
||||||
|
.setMessage(errorDetail)
|
||||||
|
.setPositiveButton("复制错误", (dialog, which) -> {
|
||||||
|
ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
ClipData clip = ClipData.newPlainText("错误详情", errorDetail);
|
||||||
|
clipboard.setPrimaryClip(clip);
|
||||||
|
Toast.makeText(activity, "已复制到剪贴板", Toast.LENGTH_SHORT).show();
|
||||||
|
})
|
||||||
|
.setNegativeButton("关闭", null)
|
||||||
|
.show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在界面上固定位置显示错误面板(建议放在登录按钮下方)
|
||||||
|
public static void showErrorPanel(Activity activity, String errorType, String solution) {
|
||||||
|
activity.runOnUiThread(() -> {
|
||||||
|
ViewGroup rootView = activity.findViewById(android.R.id.content);
|
||||||
|
|
||||||
|
// 创建错误面板
|
||||||
|
LinearLayout errorPanel = new LinearLayout(activity);
|
||||||
|
errorPanel.setOrientation(LinearLayout.VERTICAL);
|
||||||
|
errorPanel.setBackgroundColor(0x22FF0000); // 半透明红色背景
|
||||||
|
errorPanel.setPadding(16, 16, 16, 16);
|
||||||
|
|
||||||
|
TextView errorView = new TextView(activity);
|
||||||
|
errorView.setTextColor(Color.RED);
|
||||||
|
errorView.setText("⚠️ 错误类型: " + errorType);
|
||||||
|
|
||||||
|
TextView solutionView = new TextView(activity);
|
||||||
|
solutionView.setTextColor(Color.BLACK);
|
||||||
|
solutionView.setText("💡 解决方案: " + solution);
|
||||||
|
|
||||||
|
Button detailBtn = new Button(activity);
|
||||||
|
detailBtn.setText("查看技术详情");
|
||||||
|
detailBtn.setOnClickListener(v -> showErrorDialog(activity, "技术详情", errorType + "\n\n" + solution));
|
||||||
|
|
||||||
|
errorPanel.addView(errorView);
|
||||||
|
errorPanel.addView(solutionView);
|
||||||
|
errorPanel.addView(detailBtn);
|
||||||
|
|
||||||
|
// 添加到界面底部
|
||||||
|
rootView.addView(errorPanel);
|
||||||
|
|
||||||
|
// 5秒后自动隐藏
|
||||||
|
new Handler().postDelayed(() -> rootView.removeView(errorPanel), 5000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
package com.example.myapplication.Tool;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.util.SparseBooleanArray;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.BaseAdapter;
|
||||||
|
import android.widget.GridView;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import com.example.myapplication.model.ImageInfo;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ImageAdapter extends BaseAdapter {
|
||||||
|
private final Context context;
|
||||||
|
private final List<ImageInfo> imageList;
|
||||||
|
private final SparseBooleanArray selectedItems;
|
||||||
|
|
||||||
|
public ImageAdapter(Context context, List<ImageInfo> imageList) {
|
||||||
|
this.context = context;
|
||||||
|
this.imageList = imageList;
|
||||||
|
this.selectedItems = new SparseBooleanArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return imageList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getItem(int position) {
|
||||||
|
return imageList.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
ImageView imageView;
|
||||||
|
if (convertView == null) {
|
||||||
|
imageView = new ImageView(context);
|
||||||
|
imageView.setLayoutParams(new GridView.LayoutParams(200, 200));
|
||||||
|
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||||
|
imageView.setPadding(5, 5, 5, 5);
|
||||||
|
} else {
|
||||||
|
imageView = (ImageView) convertView;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageInfo imageInfo = imageList.get(position);
|
||||||
|
imageView.setImageBitmap(imageInfo.thumbnail);
|
||||||
|
|
||||||
|
// 设置选中状态
|
||||||
|
if (selectedItems.get(position, false)) {
|
||||||
|
imageView.setBackgroundColor(Color.BLUE);
|
||||||
|
} else {
|
||||||
|
imageView.setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
imageView.setOnClickListener(v -> {
|
||||||
|
if (selectedItems.get(position, false)) {
|
||||||
|
selectedItems.delete(position);
|
||||||
|
imageView.setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
} else {
|
||||||
|
selectedItems.put(position, true);
|
||||||
|
imageView.setBackgroundColor(Color.BLUE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return imageView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ImageInfo> getSelectedImages() {
|
||||||
|
List<ImageInfo> selected = new ArrayList<>();
|
||||||
|
for (int i = 0; i < imageList.size(); i++) {
|
||||||
|
if (selectedItems.get(i, false)) {
|
||||||
|
selected.add(imageList.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,282 @@
|
||||||
|
package com.example.myapplication.Tool;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
|
||||||
|
import com.example.myapplication.DataBase.DatabaseHelper;
|
||||||
|
import com.example.myapplication.api.PartService;
|
||||||
|
import com.example.myapplication.model.ApiResponse;
|
||||||
|
import com.example.myapplication.model.PartResponse;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Response;
|
||||||
|
import retrofit2.Retrofit;
|
||||||
|
import retrofit2.converter.gson.GsonConverterFactory;
|
||||||
|
|
||||||
|
public class PartListFetcher {
|
||||||
|
private final Context context;
|
||||||
|
private final String token;
|
||||||
|
private final String projectId;
|
||||||
|
|
||||||
|
private final PartService partService;
|
||||||
|
private final DatabaseHelper dbHelper;
|
||||||
|
|
||||||
|
public PartListFetcher(Context context, String token, String projectId) {
|
||||||
|
this.context = context;
|
||||||
|
this.token = token;
|
||||||
|
this.projectId = projectId;
|
||||||
|
|
||||||
|
this.dbHelper = new DatabaseHelper(context);
|
||||||
|
|
||||||
|
// 初始化Retrofit
|
||||||
|
OkHttpClient okHttpClient = new OkHttpClient.Builder()
|
||||||
|
.connectTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.readTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.writeTimeout(30, TimeUnit.SECONDS)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Retrofit retrofit = RetrofitClient.getClient(token);
|
||||||
|
|
||||||
|
this.partService = retrofit.create(PartService.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步获取部件列表
|
||||||
|
* @return 部件列表
|
||||||
|
* @throws IOException 网络异常
|
||||||
|
* @throws ApiException API异常
|
||||||
|
*/
|
||||||
|
public List<PartResponse> fetchPartListSync() throws IOException, ApiException {
|
||||||
|
if (isNetworkAvailable()) {
|
||||||
|
// 有网络时从服务器获取并更新数据库
|
||||||
|
List<PartResponse> serverParts = fetchFromServer();
|
||||||
|
dbHelper.saveParts(serverParts);
|
||||||
|
return serverParts;
|
||||||
|
} else {
|
||||||
|
// 无网络时从数据库获取
|
||||||
|
return dbHelper.getAllParts();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步获取部件列表
|
||||||
|
* @param callback 回调接口
|
||||||
|
*/
|
||||||
|
public void fetchPartListAsync(final PartListCallback callback) {
|
||||||
|
// 先从数据库获取数据快速显示
|
||||||
|
List<PartResponse> cachedParts = dbHelper.getAllParts();
|
||||||
|
if (!cachedParts.isEmpty()) {
|
||||||
|
callback.onSuccess(cachedParts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查网络连接
|
||||||
|
if (isNetworkAvailable()) {
|
||||||
|
// 有网络时从服务器获取并更新数据库
|
||||||
|
fetchFromServerAsync(new PartListCallback() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<PartResponse> partList) {
|
||||||
|
dbHelper.saveParts(partList);
|
||||||
|
callback.onSuccess(partList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Throwable t) {
|
||||||
|
// 服务器获取失败,如果之前有缓存数据则不报错
|
||||||
|
if (cachedParts.isEmpty()) {
|
||||||
|
callback.onFailure(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (cachedParts.isEmpty()) {
|
||||||
|
// 无网络且无缓存数据
|
||||||
|
callback.onFailure(new IOException("无网络连接且无缓存数据"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public String getPartIdByName(String partName) {
|
||||||
|
// 先从数据库查询
|
||||||
|
String partId = dbHelper.getPartIdByName(partName);
|
||||||
|
if (partId != null) {
|
||||||
|
return partId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数据库中没有则尝试从服务器获取
|
||||||
|
if (isNetworkAvailable()) {
|
||||||
|
try {
|
||||||
|
List<PartResponse> parts = fetchFromServer();
|
||||||
|
dbHelper.saveParts(parts);
|
||||||
|
// 再次从数据库查询
|
||||||
|
return dbHelper.getPartIdByName(partName);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
private List<PartResponse> fetchFromServer() throws IOException, ApiException {
|
||||||
|
Call<ApiResponse<List<PartResponse>>> call = partService.getPartList(
|
||||||
|
projectId,
|
||||||
|
|
||||||
|
null, null, null, null
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
Response<ApiResponse<List<PartResponse>>> response = call.execute();
|
||||||
|
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
ApiResponse<List<PartResponse>> apiResponse = response.body();
|
||||||
|
if (apiResponse.isSuccess()) {
|
||||||
|
return apiResponse.getData();
|
||||||
|
} else {
|
||||||
|
throw new ApiException(apiResponse.getCode(), apiResponse.getMsg());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new IOException("请求失败,状态码: " + response.code());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void fetchFromServerAsync(final PartListCallback callback) {
|
||||||
|
Call<ApiResponse<List<PartResponse>>> call = partService.getPartList(
|
||||||
|
projectId,
|
||||||
|
|
||||||
|
null, null, null, null
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
call.enqueue(new retrofit2.Callback<ApiResponse<List<PartResponse>>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ApiResponse<List<PartResponse>>> call,
|
||||||
|
Response<ApiResponse<List<PartResponse>>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
ApiResponse<List<PartResponse>> apiResponse = response.body();
|
||||||
|
if (apiResponse.isSuccess()) {
|
||||||
|
callback.onSuccess(apiResponse.getData());
|
||||||
|
} else {
|
||||||
|
callback.onFailure(new ApiException(apiResponse.getCode(), apiResponse.getMsg()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback.onFailure(new IOException("请求失败,状态码: " + response.code()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ApiResponse<List<PartResponse>>> call, Throwable t) {
|
||||||
|
callback.onFailure(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNetworkAvailable() {
|
||||||
|
ConnectivityManager connectivityManager =
|
||||||
|
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
if (connectivityManager != null) {
|
||||||
|
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
|
||||||
|
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 带筛选条件的异步获取部件列表
|
||||||
|
* @param keyword 关键字
|
||||||
|
* @param manufacturer 厂商
|
||||||
|
* @param model 型号
|
||||||
|
* @param type 类型
|
||||||
|
* @param callback 回调接口
|
||||||
|
*/
|
||||||
|
public void fetchPartListWithFilterAsync(String keyword, String manufacturer,
|
||||||
|
String model, String type,
|
||||||
|
PartListCallback callback) {
|
||||||
|
Call<ApiResponse<List<PartResponse>>> call = partService.getPartList(
|
||||||
|
projectId,
|
||||||
|
|
||||||
|
keyword,
|
||||||
|
manufacturer,
|
||||||
|
model,
|
||||||
|
type
|
||||||
|
);
|
||||||
|
|
||||||
|
call.enqueue(new retrofit2.Callback<ApiResponse<List<PartResponse>>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ApiResponse<List<PartResponse>>> call,
|
||||||
|
Response<ApiResponse<List<PartResponse>>> response) {
|
||||||
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
|
ApiResponse<List<PartResponse>> apiResponse = response.body();
|
||||||
|
if (apiResponse.isSuccess()) {
|
||||||
|
callback.onSuccess(apiResponse.getData());
|
||||||
|
} else {
|
||||||
|
callback.onFailure(new ApiException(apiResponse.getCode(), apiResponse.getMsg()));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback.onFailure(new IOException("请求失败,状态码: " + response.code()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ApiResponse<List<PartResponse>>> call, Throwable t) {
|
||||||
|
callback.onFailure(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface PartListCallback {
|
||||||
|
void onSuccess(List<PartResponse> partList);
|
||||||
|
void onFailure(Throwable t);
|
||||||
|
}
|
||||||
|
public String getPartIdByNameSync(String partName) throws IOException, ApiException {
|
||||||
|
List<PartResponse> partList = fetchPartListSync();
|
||||||
|
for (PartResponse part : partList) {
|
||||||
|
if (partName.equals(part.getPartName())) {
|
||||||
|
return part.getPartId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步根据部件名称获取部件ID
|
||||||
|
* @param partName 要查找的部件名称
|
||||||
|
* @param callback 回调接口
|
||||||
|
*/
|
||||||
|
public void getPartIdByNameAsync(String partName, PartIdCallback callback) {
|
||||||
|
fetchPartListAsync(new PartListCallback() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(List<PartResponse> partList) {
|
||||||
|
for (PartResponse part : partList) {
|
||||||
|
if (partName.equals(part.getPartName())) {
|
||||||
|
callback.onSuccess(part.getPartId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback.onSuccess(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Throwable t) {
|
||||||
|
callback.onFailure(t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface PartIdCallback {
|
||||||
|
void onSuccess(String partId);
|
||||||
|
void onFailure(Throwable t);
|
||||||
|
}
|
||||||
|
public static class ApiException extends Exception {
|
||||||
|
private final int code;
|
||||||
|
|
||||||
|
public ApiException(int code, String message) {
|
||||||
|
super(message);
|
||||||
|
this.code = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.example.myapplication.Tool;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
public class PermissionUtils {
|
||||||
|
// 请求码
|
||||||
|
public static final int REQUEST_STORAGE_PERMISSION = 101;
|
||||||
|
public static final int REQUEST_MEDIA_PERMISSION = 102; // Android 13+ 媒体权限
|
||||||
|
|
||||||
|
// 检查并请求所有必要权限
|
||||||
|
public static boolean checkAndRequestPermissions(Activity activity) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
||||||
|
// Android 14+ 需要检查媒体权限(如果要访问媒体文件)
|
||||||
|
return checkMediaPermissions(activity);
|
||||||
|
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
// Android 10-13 使用 SAF 或 MediaStore,不需要存储权限
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// Android 9 及以下需要传统存储权限
|
||||||
|
return checkLegacyStoragePermission(activity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Android 14+ 媒体权限检查
|
||||||
|
private static boolean checkMediaPermissions(Activity activity) {
|
||||||
|
String[] permissions;
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
permissions = new String[]{
|
||||||
|
Manifest.permission.READ_MEDIA_IMAGES,
|
||||||
|
Manifest.permission.READ_MEDIA_VIDEO,
|
||||||
|
Manifest.permission.READ_MEDIA_AUDIO
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
permissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE};
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean allGranted = true;
|
||||||
|
for (String perm : permissions) {
|
||||||
|
if (ContextCompat.checkSelfPermission(activity, perm) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
allGranted = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!allGranted) {
|
||||||
|
ActivityCompat.requestPermissions(activity, permissions, REQUEST_MEDIA_PERMISSION);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Android 9 及以下传统存储权限
|
||||||
|
private static boolean checkLegacyStoragePermission(Activity activity) {
|
||||||
|
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
|
ActivityCompat.requestPermissions(activity,
|
||||||
|
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||||
|
REQUEST_STORAGE_PERMISSION);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理权限请求结果
|
||||||
|
public static boolean handlePermissionResult(int requestCode,
|
||||||
|
String[] permissions, int[] grantResults) {
|
||||||
|
if (grantResults.length == 0) return false;
|
||||||
|
|
||||||
|
if (requestCode == REQUEST_STORAGE_PERMISSION ||
|
||||||
|
requestCode == REQUEST_MEDIA_PERMISSION) {
|
||||||
|
for (int result : grantResults) {
|
||||||
|
if (result != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
package com.example.myapplication.Tool;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.chaquo.python.Python;
|
||||||
|
import com.chaquo.python.android.AndroidPlatform;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ReportGeneratorHelper {
|
||||||
|
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
public ReportGeneratorHelper(Context context) {
|
||||||
|
this.context = context;
|
||||||
|
if (!Python.isStarted()) {
|
||||||
|
Python.start(new AndroidPlatform(context));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateReport(String templateContent, String outputPath,
|
||||||
|
String turbineId, String testDate,
|
||||||
|
List<ImageData> imageDataList,
|
||||||
|
String weather, String temperature, String humidity,
|
||||||
|
String startDate, String endDate,
|
||||||
|
ReportGenerationCallback callback) {
|
||||||
|
try {
|
||||||
|
Python py = Python.getInstance();
|
||||||
|
|
||||||
|
// 转换Java的ImageData列表为Python可接受的格式
|
||||||
|
List<List<Object>> pyImageData = new ArrayList<>();
|
||||||
|
for (ImageData data : imageDataList) {
|
||||||
|
List<Object> item = new ArrayList<>();
|
||||||
|
item.add(data.getImagePath());
|
||||||
|
item.add(data.getResistance());
|
||||||
|
pyImageData.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 准备配置字典
|
||||||
|
Map<String, Object> config = new HashMap<>();
|
||||||
|
config.put("template_content", templateContent);
|
||||||
|
config.put("output_path", outputPath);
|
||||||
|
config.put("turbine_id", turbineId);
|
||||||
|
config.put("test_date", testDate);
|
||||||
|
config.put("image_data", pyImageData);
|
||||||
|
config.put("weather", weather);
|
||||||
|
config.put("temperature", temperature);
|
||||||
|
config.put("humidity", humidity);
|
||||||
|
config.put("start_date", startDate);
|
||||||
|
config.put("end_date", endDate);
|
||||||
|
String jsonConfig = new Gson().toJson(config);
|
||||||
|
// 调用Python模块
|
||||||
|
py.getModule("report_generator")
|
||||||
|
.callAttr("generate_report_from_java", jsonConfig);
|
||||||
|
// 成功回调
|
||||||
|
callback.onSuccess(outputPath);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
callback.onError(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ReportGenerationCallback {
|
||||||
|
void onSuccess(String outputPath);
|
||||||
|
void onError(String errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ImageData {
|
||||||
|
private String imagePath;
|
||||||
|
private String resistance;
|
||||||
|
|
||||||
|
public ImageData(String imagePath, String resistance) {
|
||||||
|
this.imagePath = imagePath;
|
||||||
|
this.resistance = resistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getImagePath() {
|
||||||
|
return imagePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getResistance() {
|
||||||
|
return resistance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue