How to get uri of captured photo?
Solution 1
Follow below steps.
Step - 1 : Create provider_paths.xml in res/xml folder and write below code in it.
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="external_files"
path="." />
</paths>
Step - 2 : Declare provider in manifest as below.
<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>
If you are facing error at: android:name="android.support.v4.content.FileProvider" Use:
<provider
android:name="androidx.core.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>
Step - 3 : Write your camera intent as below.
Intent m_intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory(), "MyPhoto.jpg");
Uri uri = FileProvider.getUriForFile(this, this.getApplicationContext().getPackageName() + ".provider", file);
m_intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(m_intent, REQUEST_CAMERA_IMAGE);
Step - 4 : Handle camera result in onActivityResult as below.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
//TODO... onCamera Picker Result
case REQUEST_CAMERA_IMAGE:
if (resultCode == RESULT_OK) {
//File object of camera image
File file = new File(Environment.getExternalStorageDirectory(), "MyPhoto.jpg");
//Uri of camera image
Uri uri = FileProvider.getUriForFile(this, this.getApplicationContext().getPackageName() + ".provider", file);
}
break;
}
}
Solution 2
While calling Camera intent
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "IMG_FOLDER");
try {
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
} catch (Exception e) {
e.printStackTrace();
}
imageURI = Uri.fromFile(new File(mediaStorageDir.getPath() + File.separator +
"profile_img.jpg"));
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageURI);
startActivityForResult(intent, Utils.CAMERA_REQUEST);
Inside onActivityResult
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
if (resultCode == RESULT_OK) {
if (requestCode == Utils.CAMERA_REQUEST) {
if (imageURI != null) { // use the same uri, that you initialized while calling camera intent
// do whatever you want to do with this Uri
}
}
}
} catch(Exception E) {}
}
For Nougat, you need to add this below code in splash / launcher activity
if (Build.VERSION.SDK_INT >= 24) {
try {
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
m.invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
}
This will work in all version. I have tested it too.
neo
Updated on June 09, 2022Comments
-
neo almost 2 years
What do I want to achieve? I want to get URI of the captured image and save it on Firebase. What did I try? First of all I needed to open the camera. Below how I did it:
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) startActivityForResult(cameraIntent, CAMERA_REQUEST_CODE);
After capturing the image, I needed to get the URI of the image. Below how I did it:
if (resultCode == Activity.RESULT_OK) { if (requestCode == CAMERA_REQUEST_CODE) { if (data != null) { if (data.getData() != null) { Uri capturedImageUri = data.getData(); } else { Toast.makeText(getContext(), getString(R.string.coudldnt_get_photo), Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(getContext(), getString(R.string.coudldnt_get_photo), Toast.LENGTH_SHORT).show(); }
So everything was OK. But only on some devices. I suppose that it works only on API level more than 21 devices. In other devices ,
getData()
returns null.So, what I have done next? I found that I can get Bitmap of the image through following code:
Bitmap bitmap = (Bitmap)data.getExtras().get("data") ;
So, I have a bitmap of the image. And I needed to get the URI of this image. Below how I did it:
public Uri getImageUri(Context inContext, Bitmap inImage) { String path = Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null); return Uri.parse(path); }
Above code returns me URI, but the image has really bad quality.
So, I kept looking for a solution. And found that the right way is to create the file when I start the
CameraActivity
and save the uri of that file. AndonActivityResult
I tried to get that uri. Below how I did it:Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (cameraIntent.resolveActivity(getActivity().getPackageManager()) != null) { File photoFile = null; try { photoFile = createImageFile(); } catch (IOException ex) { } if (photoFile != null) { Uri photoUri = FileProvider.getUriForFile(getContext(), "i_dont_know_what_to_write_here", photoFile); cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); startActivityForResult(cameraIntent, CAMERA_REQUEST_CODE); } }
And my
onActivityResult
became:if (resultCode == Activity.RESULT_OK) { if (requestCode == CAMERA_REQUEST_CODE) { if (data != null) { Uri capturedPhotoUri = data.getParcelableExtra(MediaStore.EXTRA_OUTPUT); } else { Toast.makeText(getContext(), getString(R.string.coudldnt_get_photo), Toast.LENGTH_SHORT).show(); }
The above concept requires to add some tags on manifest :
<provider android:name="android.support.v4.content.FileProvider" android:authorities="i_dont_know_what_to_write_here" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/my_paths" /> </provider>
My xml file is :
<?xml version="1.0" encoding="utf-8"?> <paths> <external-files-path name="images"/> </paths>
The above method didn't work because
data
ononActivityReuslt
was null.So, what I need to do in order to achieve my goal?