将Cache Uri用作MediaStore时,相机无法工作/无法保存.EXTRA_OUTPUT [英] Camera not working/saving when using Cache Uri as 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屋!