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

Android相机APP拍照无法保存查看问题求助(附代码及报错日志)

解决Android相机APP无法保存及查看照片的问题

你遇到的核心问题是目标文件的父目录未创建导致的FileNotFoundException,再加上Android 6.0+的动态权限要求没处理,所以照片既存不了也看不了。下面是一步步的修复方案:

1. 先解决文件目录不存在的问题

你代码里直接创建了YOUR_APP_NAME文件夹下的文件,但这个父目录不会自动生成。在生成output文件前,必须先检查并创建目录:

// 修改目录创建逻辑
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "YOUR_APP_NAME");
// mkdirs()会自动创建多级不存在的目录
if (!dir.exists()) {
    dir.mkdirs();
}
// 给文件名加时间戳,避免重复覆盖旧照片
String fileName = "IMG_" + System.currentTimeMillis() + ".jpg";
output = new File(dir, fileName);

2. 添加动态权限申请

Android 6.0(API 23)及以上版本,存储类权限需要动态请求,只在Manifest里声明是无效的:

第一步:在Manifest里补充权限

<manifest ...>
    <!-- Android 12及以下的存储权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <!-- Android 13+的媒体读写权限 -->
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission android:name="android.permission.WRITE_MEDIA_IMAGES" />
    
    <!-- 你的application和provider配置... -->
</manifest>

第二步:在MainActivity里处理权限请求

把启动相机的逻辑抽出来,先检查权限再执行相机启动:

import android.Manifest;
import android.content.pm.PackageManager;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

public class MainActivity extends AppCompatActivity {
    private File output = null;
    private static final int CONTENT_REQUEST = 1745;
    private static final int PERMISSION_REQUEST_CODE = 100;
    private Uri photoURI;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        // 先检查权限,再启动相机
        checkPermissionsAndStartCamera();
    }

    private void checkPermissionsAndStartCamera() {
        // 根据Android版本判断需要申请的权限
        String[] permissions;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.TIRAMISU) {
            permissions = new String[]{Manifest.permission.WRITE_MEDIA_IMAGES};
        } else {
            permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
        }

        if (ContextCompat.checkSelfPermission(this, permissions[0]) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST_CODE);
        } else {
            startCamera();
        }
    }

    // 处理权限申请结果
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                startCamera();
            } else {
                Toast.makeText(this, "需要存储权限才能保存照片", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }

    // 启动相机的核心逻辑
    private void startCamera() {
        Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "YOUR_APP_NAME");
        if (!dir.exists()) {
            dir.mkdirs();
        }
        String fileName = "IMG_" + System.currentTimeMillis() + ".jpg";
        output = new File(dir, fileName);
        photoURI = FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID + ".provider", output);
        i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        i.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
        startActivityForResult(i, CONTENT_REQUEST);
    }

    // 你的onActivityResult方法...
}

3. 确认FileProvider路径配置正确

确保res/xml/provider_paths.xml的配置包含DCIM目录,这样FileProvider才能正确映射你的文件路径:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="DCIM/" />
</paths>

4. 优化拍照后的处理(可选但建议)

拍照成功后,通知系统媒体库扫描新照片,这样照片才能在系统相册里显示:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == CONTENT_REQUEST) {
        if (resultCode == RESULT_OK) {
            // 通知媒体库扫描新增照片
            Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            mediaScanIntent.setData(Uri.fromFile(output));
            sendBroadcast(mediaScanIntent);

            // 打开查看照片
            Intent i = new Intent(Intent.ACTION_VIEW);
            i.setDataAndType(photoURI, "image/jpeg");
            i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
            startActivity(i);
            finish();
        } else {
            // 拍照取消时,删除空文件
            if (output != null && output.exists()) {
                output.delete();
            }
        }
    }
}

按照这些步骤修改后,你的相机APP应该就能正常保存并查看照片了。

内容的提问来源于stack exchange,提问作者ghost deathrider

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:37:51