将Cache Uri用作MediaStore时,相机无法工作/无法保存.EXTRA_OUTPUT [英] Camera not working/saving when using Cache Uri as MediaStore.EXTRA_OUTPUT

查看:885
本文介绍了将Cache Uri用作MediaStore时,相机无法工作/无法保存.EXTRA_OUTPUT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从Fragment拍摄照片后获得完整图像.

I am trying to get the full image after taking a picture from a Fragment.

如果我使用文件(Uri.fromFile(file))中的Uri,则在拍照并点击确定"按钮后相机不会退出(看起来无法写入Uri或谁知道)

If I use the Uri from the file (Uri.fromFile(file)), the camera won't exit after taking the photo and tapping on the 'ok' button (looks like can't write to the Uri or who knows what).

使用File String(以'/data/data/com.package.bla/cache/img198346262jpg'的形式)不能很好地工作(文件在那里,但是它是空的,因为相机没有在上面保存任何内容).

Using the File String, in the form of '/data/data/com.package.bla/cache/img198346262jpg', it's not working as well (The file is there, but it's empty because the camera is not saving anything on it).

到目前为止我尝试过的事情:

What I tried so far:

  • 在创建文件后删除文件,就像此示例一样.但是,相机退出后该文件不存在.
  • 添加了外部存储读取权限,以防万一
  • Deleting the file after creating it, as this example does. However, the file doesn't exist after the camera exits.
  • Added External Storage READ permission, just in case

所以我不知道为什么不保存图像,而已经花费/浪费了大量时间进行测试,并弄清为什么图像不起作用.

So I have no idea why the image is not being saved and already spent/wasted a lot of time testing and figuring why it's not working.

片段:

private void launchCamera() {
    Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    File outputDir = getActivity().getCacheDir();
    File file = null;
    try {
        file = File.createTempFile("img", "jpg", outputDir);
    } catch (IOException e) {
        e.printStackTrace();
    }
    if (file != null) {
        mImageUri = Uri.fromFile(file);   //using Uri is not even exiting the camera
        //mImageUri = File.toString();    //If I use String instead of an Uri, it works better (ie, can accept camera photo)
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
        startActivityForResult(cameraIntent, RESULT_TAKE_IMAGE);
    }
}


public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == Activity.RESULT_OK) {
        Bitmap original = BitmapFactory.decodeFile(mImageUri.toString(), bounds);
    }
}

已编辑的代码,mImageUri.如前所述,如果我使用Uri,我什至无法接受相机应用程序中的照片.使用字符串可以让我接受照片,尽管实际上并没有保存照片(即文件中包含0字节).

Edited code, mImageUri. As explained, if I use Uri I can't even accept the photo in the camera app. Using a String will let me accept the photo, though the photo is not actually saved (ie the file has 0 bytes inside it).

EXPLANATION :该问题与保存到缓存目录有关.可能是一个错误,我缺少权限,或者相机应用程序无法保存到您的应用程序私有数据目录中.添加权限FLAG_GRANT_WRITE_URI_PERMISSION无法解决.相关文章:将相机中的图像存储到私有应用程序缓存目录中 AND 通过意图启动时将照相机数据保存到缓存中

EXPLANATION: The problem was related to saving into the cache directory. Maybe it's a bug, I am missing a permission or the camera app just can't save into your application private data directory. Adding Permission FLAG_GRANT_WRITE_URI_PERMISSION didn't solve it. Related posts: Store image from camera into private app cache directory AND Saving camera data to cache when launched via intent

更新从Android 2.2开始,可以使用getExternalCacheDir()方法代替getCacheDir()

UPDATE From Android 2.2 onwards getExternalCacheDir() method can be used instead of getCacheDir()

推荐答案

来自android 26+的Uri.fromFile将不起作用,您应该改用File provider.

from android 26+ Uri.fromFile will not work, you should use File provider instead.

AndroidManifest.xml

AndroidManifest.xml

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <application
        .........

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

res/xml/file_paths.xml

res/xml/file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external"
        path="." />
</paths>

最后

final Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

// output file
File path = new File(Environment.getExternalStorageDirectory(), "tmp.mp4");

// com.mydomain.fileprovider is authorities (manifest)
// getUri from file
Uri uri = FileProvider.getUriForFile(this, "com.mydomain.fileprovider", path);

takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(takeVideoIntent, 99);

在android 8.0和5.1.1上测试

tested on android 8.0 and 5.1.1

更新:在某些设备的内置摄像头上不支持EXTRA_OUTPUT,因此,如果要在所有设备上使用,请构建自己的摄像头模块.

Update: on some device built-in camera would not support for EXTRA_OUTPUT, so if you want to work on all devices, build your own camera module.

这篇关于将Cache Uri用作MediaStore时,相机无法工作/无法保存.EXTRA_OUTPUT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆