You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 01:13:38