44. e.printStackTrace();//输出红色异常信息

这篇博客主要展示了如何处理Java中的ArrayIndexOutOfBoundsException。在尝试访问数组不存在的索引时,程序抛出了这个异常。博主通过示例代码演示了异常的捕获,并使用`e.printStackTrace()`打印了详细的错误信息,最后输出了一条结束语。
部署运行你感兴趣的模型镜像
package com.itheima.exce;

import java.util.Scanner;

public class ExceptionDemo11 {
    public static void main(String[] args) {
        try {
            int[] arr={1,2,3,4,5};
            System.out.println(arr[10]);
        } catch (ArrayIndexOutOfBoundsException e) {
            /*String message = e.getMessage();
            System.out.println(message);*//*
            String s = e.toString();
            System.out.println(s);*/
            e.printStackTrace();//输出红色异常信息
        } finally {
        }
        System.out.println("嘿嘿。。。");
    }



}



您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

public class MainActivity3 extends AppCompatActivity { private static final String TAG = "camera2api"; private static final int REQUEST_CAMERA_PERMISSIONS = 100; private boolean isTextureAvailable = false; // 跟踪Surface状态 // 所需权限列表 private static final String[] REQUIRED_PERMISSIONS = { Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO }; // UI组件 private TextureView textureView; private ImageButton captureButton,recordButton, switchButton, filterButton; private ImageView thumbnailView; private View flashView; // 相机相关变量 private CameraManager cameraManager; private String cameraId; // 当前使用的相机ID private CameraDevice cameraDevice; private CameraCaptureSession captureSession; private CaptureRequest.Builder previewRequestBuilder; // 后台线程 private HandlerThread backgroundThread; private Handler backgroundHandler; // 图像读取器(用于拍照) private ImageReader imageReader; // 视频录制相关 private MediaRecorder mediaRecorder; private boolean isRecording = false; // 滤镜相关 private int currentFilter = 0; // 0:无滤镜 1:黑白 2:复古 private boolean useFilter = false; // 缩略图相关 private String lastCapturedPath; private StreamConfigurationMap map; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); // 初始化UI组件 initViews(); } // 初始化UI组件 private void initViews() { textureView = findViewById(R.id.textureView); captureButton = findViewById(R.id.btnCapture); recordButton = findViewById(R.id.btnRecord); switchButton = findViewById(R.id.btnSwitch); filterButton = findViewById(R.id.btnFilter); thumbnailView = findViewById(R.id.ivThumbnail); flashView = findViewById(R.id.flashView); try { // 初始化相机管理器 cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); cameraId = cameraManager.getCameraIdList()[0]; CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraId); map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); } catch (CameraAccessException e) { throw new RuntimeException(e); } Log.i(TAG, "使用相机ID: " + cameraId); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CAMERA_PERMISSIONS) { boolean allGranted = true; for (int result : grantResults) { if (result != PackageManager.PERMISSION_GRANTED) { allGranted = false; break; } } } } // 继续在MainActivity中添加以下代码 // TextureView监听 private final TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { // 当TextureView可用时,准备打开相机 openCamera(); // 在此处打开相机 isTextureAvailable = true; // 设置可用标志 } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { // 预览尺寸变化时处理 } @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { // TextureView销毁时释放资源 return true; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) { // 纹理更新时调用(每一帧都会调用) } }; // 选择合适的预览尺寸 private Size chooseOptimalSize(Size[] choices, int width, int height) { List<Size> bigEnough = new ArrayList<>(); for (Size option : choices) { if (option.getHeight() == option.getWidth() * height / width && option.getWidth() >= width && option.getHeight() >= height) { bigEnough.add(option); } } if (bigEnough.size() > 0) { return Collections.min(bigEnough, new CompareSizesByArea()); } else { return choices[0]; } } // 比较尺寸大小的工具类 static class CompareSizesByArea implements Comparator<Size> { @Override public int compare(Size lhs, Size rhs) { return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight()); } } // 打开相机 private void openCamera() { try { Log.i(TAG, "打开相机"); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { return; } // 打开相机 cameraManager.openCamera(cameraId, stateCallback, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } // 相机状态回调 private final CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(@NonNull CameraDevice camera) { Log.i(TAG, "打开相机成功"); // 相机打开成功 cameraDevice = camera; // 创建预览会话 createCameraPreviewSession(); } @Override public void onDisconnected(@NonNull CameraDevice camera) { // 相机关闭连接 camera.close(); cameraDevice = null; } @Override public void onError(@NonNull CameraDevice camera, int error) { // 相机出错 camera.close(); cameraDevice = null; finish(); } }; // 创建相机预览会话 private void createCameraPreviewSession() { try { Log.i(TAG, "创建相机预览会话"); SurfaceTexture texture = textureView.getSurfaceTexture(); if (texture == null) { Log.i(TAG, "texture为空"); return; } // 配置预览尺寸 Size[] previewSizes = map.getOutputSizes(SurfaceTexture.class); Size previewSize = chooseOptimalSize(previewSizes, textureView.getWidth(), textureView.getHeight()); texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); // 创建预览的Surface Surface previewSurface = new Surface(texture); // 配置拍照尺寸 Size[] outputSizes = map.getOutputSizes(ImageFormat.JPEG); Size imageSize = outputSizes[0]; // 选择第一个可用尺寸 imageReader = ImageReader.newInstance( imageSize.getWidth(), imageSize.getHeight(), ImageFormat.JPEG, 2); imageReader.setOnImageAvailableListener(onImageAvailableListener, backgroundHandler); // 创建预览请求 previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); previewRequestBuilder.addTarget(previewSurface); // 创建捕获会话 cameraDevice.createCaptureSession(Arrays.asList(previewSurface, imageReader.getSurface()), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { Log.i(TAG, "预览流配置成功"); if (cameraDevice == null) { return; } // 会话配置成功 captureSession = session; try { // 设置自动对焦和自动曝光 previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); // 开始预览 CaptureRequest previewRequest = previewRequestBuilder.build(); Log.i(TAG, "预览下发"); captureSession.setRepeatingRequest(previewRequest, null, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession session) { Toast.makeText(MainActivity3.this, "配置相机失败", Toast.LENGTH_SHORT).show(); } }, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } // 图像可用回调(拍照后) private final ImageReader.OnImageAvailableListener onImageAvailableListener = new ImageReader.OnImageAvailableListener() { @Override public void onImageAvailable(ImageReader reader) { // 获取拍摄的图像 Image image = reader.acquireLatestImage(); if (image == null) { return; } // 处理图像数据 ByteBuffer buffer = image.getPlanes()[0].getBuffer(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes); // 应用滤镜(如果启用) if (useFilter) { bytes = applyFilter(bytes); } // 保存图像 String path = saveImageToFile(bytes); // 更新缩略图 if (path != null) { lastCapturedPath = path; runOnUiThread(() -> updateThumbnail(path)); } // 释放图像资源 image.close(); // 恢复预览 try { captureSession.setRepeatingRequest(previewRequestBuilder.build(), null, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } }; // 保存图像到文件 private String saveImageToFile(byte[] data) { File pictureFile = createImageFile(); if (pictureFile == null) { return null; } try (FileOutputStream fos = new FileOutputStream(pictureFile)) { fos.write(data); // 通知媒体库更新 MediaScannerConnection.scanFile(this, new String[]{pictureFile.getAbsolutePath()}, null, (path, uri) -> Log.d(TAG, "图像已保存: " + path)); return pictureFile.getAbsolutePath(); } catch (IOException e) { Log.e(TAG, "保存图像失败: " + e.getMessage()); } return null; } // 创建图像文件 private File createImageFile() { try { // 创建文件名 String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; // 获取存储目录 File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); if (!storageDir.exists()) { storageDir.mkdirs(); } // 创建文件 File imageFile = File.createTempFile( imageFileName, /* 前缀 */ ".jpg", /* 后缀 */ storageDir /* 目录 */ ); return imageFile; } catch (IOException e) { Log.e(TAG, "创建图像文件失败: " + e.getMessage()); } return null; } // 拍照方法 private void takePicture() { if (cameraDevice == null || captureSession == null) { return; } try { // 创建拍照请求 final CaptureRequest.Builder captureBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); captureBuilder.addTarget(imageReader.getSurface()); // 设置自动对焦 captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); // 设置照片方向 int rotation = getWindowManager().getDefaultDisplay().getRotation(); captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation)); // 停止预览 captureSession.stopRepeating(); // 执行拍照 captureSession.capture(captureBuilder.build(), new CameraCaptureSession.CaptureCallback() { @Override public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) { super.onCaptureCompleted(session, request, result); // 拍照完成,显示黑闪效果 runOnUiThread(() -> flash()); } }, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } // 获取照片方向 private int getOrientation(int rotation) { switch (rotation) { case Surface.ROTATION_0: return 90; case Surface.ROTATION_90: return 0; case Surface.ROTATION_180: return 270; case Surface.ROTATION_270: return 180; default: return 90; } } // 拍照黑闪效果 private void flash() { flashView.setVisibility(View.VISIBLE); AlphaAnimation anim = new AlphaAnimation(1.0f, 0.0f); anim.setDuration(200); anim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { flashView.setVisibility(View.INVISIBLE); } @Override public void onAnimationRepeat(Animation animation) { } }); flashView.startAnimation(anim); } // 初始化媒体录制器 private void initMediaRecorder() { try { mediaRecorder = new MediaRecorder(); // 设置音频源 mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置视频源 mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); // 设置输出格式 mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); // 创建视频文件 String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); String videoFileName = "VIDEO_" + timeStamp + ".mp4"; File storageDir = getExternalFilesDir(Environment.DIRECTORY_MOVIES); if (!storageDir.exists()) { storageDir.mkdirs(); } File videoFile = new File(storageDir, videoFileName); lastCapturedPath = videoFile.getAbsolutePath(); // 设置输出文件 mediaRecorder.setOutputFile(videoFile.getAbsolutePath()); // 设置视频尺寸 CameraCharacteristics characteristics = null; try { characteristics = cameraManager.getCameraCharacteristics(cameraId); } catch (CameraAccessException e) { throw new RuntimeException(e); } StreamConfigurationMap map = characteristics.get( CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP); if (map != null) { Size videoSize = map.getOutputSizes(MediaRecorder.class)[0]; mediaRecorder.setVideoSize(videoSize.getWidth(), videoSize.getHeight()); } // 设置视频编码格式 mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); // 设置音频编码格式 mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); // 设置视频比特率 mediaRecorder.setVideoEncodingBitRate(10000000); // 设置视频帧率 mediaRecorder.setVideoFrameRate(30); // 设置方向 int rotation = getWindowManager().getDefaultDisplay().getRotation(); mediaRecorder.setOrientationHint(getOrientation(rotation)); // 准备录制 mediaRecorder.prepare(); } catch (IOException e) { e.printStackTrace(); } } // 开始录制视频 private void startRecording() { if (cameraDevice == null) { return; } try { // 停止预览 captureSession.stopRepeating(); captureSession.abortCaptures(); // 初始化媒体录制器 initMediaRecorder(); // 创建新的捕获会话,用于录制 SurfaceTexture texture = textureView.getSurfaceTexture(); Size previewSize = chooseOptimalSize( cameraManager.getCameraCharacteristics(cameraId) .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP) .getOutputSizes(SurfaceTexture.class), textureView.getWidth(), textureView.getHeight()); texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); Surface previewSurface = new Surface(texture); Surface recorderSurface = mediaRecorder.getSurface(); // 创建录制请求 final CaptureRequest.Builder recordRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); recordRequestBuilder.addTarget(previewSurface); recordRequestBuilder.addTarget(recorderSurface); // 设置自动对焦和曝光 recordRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); recordRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); // 创建新的捕获会话 cameraDevice.createCaptureSession(Arrays.asList(previewSurface, recorderSurface), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { captureSession = session; try { // 开始录制 mediaRecorder.start(); // 开始预览 captureSession.setRepeatingRequest(recordRequestBuilder.build(), null, backgroundHandler); isRecording = true; // runOnUiThread(() -> { // recordButton.setImageResource(R.drawable.ic_launcher_background); // Toast.makeText(MainActivity3.this, "开始录制", // Toast.LENGTH_SHORT).show(); // }); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession session) { runOnUiThread(() -> Toast.makeText(MainActivity3.this, "录制配置失败", Toast.LENGTH_SHORT).show()); } }, backgroundHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } // 停止录制视频 private void stopRecording() { if (!isRecording) { return; } // 停止录制 isRecording = false; // runOnUiThread(() -> recordButton.setImageResource(R.drawable.ic_launcher_foreground)); try { mediaRecorder.stop(); mediaRecorder.reset(); Toast.makeText(this, "视频已保存", Toast.LENGTH_SHORT).show(); // 更新缩略图 runOnUiThread(() -> updateThumbnail(lastCapturedPath)); // 恢复预览 createCameraPreviewSession(); } catch (IllegalStateException e) { e.printStackTrace(); } } // 应用滤镜 private byte[] applyFilter(byte[] originalData) { // 将字节数据转换为Bitmap Bitmap originalBitmap = BitmapFactory.decodeByteArray(originalData, 0, originalData.length); if (originalBitmap == null) { return originalData; } // 根据当前选择的滤镜处理Bitmap Bitmap filteredBitmap; switch (currentFilter) { case 1: // 黑白滤镜 filteredBitmap = applyBlackWhiteFilter(originalBitmap); break; case 2: // 复古滤镜 filteredBitmap = applyVintageFilter(originalBitmap); break; default: // 无滤镜 return originalData; } // 将处理后的Bitmap转换回字节数组 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); filteredBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); // 回收Bitmap资源 originalBitmap.recycle(); filteredBitmap.recycle(); return outputStream.toByteArray(); } // 黑白滤镜 private Bitmap applyBlackWhiteFilter(Bitmap original) { int width = original.getWidth(); int height = original.getHeight(); Bitmap filtered = Bitmap.createBitmap(width, height, original.getConfig()); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int pixel = original.getPixel(x, y); // 获取RGB值 int red = Color.red(pixel); int green = Color.green(pixel); int blue = Color.blue(pixel); // 计算灰度值 int gray = (int) (0.299 * red + 0.587 * green + 0.114 * blue); // 创建新像素(保持透明度不变) int newPixel = (Color.alpha(pixel) << 24) | (gray << 16) | (gray << 8) | gray; filtered.setPixel(x, y, newPixel); } } return filtered; } // 复古滤镜 private Bitmap applyVintageFilter(Bitmap original) { int width = original.getWidth(); int height = original.getHeight(); Bitmap filtered = Bitmap.createBitmap(width, height, original.getConfig()); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { int pixel = original.getPixel(x, y); // 获取RGB值 int red = Color.red(pixel); int green = Color.green(pixel); int blue = Color.blue(pixel); // 复古效果:增加红色,减少蓝色 int newRed = Math.min(255, red + 30); int newGreen = Math.min(255, green + 10); int newBlue = Math.max(0, blue - 30); // 创建新像素 int newPixel = (Color.alpha(pixel) << 24) | (newRed << 16) | (newGreen << 8) | newBlue; filtered.setPixel(x, y, newPixel); } } return filtered; } // 切换滤镜 private void toggleFilter() { currentFilter = (currentFilter + 1) % 3; useFilter = currentFilter != 0; String filterName; switch (currentFilter) { case 0: filterName = "无滤镜"; break; case 1: filterName = "黑白滤镜"; break; case 2: filterName = "复古滤镜"; break; default: filterName = "无滤镜"; } Toast.makeText(this, "当前滤镜: " + filterName, Toast.LENGTH_SHORT).show(); } // 更新缩略图 private void updateThumbnail(String path) { if (path == null) { return; } // 判断是图片还是视频 if (path.endsWith(".jpg")) { // 加载图片缩略图 Bitmap thumbnail = BitmapFactory.decodeFile(path); if (thumbnail != null) { // 缩放缩略图 Bitmap scaled = Bitmap.createScaledBitmap(thumbnail, 100, 150, true); thumbnailView.setImageBitmap(scaled); thumbnail.recycle(); } } else if (path.endsWith(".mp4")) { // 加载视频缩略图 MediaMetadataRetriever retriever = new MediaMetadataRetriever(); try { retriever.setDataSource(path); Bitmap thumbnail = retriever.getFrameAtTime(); if (thumbnail != null) { Bitmap scaled = Bitmap.createScaledBitmap(thumbnail, 100, 150, true); thumbnailView.setImageBitmap(scaled); thumbnail.recycle(); } } catch (IllegalArgumentException e) { e.printStackTrace(); } finally { try { retriever.release(); } catch (IOException e) { throw new RuntimeException(e); } } } } // 切换相机(前置/后置) private void switchCamera() { // 关闭当前相机 closeCamera(); try { // 查找另一个相机 for (String id : cameraManager.getCameraIdList()) { if (!id.equals(cameraId)) { CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(id); Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING); if (facing != null) { cameraId = id; break; } } } // 重新打开相机 openCamera(); } catch (CameraAccessException e) { e.printStackTrace(); } } // 设置按钮点击事件 private void setupButtonListeners() { // 设置按钮点击事件 Log.i(TAG, "设置按钮点击事件"); captureButton.setOnClickListener(v -> { if (!isRecording) { takePicture(); } }); recordButton.setOnClickListener(v -> { if (isRecording) { stopRecording(); } else { startRecording(); } }); switchButton.setOnClickListener(v -> switchCamera()); filterButton.setOnClickListener(v -> toggleFilter()); // 点击缩略图查看原图 thumbnailView.setOnClickListener(v -> { if (lastCapturedPath != null) { viewMediaFile(lastCapturedPath); } }); } // 查看媒体文件 private void viewMediaFile(String path) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); File file = new File(path); Uri uri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", file); intent.setDataAndType(uri, path.endsWith(".jpg") ? "image/*" : "video/*"); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(intent); } @Override protected void onResume() { super.onResume(); // 1. 启动后台线程(必须先执行) startBackgroundThread(); Log.i(TAG, "判断是否有相机权限"); List<String> permissions=new ArrayList<>(); permissions.add(Manifest.permission.CAMERA); permissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); permissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); permissions.add(Manifest.permission.RECORD_AUDIO); if (!checkPermission(permissions)){ Log.i(TAG, "没有相机权限——>开始请求相机权限"); ActivityCompat.requestPermissions(this, permissions.toArray(new String[0]), REQUEST_CAMERA_PERMISSIONS); } // // 设置预览监听 textureView.setSurfaceTextureListener(surfaceTextureListener); // 设置按钮监听 setupButtonListeners(); Log.i(TAG, "授权判断"); if (textureView.isAvailable()) { Log.i(TAG, "授权成功"); openCamera(); } } // 新增辅助方法:检查单权限 private boolean checkPermission(List<String> permissions) { boolean isPermissionFlag=true; for (String permission : permissions) { if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED){ isPermissionFlag=false; } } return isPermissionFlag; } @Override protected void onPause() { closeCamera(); stopBackgroundThread(); super.onPause(); } // 打开后台线程 private void startBackgroundThread() { backgroundThread = new HandlerThread("CameraBackground"); backgroundThread.start(); backgroundHandler = new Handler(backgroundThread.getLooper()); } // 停止后台线程 private void stopBackgroundThread() { backgroundThread.quitSafely(); try { backgroundThread.join(); backgroundThread = null; backgroundHandler = null; } catch (InterruptedException e) { e.printStackTrace(); } } // 关闭相机 private void closeCamera() { if (captureSession != null) { captureSession.close(); captureSession = null; } if (cameraDevice != null) { cameraDevice.close(); cameraDevice = null; } if (imageReader != null) { imageReader.close(); imageReader = null; } if (mediaRecorder != null) { mediaRecorder.release(); mediaRecorder = null; } } }为什么会闪退
09-18
package com.awspaas.user.apps.app20250410155149; import com.actionsoft.bpms.bpmn.engine.core.delegate.ProcessExecutionContext; import com.actionsoft.bpms.bpmn.engine.listener.ExecuteListener; import com.actionsoft.bpms.commons.formfile.model.FormFileModel; import com.actionsoft.bpms.commons.formfile.model.delegate.FormFile; import com.actionsoft.bpms.server.UserContext; import com.actionsoft.bpms.server.fs.DCContext; import com.actionsoft.sdk.local.SDK; import io.transwarp.guardian.federation.org.apache.commons.lang.WordUtils; import org.docx4j.Docx4J; import org.docx4j.convert.out.FOSettings; import org.docx4j.fonts.IdentityPlusMapper; import org.docx4j.fonts.Mapper; import org.docx4j.fonts.PhysicalFont; import org.docx4j.fonts.PhysicalFonts; import org.docx4j.openpackaging.packages.WordprocessingMLPackage; import java.io.*; import java.net.URL; import java.util.List; public class TestWordPDFEvent extends ExecuteListener { @Override public void execute(ProcessExecutionContext pec) throws Exception { String boid = pec.getBO("BO_EU_GJPB001").getId(); UserContext userContext = pec.getUserContext(); String uid = userContext.getUID(); String processid = pec.getProcessInstance().getId(); String taskid = pec.getTaskInstance().getId(); List<FormFile> files = SDK.getBOAPI().getFiles(boid, "FJ"); //WordToPdfConverter wordToPdfConverter = new WordToPdfConverter(); if (files.isEmpty()||files==null||files.size()==0){ }else{ for (FormFile ff:files) { DCContext fileDCContext = SDK.getBOAPI().getFileDCContext(ff); //获取到docx文件的文件路径 String docxPath = fileDCContext.getFilePath(); String PdfPath = getCorrespondingPdfPath(docxPath); /*可以转换出文档的英文和图片 DocxToPdf docxToPdf = new DocxToPdf(); docxToPdf.PDFZH(docxPath,PdfPath); */ //wordToPdfConverter.convertWordToPdf(docxPath,PdfPath); //WordToPdfConverter converter = new WordToPdfConverter(); //DocxToPdfInputStream docxToPdfInputStream = new DocxToPdfInputStream(); // 加载 DOCX 文件 WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new File(docxPath)); // 自动发现系统字体 PhysicalFonts.discoverPhysicalFonts(); // 手动注册字体文件 /* URL fontUrl = WordUtils.class.getClassLoader().getResource("E:/PingTaiKu/aws64GA45/release/apps/install/com.awspaas.user.apps.app20250410155149/template/fonts/MicrosoftYaHei-Bold-01.ttf"); if (fontUrl == null) { throw new FileNotFoundException("字体文件未找到,请检查 resources/fonts/SimSun.ttf 是否存在"); } PhysicalFonts.addPhysicalFonts("SimSun", fontUrl); */ // 创建字体映射器 Mapper fontMapper = new IdentityPlusMapper(); // 添加字体到PhysicalFonts //PhysicalFonts.addPhysicalFonts("SimSun", fontUrl); //PhysicalFont font = PhysicalFonts.get("SimSun"); PhysicalFont font = PhysicalFonts.get("SimSun"); fontMapper.put("PMingLiU", font); fontMapper.put("宋体", font); fontMapper.put("Calibri", font); // 尝试映射 PMingLiU 字体 /* PhysicalFont pmingliuFont = PhysicalFonts.get("PMingLiU"); if (pmingliuFont != null) { fontMapper.put("PMingLiU", pmingliuFont); }else{ fontMapper.put("PMingLiU", font); } if (font != null) { fontMapper.put("宋体", font); } // 尝试映射 Calibri 字体 PhysicalFont calibriFont = PhysicalFonts.get("Calibri"); if (calibriFont != null) { fontMapper.put("Calibri", calibriFont); }else{ fontMapper.put("Calibri", font); } */ // 设置字体映射器 wordMLPackage.setFontMapper(fontMapper); // 映射中文字体,这里以宋体为例 // 创建 FOSettings 对象 FOSettings foSettings = Docx4J.createFOSettings(); foSettings.setWmlPackage(wordMLPackage); // 输出 PDF 文件 OutputStream os = new FileOutputStream(new File(PdfPath)); Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL); os.close(); File file = new File(PdfPath); // 检查文件是否存在 if (file.exists()) { System.out.println("文件存在: " + file.getAbsolutePath()); //通过获取PDF文件把文件放入PDF中 FormFileModel formFileModel = new FormFileModel(); formFileModel.setAppId("com.awspaas.user.apps.app20250410155149"); //formFileModel.setCreateDate(formFile.getCreateDate()); formFileModel.setCreateUser(uid); formFileModel.setId(SDK.getRuleAPI().executeAtScript("@uuid"));//必须字段 formFileModel.setFileName(file.getName());//必须字段 formFileModel.setBoName("BO_EU_GJPB001");//必须字段 formFileModel.setBoId(boid);//必须字段 formFileModel.setTaskInstId(taskid); formFileModel.setProcessInstId(processid); formFileModel.setBoItemName("ZHPDF");//必须字段 InputStream pdfInputStream = new FileInputStream(file); SDK.getBOAPI().upFile(formFileModel,pdfInputStream); } else { System.out.println("文件不存在!"); } // 设置字体映射 /* Mapper fontMapper = new IdentityPlusMapper(); fontMapper.put("宋体", PhysicalFonts.get("SimSun")); fontMapper.put("黑体", PhysicalFonts.get("SimHei")); fontMapper.put("楷体_GB2312", PhysicalFonts.get("KaiTi_GB2312")); fontMapper.put("仿宋_GB2312", PhysicalFonts.get("FangSong_GB2312")); fontMapper.put("新宋体", PhysicalFonts.get("NSimSun")); fontMapper.put("仿宋", PhysicalFonts.get("FangSong")); fontMapper.put("楷体", PhysicalFonts.get("KaiTi")); fontMapper.put("微软正黑", PhysicalFonts.get("Microsoft JhengHei")); fontMapper.put("微软雅黑", PhysicalFonts.get("Microsoft YaHei")); fontMapper.put("细明体", PhysicalFonts.get("MingLiU")); fontMapper.put("标楷体", PhysicalFonts.get("DFKai-SB")); fontMapper.put("新细明体", PhysicalFonts.get("PMingLiU")); fontMapper.put("华文宋体", PhysicalFonts.get("STSong")); fontMapper.put("华文中宋", PhysicalFonts.get("STZhongsong")); fontMapper.put("华文仿宋", PhysicalFonts.get("STFangsong")); fontMapper.put("华文彩云", PhysicalFonts.get("STCaiyun")); fontMapper.put("华文琥珀", PhysicalFonts.get("STHupo")); fontMapper.put("华文隶书", PhysicalFonts.get("STLiti")); fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai")); fontMapper.put("华文新魏", PhysicalFonts.get("STXinwei")); fontMapper.put("华文细黑", PhysicalFonts.get("STXihei")); fontMapper.put("华文楷体", PhysicalFonts.get("STKaiti")); fontMapper.put("方正舒体", PhysicalFonts.get("FZShuTi")); fontMapper.put("方正姚体", PhysicalFonts.get("FZYaoti")); fontMapper.put("幼圆", PhysicalFonts.get("YouYuan")); fontMapper.put("隶书", PhysicalFonts.get("LiSu")); */ /* try { //ByteArrayInputStream byteArrayInputStream = docxToPdfInputStream.convertDocxToPdfInputStream(docxPath); //ByteArrayInputStream pdfInputStream = docxToHtmlConverter.convertDocxToPdfInputStream(docxFilePath); // 这里可以使用 pdfInputStream 进行后续操作 // docxToPdfInputStream.convertDocxToPdf(docxPath); System.out.println("PDF 文件已生成:" + docxPath.replaceAll("\\.docx$", ".pdf")); } catch (IOException e) { e.printStackTrace(); } */ /* try { WordToPdfConverter.convertWordToPdf(docxPath, PdfPath); System.out.println("Conversion successful!"); } catch (IOException e) { System.err.println("Error during conversion: " + e.getMessage()); } */ /* try { File wordFile = new File(docxPath); if (!wordFile.exists()) { System.out.println("请将Word文档命名为input.docx并放在项目根目录"); return; } InputStream pdfInputStream = converter.convertWordToPdfStream(wordFile); System.out.println("Word转PDF成功!PDF输入流已生成"); // 这里可以继续处理PDF输入流,如上载到云存储或进行其他操作 pdfInputStream.close(); } catch (Exception e) { System.err.println("转换失败: " + e.getMessage()); e.printStackTrace(); } */ } } } public static String getCorrespondingPdfPath(String docxPath) { if (!docxPath.toLowerCase().endsWith(".docx")) { throw new IllegalArgumentException("Only .docx files supported"); } return docxPath.substring(0, docxPath.length() - 5) + ".pdf"; } } 为什么我利用这段代码转换后的pdf文件,除了中文变#号外,文档的格式都变了,例如:添加了红色的竖线,转换后就没了
11-20
你帮我检查一下,RoutePlanActivity这样改对不对?package com.example.bus; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.activity.OnBackPressedCallback; import com.amap.api.location.AMapLocation; import com.amap.api.location.AMapLocationClient; import com.amap.api.location.AMapLocationClientOption; import com.amap.api.location.AMapLocationListener; import com.amap.api.maps.AMap; import com.amap.api.maps.CameraUpdateFactory; import com.amap.api.maps.MapView; import com.amap.api.maps.model.LatLng; import com.amap.api.maps.model.LatLngBounds; import com.amap.api.maps.model.PolylineOptions; import com.amap.api.services.core.LatLonPoint; import com.amap.api.services.route.BusPath; import com.amap.api.services.route.BusRouteResult; import com.amap.api.services.route.BusStep; import com.amap.api.services.route.RouteSearch; import java.util.ArrayList; import java.util.List; public class RoutePlanActivity extends AppCompatActivity implements RouteSearch.OnRouteSearchListener, AMapLocationListener { // 来源类型常量 public static final String EXTRA_SOURCE = "extra_source"; public static final int SOURCE_FROM_HOME_SEARCH = 1001; public static final int SOURCE_FROM_MAP_DIRECT = 1002; private MapView mapView; private AMap aMap; private RouteSearch routeSearch; private RecyclerView recyclerSteps; private TextView tvRouteInfo; // 持久显示路线信息 private boolean isSearching = false; private int sourceType = -1; // 定位相关 private AMapLocationClient locationClient; private LatLonPoint currentLocation; // 存储定位到的“我的位置” private LatLonPoint targetPoint; // 存储目标点(终点) // 新增:防止重复发起搜索 private boolean hasStartedSearch = false; // 🔥 控制只发起一次搜索 // 新增:用于管理返回键行为 private OnBackPressedCallback onBackPressedCallback; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_route_plan); // 获取来源 sourceType = getIntent().getIntExtra(EXTRA_SOURCE, -1); // 获取目标位置 double targetLat = getIntent().getDoubleExtra("target_lat", 0); double targetLng = getIntent().getDoubleExtra("target_lng", 0); if (targetLat == 0 || targetLng == 0) { Toast.makeText(this, "目标位置无效", Toast.LENGTH_SHORT).show(); finish(); return; } targetPoint = new LatLonPoint(targetLat, targetLng); // 初始化视图 mapView = findViewById(R.id.map_view); recyclerSteps = findViewById(R.id.recycler_steps); tvRouteInfo = findViewById(R.id.tv_route_info); // 显示路线信息(持续) mapView.onCreate(savedInstanceState); if (aMap == null) { aMap = mapView.getMap(); } try { routeSearch = new RouteSearch(this); routeSearch.setRouteSearchListener(this); } catch (Exception e) { Log.e("RoutePlan", "RouteSearch 初始化失败", e); tvRouteInfo.setText("路线服务初始化失败"); finish(); return; } if (getSupportActionBar() != null) { getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setTitle("公交路线规划"); } // 初始化定位 initLocation(); // 如果来自 MapFragment,直接发起搜索(不需要等定位) if (sourceType == SOURCE_FROM_MAP_DIRECT) { startRouteSearch(); // 🔥 提前发起搜索,不等待定位 } // 🔥 替换 onBackPressed:注册 OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { if (sourceType == SOURCE_FROM_MAP_DIRECT) { Intent intent = new Intent(RoutePlanActivity.this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.putExtra("open_tab", "map"); startActivity(intent); finish(); } else { setEnabled(false); getOnBackPressedDispatcher().onBackPressed(); setEnabled(true); } } }; getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback); } /** * 初始化定位客户端 */ private void initLocation() { try { locationClient = new AMapLocationClient(this); AMapLocationClientOption option = new AMapLocationClientOption(); option.setOnceLocation(true); option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy); option.setMockEnable(false); locationClient.setLocationOption(option); locationClient.setLocationListener(this); locationClient.startLocation(); tvRouteInfo.setText("正在获取您的位置..."); } catch (Exception e) { Log.e("RoutePlan", "定位初始化失败", e); tvRouteInfo.setText("定位服务启动失败"); finish(); } } /** * 发起公交路线搜索(增加防重发机制) */ private void startRouteSearch() { if (isSearching || hasStartedSearch) return; hasStartedSearch = true; // ✅ 必须第一时间标记,防止定位回调干扰 LatLonPoint start = null; if (sourceType == SOURCE_FROM_HOME_SEARCH) { if (currentLocation == null) { Log.e("RoutePlan", "📍 定位未完成,无法发起 HOME_SEARCH"); tvRouteInfo.setText("无法获取您的位置,请稍后重试"); finish(); return; } start = currentLocation; Log.d("RoutePlan", "🏠 使用定位位置作为起点: " + start.getLatitude() + "," + start.getLongitude()); } else if (sourceType == SOURCE_FROM_MAP_DIRECT) { double startLat = getIntent().getDoubleExtra("start_lat", 0); double startLng = getIntent().getDoubleExtra("start_lng", 0); if (Math.abs(startLat) < 1e-6 || Math.abs(startLng) < 1e-6) { Log.e("RoutePlan", "❌ MapDirect: 起点坐标无效 (" + startLat + ", " + startLng + ")"); tvRouteInfo.setText("起点坐标错误"); finish(); return; } start = new LatLonPoint(startLat, startLng); Log.d("RoutePlan", "🗺️ 使用地图中心作为起点: " + start.getLatitude() + "," + start.getLongitude()); } else { tvRouteInfo.setText("未知操作来源"); Log.e("RoutePlan", "❌ 未知来源: " + sourceType); finish(); return; } // 构建查询 RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(start, targetPoint); RouteSearch.BusRouteQuery query = new RouteSearch.BusRouteQuery(fromAndTo, RouteSearch.BUS_DEFAULT, "全国", 0); isSearching = true; tvRouteInfo.setText("正在规划路线..."); routeSearch.calculateBusRouteAsyn(query); } private void addStartMarker(LatLonPoint startPoint) { if (startPoint == null || aMap == null) return; aMap.addMarker(new com.amap.api.maps.model.MarkerOptions() .position(new LatLng(startPoint.getLatitude(), startPoint.getLongitude())) .title("出发点")); } @Override public void onLocationChanged(AMapLocation loc) { if (loc != null && loc.getErrorCode() == 0) { currentLocation = new LatLonPoint(loc.getLatitude(), loc.getLongitude()); Log.d("RoutePlan", "✅ 定位成功: " + loc.getLatitude() + "," + loc.getLongitude()); // 只有来自 SearchResultActivity 才在此处开始搜索 if (sourceType == SOURCE_FROM_HOME_SEARCH && !hasStartedSearch) { startRouteSearch(); } // 🔥 其他情况(如 MapDirect)已经搜过或不需要定位数据,无需处理 } else { Log.e("RoutePlan", "❌ 定位失败: " + (loc != null ? loc.getErrorInfo() : "null")); tvRouteInfo.setText("定位失败,请检查权限"); Toast.makeText(this, "无法获取位置", Toast.LENGTH_LONG).show(); finish(); } } @Override public void onBusRouteSearched(BusRouteResult result, int rCode) { isSearching = false; if (rCode != 1000 || result == null || result.getPaths().isEmpty()) { tvRouteInfo.setText("未找到公交路线"); return; } BusPath bestPath = result.getPaths().get(0); // 默认最优路线 drawRouteOnMap(bestPath); StepAdapter adapter = new StepAdapter(bestPath.getSteps()); recyclerSteps.setLayoutManager(new LinearLayoutManager(this)); recyclerSteps.setAdapter(adapter); // ✅ 手动计算总时间和换乘次数 long totalDuration = 0; int busRideCount = 0; for (BusStep step : bestPath.getSteps()) { // 公交段 if (step.getBusLine() != null && step.getBusLine().getDuration() > 0) { totalDuration += step.getBusLine().getDuration(); busRideCount++; } // 步行段 else if (step.getWalk() != null) { totalDuration += step.getWalk().getDuration(); } } LatLonPoint start = null; if (sourceType == SOURCE_FROM_HOME_SEARCH && currentLocation != null) { start = currentLocation; } else if (sourceType == SOURCE_FROM_MAP_DIRECT) { double slat = getIntent().getDoubleExtra("start_lat", 0); double slng = getIntent().getDoubleExtra("start_lng", 0); if (Math.abs(slat) > 1e-6 && Math.abs(slng) > 1e-6) { start = new LatLonPoint(slat, slng); } } if (start != null) { addStartMarker(start); // 红色小点标出起点 } int transferNum = Math.max(0, busRideCount - 1); // 显示路线概要信息 String info = String.format("⏱️ %d分钟 | 💰 ¥%.2f | 🚌 %d次换乘", totalDuration / 60, bestPath.getCost(), transferNum); tvRouteInfo.setText(info); } /** * 绘制路线 */ private void drawRouteOnMap(BusPath path) { aMap.clear(); List<LatLng> allPoints = new ArrayList<>(); for (BusStep step : path.getSteps()) { // 公交段 if (step.getBusLine() != null && step.getBusLine().getPolyline() != null) { for (LatLonPoint point : step.getBusLine().getPolyline()) { allPoints.add(new LatLng(point.getLatitude(), point.getLongitude())); } } // 步行段 else if (step.getWalk() != null && step.getWalk().getPolyline() != null) { for (LatLonPoint point : step.getWalk().getPolyline()) { allPoints.add(new LatLng(point.getLatitude(), point.getLongitude())); } } // 出入口 fallback else { if (step.getEntrance() != null && step.getEntrance().getLatLonPoint() != null) { LatLonPoint p = step.getEntrance().getLatLonPoint(); allPoints.add(new LatLng(p.getLatitude(), p.getLongitude())); } if (step.getExit() != null && step.getExit().getLatLonPoint() != null) { LatLonPoint p = step.getExit().getLatLonPoint(); allPoints.add(new LatLng(p.getLatitude(), p.getLongitude())); } } } if (!allPoints.isEmpty()) { PolylineOptions options = new PolylineOptions() .addAll(allPoints) .color(0xFF4A90E2) .width(12f); aMap.addPolyline(options); // 聚焦整条路线 LatLngBounds.Builder builder = new LatLngBounds.Builder(); for (LatLng point : allPoints) { builder.include(point); } aMap.animateCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 100)); } else { tvRouteInfo.setText("路线数据为空"); } } @Override public boolean onSupportNavigateUp() { getOnBackPressedDispatcher().onBackPressed(); return true; } // 以下回调不处理 @Override public void onDriveRouteSearched(com.amap.api.services.route.DriveRouteResult r, int c) {} @Override public void onWalkRouteSearched(com.amap.api.services.route.WalkRouteResult r, int c) {} @Override public void onRideRouteSearched(com.amap.api.services.route.RideRouteResult r, int c) {} // 生命周期方法 @Override protected void onResume() { super.onResume(); mapView.onResume(); } @Override protected void onPause() { super.onPause(); mapView.onPause(); } @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); if (routeSearch != null) { routeSearch.setRouteSearchListener(null); } if (locationClient != null) { locationClient.onDestroy(); } } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } } MapFragment有点没看懂怎么改,目前代码如下:package com.example.bus.ui.map; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import com.amap.api.maps.MapView; import com.amap.api.maps.AMap; import com.amap.api.maps.model.LatLng; //import com.example.bus.R; //import com.example.bus.databinding.FragmentMapBinding; import com.amap.api.services.core.AMapException; import com.amap.api.maps.CameraUpdateFactory; import com.amap.api.maps.UiSettings; import com.amap.api.services.poisearch.PoiResult; import com.amap.api.services.poisearch.PoiSearch; import com.example.bus.R; import com.example.bus.RoutePlanActivity; import com.example.bus.databinding.FragmentMapBinding; import com.amap.api.services.core.PoiItem; import com.amap.api.services.core.LatLonPoint; // MapView 已在 XML 中声明,无需额外 import(会自动识别) public class MapFragment extends Fragment { private FragmentMapBinding binding; private MapView mapView; // 高德地图视图 private AMap aMap; // 地图控制器 private boolean isFirstLocationSet = false; // 防止反复跳转 @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 初始化 ViewModel 和 ViewBinding binding = FragmentMapBinding.inflate(inflater, container, false); View root = binding.getRoot(); //绑定 MapView mapView = root.findViewById(R.id.map_view); mapView.onCreate(savedInstanceState); // 必须调用生命周期方法 // 初始化地图 initMap(); if (binding.mapSearch != null) { binding.mapSearch.setOnClickListener(v -> { String keyword = binding.mapInput2.getText().toString().trim(); if (keyword.isEmpty()) { Toast.makeText(requireContext(), "请输入终点", Toast.LENGTH_SHORT).show(); return; } PoiSearch.Query query = new PoiSearch.Query(keyword, "", "全国"); query.setPageSize(10); query.setPageNum(0); try { PoiSearch search = new PoiSearch(requireContext(), query); search.setOnPoiSearchListener(new PoiSearch.OnPoiSearchListener() { @Override public void onPoiSearched(PoiResult result, int rCode) { requireActivity().runOnUiThread(() -> { if (rCode == 1000 && result != null && !result.getPois().isEmpty()) { PoiItem item = result.getPois().get(0); LatLonPoint point = item.getLatLonPoint(); // ✅ 使用地图当前中心作为起点 LatLng center = aMap.getCameraPosition().target; Intent intent = new Intent(requireContext(), RoutePlanActivity.class); intent.putExtra(RoutePlanActivity.EXTRA_SOURCE, RoutePlanActivity.SOURCE_FROM_MAP_DIRECT); intent.putExtra("start_lat", center.latitude); intent.putExtra("start_lng", center.longitude); intent.putExtra("target_lat", point.getLatitude()); intent.putExtra("target_lng", point.getLongitude()); intent.putExtra("target_title", item.getTitle()); startActivity(intent); } else { handlePoiSearchError(rCode); } }); } @Override public void onPoiItemSearched(PoiItem item, int rCode) {} }); search.searchPOIAsyn(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(requireContext(), "搜索失败:" + e.getMessage(), Toast.LENGTH_LONG).show(); } }); } return root; } private void handlePoiSearchError(int rCode) { String errorMsg; switch (rCode) { case 1101: errorMsg = "网络连接异常"; break; case 1102: errorMsg = "网络响应超时"; break; case 1103: errorMsg = "解析异常"; break; case 1104: errorMsg = "请求参数非法"; break; case 1200: errorMsg = "API Key 不存在"; break; case 1202: errorMsg = "签名验证失败(SHA1/包名不匹配)"; break; case 1206: errorMsg = "API Key 权限不足(未开通 POI 搜索服务)"; break; default: errorMsg = "未知错误: " + rCode; break; } Toast.makeText(requireContext(), "搜索失败: " + errorMsg, Toast.LENGTH_LONG).show(); } /** * 初始化地图 */ private void initMap() { if (aMap == null) { aMap = mapView.getMap(); UiSettings uiSettings = aMap.getUiSettings(); uiSettings.setZoomControlsEnabled(true); // 显示缩放按钮 uiSettings.setCompassEnabled(true); // 显示指南针 uiSettings.setMyLocationButtonEnabled(false); // 我们自己控制定位行为 } } @Override public void onResume() { super.onResume(); //每次恢复可见时都检查权限状态 mapView.onResume(); // ✅ 直接开启定位图层(信任 MainActivity 的判断) if (aMap != null) { aMap.setMyLocationEnabled(true); // 只第一次进入时移动相机 if (!isFirstLocationSet) { LatLng defaultLoc = new LatLng(39.909186, 116.397411); aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(defaultLoc, 12f)); isFirstLocationSet = true; } } } @Override public void onPause() { super.onPause(); mapView.onPause(); } @Override public void onDestroyView() { super.onDestroyView(); if (mapView != null) { mapView.onDestroy(); } binding = null; } @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } } 按照你刚刚所说的方案给我提供完整代码,其他的地方不动,不要乱改东西
11-18
package com.example.skin; import android.content.Context; import android.graphics.Bitmap; import android.util.Log; import org.tensorflow.lite.DataType; import org.tensorflow.lite.Interpreter; import org.tensorflow.lite.support.common.ops.NormalizeOp; import org.tensorflow.lite.support.image.ImageProcessor; import org.tensorflow.lite.support.image.TensorImage; import org.tensorflow.lite.support.image.ops.ResizeOp; import org.tensorflow.lite.support.image.ops.ResizeWithCropOrPadOp; import org.tensorflow.lite.support.tensorbuffer.TensorBuffer; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.List; public class SkinClassifier { private static final String TAG = "SkinClassifier"; private static final int INPUT_SIZE = 224; // 模型输入尺寸 private static final int NUM_CHANNELS = 3; // RGB通道 private static final int NUM_CLASSES = 3; // 分类类别数 private final Interpreter tflite; private final ImageProcessor imageProcessor; public SkinClassifier(Context context) throws IOException { // 1. 从ml文件夹加载模型文件 ByteBuffer modelBuffer = loadModelFile(context, "skin_classifier.tflite"); // 2. 初始化Interpreter Interpreter.Options options = new Interpreter.Options(); options.setNumThreads(4); // 使用4个线程加速推理 tflite = new Interpreter(modelBuffer, options); // 3. 初始化图像处理器 imageProcessor = new ImageProcessor.Builder() .add(new ResizeWithCropOrPadOp(INPUT_SIZE, INPUT_SIZE)) .add(new ResizeOp(INPUT_SIZE, INPUT_SIZE, ResizeOp.ResizeMethod.BILINEAR)) .add(new NormalizeOp(0f, 255f)) // 归一化处理 .build(); // 打印输入输出张量信息 Log.i(TAG, "输入张量: " + tflite.getInputTensor(0).shape()[1] + "x" + tflite.getInputTensor(0).shape()[2] + "x" + tflite.getInputTensor(0).shape()[3]); Log.i(TAG, "输出张量: " + tflite.getOutputTensor(0).shape()[1]); } // 从ml文件夹加载模型 private ByteBuffer loadModelFile(Context context, String modelName) throws IOException { String resourceName = modelName.replace(".tflite", "").toLowerCase(); int resId = context.getResources().getIdentifier( resourceName, "raw", context.getPackageName()); if (resId == 0) { throw new IOException("模型资源未找到: " + resourceName); } try (InputStream inputStream = context.getResources().openRawResource(resId)) { byte[] modelBytes = new byte[inputStream.available()]; inputStream.read(modelBytes); // 修复方案:直接创建只读缓冲区 return (ByteBuffer) ByteBuffer.allocateDirect(modelBytes.length) .order(ByteOrder.nativeOrder()) .put(modelBytes) .asReadOnlyBuffer() // 在ByteBuffer上调用 .rewind(); // 重置位置指针 } } // 执行分类 public List<Category> classify(Bitmap bitmap) { if (bitmap == null) { Log.w(TAG, "输入Bitmap为空"); return new ArrayList<>(); } try { // 使用TensorBuffer直接处理 TensorImage tensorImage = new TensorImage(DataType.FLOAT32); tensorImage.load(bitmap); TensorImage processedImage = imageProcessor.process(tensorImage); // 自动处理输入输出 TensorBuffer inputBuffer = processedImage.getTensorBuffer(); TensorBuffer outputBuffer = TensorBuffer.createFixedSize( new int[]{1, NUM_CLASSES}, DataType.FLOAT32); // 执行推理 tflite.run(inputBuffer.getBuffer(), outputBuffer.getBuffer()); // 解析结果 return parseOutput(outputBuffer.getFloatArray()); } catch (Exception e) { Log.e(TAG, "分类错误", e); return new ArrayList<>(); } } public void close() { if (tflite != null) { tflite.close(); Log.i(TAG, "模型资源已释放"); } } // 解析模型输出 private List<Category> parseOutput(float[] probabilities) { List<Category> results = new ArrayList<>(); // 假设类别顺序: [0]油性, [1]干性, [2]中性 String[] labels = {"Dry", "Normal", "Oily"}; for (int i = 0; i < probabilities.length; i++) { results.add(new Category(labels[i], probabilities[i])); } // 按置信度排序 results.sort((c1, c2) -> Float.compare(c2.confidence, c1.confidence)); return results; } // 自定义分类结果类 public static class Category { public final String label; public final float confidence; public Category(String label, float confidence) { this.label = label; this.confidence = confidence; } } }上述为SkinClassifier的代码package com.example.skin; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.core.content.FileProvider; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; public class MainActivity extends AppCompatActivity { private static final int CAMERA_PERMISSION_CODE = 100; private static final int CAMERA_REQUEST_CODE = 101; private static final int PICK_IMAGE_REQUEST = 102; private String currentPhotoPath; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 设置点击监听器 findViewById(R.id.takePhotoBtn).setOnClickListener(v -> checkCameraPermission()); findViewById(R.id.selectPhotoBtn).setOnClickListener(v -> { // 这里可以添加从相册选择照片的功能 Toast.makeText(this, "相册功能待实现", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, PICK_IMAGE_REQUEST); }); } private void checkCameraPermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, CAMERA_PERMISSION_CODE); } else { openCamera(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == CAMERA_PERMISSION_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { openCamera(); } else { Toast.makeText(this, "需要摄像头权限才能拍照", Toast.LENGTH_SHORT).show(); } } } private void openCamera() { Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (cameraIntent.resolveActivity(getPackageManager()) != null) { File photoFile = createImageFile(); if (photoFile != null) { Uri photoURI = FileProvider.getUriForFile(this, "com.example.skin.fileprovider", photoFile); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); startActivityForResult(cameraIntent, CAMERA_REQUEST_CODE); } } } private File createImageFile() { String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); String imageFileName = "SKIN_ANALYSIS_" + timeStamp + "_"; File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); File image = null; try { image = File.createTempFile( imageFileName, ".jpg", storageDir ); currentPhotoPath = image.getAbsolutePath(); } catch (IOException e) { e.printStackTrace(); } return image; } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != RESULT_OK) return; if (requestCode == CAMERA_REQUEST_CODE) { // 相机拍照处理 Intent analysisIntent = new Intent(this, AnalysisActivity.class); analysisIntent.putExtra("image_path", currentPhotoPath); startActivity(analysisIntent); } else if (requestCode == PICK_IMAGE_REQUEST && data != null) { // 相册选择处理 Uri selectedImage = data.getData(); String[] filePathColumn = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query( selectedImage, filePathColumn, null, null, null); if (cursor != null && cursor.moveToFirst()) { int columnIndex = cursor.getColumnIndex(filePathColumn[0]); String imagePath = cursor.getString(columnIndex); cursor.close(); Intent analysisIntent = new Intent(this, AnalysisActivity.class); analysisIntent.putExtra("image_path", imagePath); startActivity(analysisIntent); //跳转到皮肤分析界面后可点击分享按钮,实现分享功能 } } } }上述为mainactivity的代码package com.example.skin; import android.annotation.SuppressLint; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.net.Uri; import android.os.Bundle; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.FileProvider; import com.example.skin.SkinClassifier; import java.io.File; import java.util.List; public class AnalysisActivity extends AppCompatActivity { private ImageView previewImage; private TextView resultText; private Button retryButton; private SkinClassifier classifier; private String imagePath; private Button homeButton; private Button shareButton; private String skinTypeResult = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_analysis); // 初始化UI previewImage = findViewById(R.id.previewImage); resultText = findViewById(R.id.resultText); retryButton = findViewById(R.id.retryButton); // 获取传递的图片路径 imagePath = getIntent().getStringExtra("image_path"); // 显示图片 Bitmap bitmap = BitmapFactory.decodeFile(imagePath); previewImage.setImageBitmap(bitmap); // 初始化分类器 initClassifier(); // 重拍按钮事件 retryButton.setOnClickListener(v -> finish()); // 绑定新按钮 homeButton = findViewById(R.id.homeButton); shareButton = findViewById(R.id.shareButton); // 设置监听器 homeButton.setOnClickListener(v -> returnToMain()); shareButton.setOnClickListener(v -> shareResults()); } private void initClassifier() { new Thread(() -> { try { classifier = new SkinClassifier(this); runOnUiThread(this::performAnalysis); } catch (Exception e) { runOnUiThread(() -> { resultText.setText("模型加载失败"); resultText.setTextColor(Color.RED); }); } }).start(); } // 返回主界面功能 private void returnToMain() { Intent mainIntent = new Intent(this, MainActivity.class); mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); // 清除Activity栈 startActivity(mainIntent); finish(); // 结束当前Activity } // 分享功能实现 private void shareResults() { // 1. 获取分享内容 TextView resultView = findViewById(R.id.resultText); TextView adviceView = findViewById(R.id.adviceText); String resultText = skinTypeResult + "\n\n" + resultView.getText().toString() + "\n\n" + adviceView.getText().toString(); // 2. 创建分享图片的URI Uri imageUri = FileProvider.getUriForFile( this, "com.example.skin.fileprovider", new File(imagePath) ); // 3. 创建分享Intent Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("image/*"); shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri); shareIntent.putExtra(Intent.EXTRA_TEXT, resultText); shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 4. 启动分享选择器 startActivity(Intent.createChooser( shareIntent, "分享皮肤分析结果" )); } @SuppressLint("SetTextI18n") private void performAnalysis() { new Thread(() -> { try { Bitmap bitmap = BitmapFactory.decodeFile(imagePath); if (bitmap == null) return; // 执行预测 long start = System.currentTimeMillis(); List<SkinClassifier.Category> results = classifier.classify(bitmap); long duration = System.currentTimeMillis() - start; runOnUiThread(() -> { if (results != null && !results.isEmpty()) { SkinClassifier.Category top = results.get(0); String skinType = getSkinTypeDisplayName(top.label); @SuppressLint("DefaultLocale") String resultMsg = String.format( "✅ 预测结果: %s\n\n" + "🔬 置信度: %.1f%%\n" + "⏱️ 耗时: %dms", skinType, top.confidence * 100, duration ); resultText.setText(resultMsg); resultText.setTextColor(getConfidenceColor(top.confidence)); // 添加个性化建议 addSkinCareAdvice(skinType); // 记录分享用的文本 skinTypeResult = "我的皮肤类型分析结果:" + skinType; // 启用分享按钮 shareButton.setEnabled(true); } else { resultText.setText("⚠️ 无法识别皮肤类型"); resultText.setTextColor(Color.YELLOW); // 禁用分享按钮 shareButton.setEnabled(false); } }); } catch (Exception e) { runOnUiThread(() -> { resultText.setText("❌ 分析失败: " + e.getMessage()); resultText.setTextColor(Color.RED); }); } }).start(); } private String getSkinTypeDisplayName(String type) { switch (type.toLowerCase()) { case "oily": return "油性肌肤"; case "dry": return "干性肌肤"; case "normal": return "中性肌肤"; default: return type; } } private int getConfidenceColor(float confidence) { if (confidence > 0.8f) return Color.parseColor("#4CAF50"); // 绿色 if (confidence > 0.6f) return Color.parseColor("#FFC107"); // 黄色 return Color.parseColor("#F44336"); // 红色 } private void addSkinCareAdvice(String skinType) { TextView adviceText = findViewById(R.id.adviceText); switch (skinType) { case "油性肌肤": adviceText.setText("✨ 护理建议:\n- 使用控油洁面产品\n- 每周1-2次深层清洁\n- 选择轻薄无油配方护肤品"); break; case "干性肌肤": adviceText.setText("✨ 护理建议:\n- 使用滋润型洁面乳\n- 早晚使用高效保湿霜\n- 每周2-3次保湿面膜"); break; default: adviceText.setText("✨ 护理建议:\n- 保持日常清洁保湿\n- 注意防晒\n- 定期皮肤检查"); } adviceText.setTextColor(Color.parseColor("#2196F3")); // 蓝色 } }上述为analysisactivity的代码<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="my_images" path="Pictures/" /> <external-path name="external_files" path="."/> <external-files-path name="images" path="Pictures" /> </paths>上述为file_paths的代码仔细分析所给代码,用Android Studio运行该APP时拍照后出现跳转皮肤分析界面,显示tflite模型加载失败,分析问题,并给出解决办法,tflite模型是在Python环境下tflite-support为0.1.0a1版本下训练的,但在Android中打开模型时没有元数据显示
10-25
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值