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

Android API21以下调用相机Intent拍摄照片崩溃问题求助

解决API21以下调用相机Intent结合FileProvider崩溃的问题

从你提供的LogCat可以看到核心错误:

java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{a538ebb8 3090:com.android.camera/u0a32} (pid=3090, uid=10032) that is not exported from uid 10057

这个问题的根源是Android 4.4(API19)及以下版本的权限机制限制:即使你在Manifest里给FileProvider设置了android:grantUriPermissions="true",通过startActivityForResult启动第三方相机应用时,系统不会自动把URI的读写权限授予给相机进程,导致相机应用无法访问你通过FileProvider提供的文件路径。

具体修复步骤

1. 显式为相机应用授予URI权限

修改你的dispatchTakePictureIntent方法,在启动相机Intent之前,针对目标相机应用的包名手动授予权限:

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    PackageManager packageManager = getPackageManager();
    
    // 确认有相机应用可以处理Intent
    if (takePictureIntent.resolveActivity(packageManager) != null) {
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            // 处理文件创建失败的情况
            ex.printStackTrace();
        }
        
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(this, "com.example.android.fileprovider", photoFile);
            
            // 关键:获取相机应用的组件信息,显式授予权限
            ComponentName cameraComponent = takePictureIntent.resolveActivity(packageManager);
            if (cameraComponent != null) {
                grantUriPermission(
                    cameraComponent.getPackageName(),
                    photoURI,
                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION
                );
            }
            
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
        }
    }
}

2. 校验FileProvider配置的一致性

  • 确保Manifest中FileProvider的android:authorities值和代码里FileProvider.getUriForFile的第二个参数完全一致(比如你代码里的com.example.android.fileprovider,建议改成和应用包名绑定的格式,比如com.your.real.package.fileprovider,避免冲突)
  • 检查res/xml/file_paths.xml里的路径配置:把占位符com.example.package.name替换成你的应用实际包名,因为getExternalFilesDir(Environment.DIRECTORY_PICTURES)返回的路径是Android/data/你的包名/files/Pictures,路径必须完全匹配才能让FileProvider正确映射。

3. 安全提醒

绝对不要把FileProvider的android:exported设置为true,这会让其他应用随意访问你的私有文件,带来严重的安全风险,保持false即可。

为什么API21以上正常?

从Android 5.0(API21)开始,系统优化了URI权限的传递机制:当你通过startActivityForResult启动其他应用时,系统会自动将Intent中携带的URI权限授予给目标应用,所以你的代码在高版本设备上可以正常运行。

内容的提问来源于stack exchange,提问作者Aleksey Kabanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:56:10