Android 使用 FileProvider 拍照

标签 android android-camera android-fileprovider

我正在使用 FileProvider 在 Android Nougat 上拍照,这是我的代码

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.mypackage.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
</provider>

文件路径.xml:

<paths>
    <files-path name="img" path="images/" />
</paths>

Java:

 String fileName = "cameraOutput" + System.currentTimeMillis() + ".jpg";
 File imagePath = new File(getContext().getFilesDir(), "images");
 File file = new File(imagePath, fileName);
 Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

 final Uri outputUri = FileProvider.getUriForFile(activity, "com.mypackage.fileprovider", file);
 cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputUri);
 getContext().grantUriPermission(
            "com.google.android.GoogleCamera",
            outputUri,
            Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION
 );
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            cameraIntent.setFlags(FLAG_GRANT_WRITE_URI_PERMISSION);
 activity.startActivityForResult(cameraIntent, ACTIVITY_REQUEST_CODE);

相机 Activity 启动,拍照成功,但 Activity 结果不正常,我在错误日志中看到的唯一内容是

CAM_StateSavePic:将结果保存到 URI 时出现异常:Optional.of(content://com.mypackage.fileprovider/img/cameraOutput1469383289530.jpg) FileNotFoundException: 是一个目录

编辑 错过了 File#createNewFile();

最佳答案

让相机和图库 URI 正常工作的主要因素是提供程序路径。

您需要创建一个 provider_paths.xml 到/res/xml/目录

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

在您的 list 文件中,在

之间添加此行
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
   <meta-data
       android:name="android.support.FILE_PROVIDER_PATHS"
       android:resource="@xml/provider_paths">
</provider>

还有一件事,我发现我们需要像这样在 Application 类中设置 vmPolicy

@Override
public void onCreate() {
    super.onCreate();
   //Allowing Strict mode policy for Nougat support
   StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
   StrictMode.setVmPolicy(builder.build());
}

在 list 文件中仔细检查您的相机和外部存储权限,然后您就可以使用 nougat URI。

有关更多详细信息,请查看此链接:Android N FileUriExposedException

关于Android 使用 FileProvider 拍照,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38555301/

相关文章:

android - 使用 FileProvider 从图库中选择图像文件

java - 使用 Android 7.1.1 的 FileProvider 通过相机拍照后无法将文件保存到图库

Android 传感器读数不返回所有传感器

Android 相机预览 vs 后台服务

java - Android 阻止 textview 增加其大小

Android 12(SDK > 29)ACTION_IMAGE_CAPTURE 的 Extra_Output 不起作用

android - 如何在surfaceview上绘制?

android - SecurityException:打开未从 uid 导出的提供程序

android - Android 中使用 HTTP 协议(protocol)的 Web 服务

android - 如何以编程方式更改 WindowManager.LayoutParams 的类型?