I am trying to get the full image after taking a picture from a Fragment
.
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).
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:
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.
Fragment:
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);
}
}
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: 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
UPDATE From Android 2.2 onwards getExternalCacheDir()
method can be used instead of getCacheDir()
from android 26+ Uri.fromFile will not work, you should use File provider instead.
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
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
</paths>
finally
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);
tested on android 8.0 and 5.1.1
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.
Why not saving it in a new File
final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator);
root.mkdirs();
final String fname = "img_"+ System.currentTimeMillis() + ".jpg";
final File sdImageMainDirectory = new File(root, fname);
mImageUri = Uri.fromFile(sdImageMainDirectory);
And then pass that uri to the intent
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With