I am using intent to launch camera:
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
getParent().startActivityForResu
I also used the answer from Vicky but I had to save the uri to a bundle to avoid loss of it on orientation change. So if you don't get a result from your intent after tilting the device it might be because your uri did not survive the orientation change.
static final int CAMERA_CAPTURE_REQUEST = 1;
static final String ARG_CURRENT_PIC_URI = "CURRENT_PIC_URI";
String pictureImagePath = folderName + "/" + imageFileName;
File file = new File(Environment.getExternalStorageDirectory(), pictureImagePath);
Uri outputFileUri = Uri.fromFile(file);
mCurrentPicUri = outputFileUri.getPath();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(cameraIntent, CAMERA_CAPTURE_REQUEST);
Activity Result code:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_CAPTURE_REQUEST && resultCode == Activity.RESULT_OK)
{
File imgFile = new File(mCurrentPicUri);
// do something with your image
// delete uri
mCurrentPicUri = "";
}
}
save the uri to the bundle:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save uri to bundle
outState.putString(ARG_CURRENT_PIC_URI, mCurrentPicUri);
}
retrieve it from your saved bundle during on create:
if (bundle.containsKey(ARG_CURRENT_PIC_URI))
mCurrentPicUri = bundle.getString(ARG_CURRENT_PIC_URI);
To get full sized camera image you should point camera to save picture in temporary file, like:
private URI mImageUri;
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
File photo;
try
{
// place where to store camera taken picture
photo = this.createTemporaryFile("picture", ".jpg");
photo.delete();
}
catch(Exception e)
{
Log.v(TAG, "Can't create file to take picture!");
Toast.makeText(activity, "Please check SD card! Image shot is impossible!", 10000);
return false;
}
mImageUri = Uri.fromFile(photo);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
//start camera intent
activity.startActivityForResult(this, intent, MenuShootImage);
private File createTemporaryFile(String part, String ext) throws Exception
{
File tempDir= Environment.getExternalStorageDirectory();
tempDir=new File(tempDir.getAbsolutePath()+"/.temp/");
if(!tempDir.exists())
{
tempDir.mkdirs();
}
return File.createTempFile(part, ext, tempDir);
}
Then after image capture intent finished to work - just grab your picture from imageUri
using following code:
public void grabImage(ImageView imageView)
{
this.getContentResolver().notifyChange(mImageUri, null);
ContentResolver cr = this.getContentResolver();
Bitmap bitmap;
try
{
bitmap = android.provider.MediaStore.Images.Media.getBitmap(cr, mImageUri);
imageView.setImageBitmap(bitmap);
}
catch (Exception e)
{
Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT).show();
Log.d(TAG, "Failed to load", e);
}
}
//called after camera intent finished
@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent)
{
//MenuShootImage is user defined menu option to shoot image
if(requestCode==MenuShootImage && resultCode==RESULT_OK)
{
ImageView imageView;
//... some code to inflate/create/find appropriate ImageView to place grabbed image
this.grabImage(imageView);
}
super.onActivityResult(requestCode, resultCode, intent);
}
P.S. Code need to be revised with respect to new security restriction applied in Android M - FileProvider: mImageUri
has to be packed with FileProvider
Even though this is an old question and it has an accepted answer,
I would like to share my solution.
In this case you don't have to create a temporary file.
Additionally we creating a chooser which offers to user both: take a picture with the camera or pick an existing one from a gallery.
Intent galleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INTENT, galleryIntent);
chooser.putExtra(Intent.EXTRA_TITLE, getString(R.string.chooseaction));
Intent[] intentArray = {cameraIntent};
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooser, RESULT_LOAD_IMAGE);
and here we retrieving results:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// todo use appropriate resultCode in your case
if (requestCode == RESULT_LOAD_IMAGE && resultCode == FragmentActivity.RESULT_OK) {
if (data.getData() != null) {
// this case will occur in case of picking image from the Gallery,
// but not when taking picture with a camera
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), data.getData());
// do whatever you want with the Bitmap ....
} catch (IOException e) {
e.printStackTrace();
}
} else {
// this case will occur when taking a picture with a camera
Bitmap bitmap = null;
Cursor cursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_ADDED,
MediaStore.Images.ImageColumns.ORIENTATION}, MediaStore.Images.Media.DATE_ADDED,
null, "date_added DESC");
if (cursor != null && cursor.moveToFirst()) {
Uri uri = Uri.parse(cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA)));
String photoPath = uri.toString();
cursor.close();
if (photoPath != null) {
bitmap = BitmapFactory.decodeFile(photoPath);
}
}
if (bitmap == null) {
// for safety reasons you can
// use thumbnail if not retrieved full sized image
bitmap = (Bitmap) data.getExtras().get("data");
}
// do whatever you want with the Bitmap ....
}
super.onActivityResult(requestCode, resultCode, data);
}
}
API Level 29
I tried the accepted answer, but both Environment.getExternalStorageDirectory()
used in the accepted answer and Environment.getExternalStoragePublicDirectory()
used in a subsequent answer are deprecated in API level 29. So is the MediaStore.Images.Media.DATA
used in the third answer deprecated in API level 29. The following code (in Kotlin) stores the full image in MediaStore
as shown in this stackoverflow answer to a different question and doesn't rely on the FileProvider
:
var imageUri: Uri? = null
fun takePhoto(view: View?) {
val values = ContentValues()
values.put(MediaStore.MediaColumns.DISPLAY_NAME, "myimage.jpg")
values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
startActivityForResult(intent, TAKE_PHOTO_REQUEST)
}
Don't use onActivityResult
's data. It took me many hours to test different solutions. A camera saves a picture (even if you don't set permissions for camera and card reading in AndroidManifest), but then onActivityResult
returns data == null
and MediaStore
returns wrong path. In these solutions you simply get last gallery image, not your photo.
private Uri photoUri;
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
...
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_RESULT) {
if (resultCode == RESULT_OK) {
if (photoUri != null) {
image.setImageURI(photoUri);
}
}
}
}
private void showCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getContext().getPackageManager()) != null) {
File file = null;
try {
file = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
photoUri = null;
if (file != null) {
photoUri = Uri.fromFile(file);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(intent, CAMERA_REQUEST);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File storageDir = getContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
// File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return File.createTempFile(timeStamp, ".jpg", storageDir);
}
To capture maximum picture size from camera, i hope these simple steps will be quite useful
public static Camera mCamera;
Camera.Parameters parameters = mCamera.getParameters();
parameters.getSupportedPictureSizes();
List<Camera.Size> supportedSizes = parameters.getSupportedPictureSizes();
mSizePicture1 = supportedSizes.get(0);
int cameraSize = supportedSizes.size();
mSizePicture2 = supportedSizes.get(cameraSize - 1);
if (mSizePicture1.height < mSizePicture2.height)
mSizePicture = supportedSizes.get(cameraSize - 1);
else
mSizePicture = supportedSizes.get(0);
parameters.setPictureSize(mSizePicture.width, mSizePicture.height);
Here, the supported size of the each mobile is taken, from that which size is maximum that is fixed as picture size to capture.