Android Studio中Bitmap转Uri并保存失败,应用崩溃求助
问题分析与修复方案
你的应用崩溃和启动报错来自几个关键代码错误,以下是逐个修复步骤:
1. 修复FileProvider的Manifest配置错误
你当前的FileProvider设置了android:exported="true",这是致命错误——FileProvider要求exported必须为false,因为它是用于安全共享文件的组件,不能公开导出。同时要保证authorities和后续代码调用一致。
修改后的Manifest配置:
<provider android:authorities="${applicationId}.provider" android:name="androidx.core.content.FileProvider" android:exported="false" <!-- 必须改为false --> android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" /> </provider>
2. 确保provider_paths.xml存在并配置正确
在res/xml目录下创建provider_paths.xml(没有则新建),配置你要共享的缓存目录路径:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <cache-path name="photome" path="photome/" /> </paths>
3. 修复saveImage方法的关键错误
你的saveImage存在三个问题:用mkdir()而非mkdirs()(无法创建多级目录)、FileProvider的authorities为空、异常捕获后无日志输出。修改后的代码:
private Uri saveImage(Bitmap img, Context context) { File imagesFolder = new File(context.getCacheDir(), "photome"); Uri uris = null; try{ // 用mkdirs()确保父目录不存在时也能创建 imagesFolder.mkdirs(); // 用时间戳命名避免覆盖旧图 String fileName = System.currentTimeMillis() + ".jpg"; File file = new File(imagesFolder, fileName); FileOutputStream stream = new FileOutputStream(file); // 100质量过高,建议80平衡体积与清晰度 img.compress(Bitmap.CompressFormat.JPEG, 80, stream); stream.flush(); stream.close(); // 与Manifest中的authorities保持一致 uris = FileProvider.getUriForFile(context.getApplicationContext(), context.getPackageName() + ".provider", file); } catch (FileNotFoundException e){ e.printStackTrace(); // 打印日志便于排查 } catch (IOException e){ e.printStackTrace(); } return uris; }
4. 修复ActivityResult处理中的空指针与Bitmap错误
当前代码直接强转相机返回数据,若拍照取消或数据为空会直接崩溃;同时Bitmap缩放的宽高参数搞反,WeakReference在这里完全没必要,反而可能导致Bitmap被提前回收。修改后的代码:
activityResultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { // 先判断结果是否成功、数据是否为空 if (result.getResultCode() == RESULT_OK && result.getData() != null) { Bundle extras = result.getData().getExtras(); if (extras != null) { Bitmap bitmap = (Bitmap) extras.get("data"); if (bitmap != null) { // 修复缩放参数:createScaledBitmap参数为目标宽、目标高 Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), false); Bitmap bmP = scaledBitmap.copy(Bitmap.Config.RGB_565, true); Uri imageUri = saveImage(bmP, UploadCamera.this); if (imageUri != null) { imgT.setImageURI(imageUri); lv_txt.setText(imageUri.toString()); } // 及时回收Bitmap避免内存泄漏 bitmap.recycle(); scaledBitmap.recycle(); bmP.recycle(); } } } } });
内容的提问来源于stack exchange,提问作者caraka deo
相关产品推荐
相关产品推荐

