I am building an application where I want to capture an image by the default camera activity and return back to my activity and load that image in a ImageView. The problem is camera activity always returning null. In my onActivityResult(int requestCode, int resultCode, Intent data) method I am getting data as null. Here is my code:
public class CameraCapture extends Activity {
protected boolean _taken = true;
File sdImageMainDirectory;
Uri outputFileUri;
protected static final String PHOTO_TAKEN = "photo_taken";
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.cameracapturedimage);
File root = new File(Environment
.getExternalStorageDirectory()
+ File.separator + "myDir" + File.separator);
root.mkdirs();
sdImageMainDirectory = new File(root, "myPicName");
startCameraActivity();
} catch (Exception e) {
finish();
Toast.makeText(this, "Error occured. Please try again later.",
Toast.LENGTH_SHORT).show();
}
}
protected void startCameraActivity() {
outputFileUri = Uri.fromFile(sdImageMainDirectory);
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE:
{
if(resultCode==Activity.RESULT_OK)
{
try{
ImageView imageView=(ImageView)findViewById(R.id.cameraImage);
imageView.setImageBitmap((Bitmap) data.getExtras().get("data"));
}
catch (Exception e) {
// TODO: handle exception
}
}
break;
}
default:
break;
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.getBoolean(CameraCapture.PHOTO_TAKEN)) {
_taken = true;
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(CameraCapture.PHOTO_TAKEN, _taken);
}
}
Am I doing anything wrong?
You are getting wrong because you are doing it wrong way.
If you pass the extra parameter MediaStore.EXTRA_OUTPUT with the camera intent then camera activity will write the captured image to that path and it will not return the bitmap in the onActivityResult method.
If you will check the path which you are passing then you will know that actually camera had write the captured file in that path.
For further information you can follow this, this and this
I am doing it another way. The data.getData() field is not guaranteed to return a Uri, so I am checking if it's null or not, if it is then the image is in extras. So the code would be -
if(data.getData()==null){
bitmap = (Bitmap)data.getExtras().get("data");
}else{
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), data.getData());
}
I am using this code in the production application, and it's working.
I had a similar problem. I had commented out some lines in my manifest file which caused the thumbnail data to be returned as null.
You require the following to get this to work:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
I hope this resolves your issue
If you phone is a Samsung, it could be related to this http://kevinpotgieter.wordpress.com/2011/03/30/null-intent-passed-back-on-samsung-galaxy-tab/
There is another open question which may give additional information
If you are using an ImageView to display the Bitmap returned by Camera Intent
you need to save the imageview reference inside onSaveInstanceState and also restore it later on inside onRestoreInstanceState. Check out the code for onSaveInstanceState and onRestoreInstanceState below.
public class MainActivity extends Activity {
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 1;
String mCurrentPhotoPath;
ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
imageView = (ImageView) findViewById(R.id.imageView1);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void startCamera(View v) throws IOException {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photoFile = null;
photoFile = createImageFile();
//intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photoFile));
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE
&& resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
System.out.println(imageBitmap);
imageView.setImageBitmap(imageBitmap);
}
}
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
System.out.println(mCurrentPhotoPath);
return image;
}
private void setPic() {
// Get the dimensions of the View
int targetW = imageView.getWidth();
int targetH = imageView.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
imageView.setImageBitmap(bitmap);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
System.out.println(mCurrentPhotoPath);
imageView = (ImageView) findViewById(R.id.imageView1);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
System.out.println(mCurrentPhotoPath);
imageView = (ImageView) findViewById(R.id.imageView1);
}
}
after many search :
private static final int TAKE_PHOTO_REQUEST = 1;
private ImageView mImageView;
String mCurrentPhotoPath;
private File photoFile;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_saisir_frais);
mImageView = (ImageView) findViewById(R.id.imageViewPhoto);
dispatchTakePictureIntent();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAKE_PHOTO_REQUEST && resultCode == RESULT_OK) {
// set the dimensions of the image
int targetW =100;
int targetH = 100;
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(photoFile.getAbsolutePath(), bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
// stream = getContentResolver().openInputStream(data.getData());
Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath(),bmOptions);
mImageView.setImageBitmap(bitmap);
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
private void dispatchTakePictureIntent() {
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try {
photoFile = createImageFile();
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePhotoIntent, TAKE_PHOTO_REQUEST);
} catch (IOException e) {
e.printStackTrace();
}
}
Try following code
{
final String[] imageColumns = { MediaStore.Images.Media._ID,MediaStore.Images.Media.DATA };
final String imageOrderBy = MediaStore.Images.Media._ID + " DESC";
Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, null, null, imageOrderBy);
imageCursor.moveToFirst();
do {
String fullPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
if (fullPath.contains("DCIM")) {
//get bitmap from fullpath here.
return;
}
}
while (imageCursor.moveToNext());
While taking from camera few mobiles would return null. The below workaround will solve. Make sure to check data is null:
private int CAMERA_NEW = 2;
private String imgPath;
private void takePhotoFromCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, setImageUri());
startActivityForResult(intent, CAMERA_NEW);
}
// to get the file path
private Uri setImageUri() {
// Store image in dcim
File file = new File(Environment.getExternalStorageDirectory() + "/DCIM/", "image" + new Date().getTime() + ".png");
Uri imgUri = Uri.fromFile(file);
this.imgPath = file.getAbsolutePath();
return imgUri;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_NEW) {
try {
Log.i("Crash","CAMERA_NEW");
if(data!=null &&(Bitmap) data.getExtras().get("data")!=null){
bitmap = (Bitmap) data.getExtras().get("data");
personImage.setImageBitmap(bitmap);
Utils.saveImage(bitmap, getActivity());
}else{
File f= new File(imgPath);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inSampleSize= 4;
bitmap = BitmapFactory.decodeStream(new FileInputStream(f), null, options);
personImage.setImageBitmap(bitmap);
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getActivity(), "Failed!", Toast.LENGTH_SHORT).show();
}
}
You can generate bitmap from the file that you send to camera intent. Please use this code...
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
switch (requestCode) {
case CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE:
{
if(resultCode==Activity.RESULT_OK)
{
int orientation = getOrientationFromExif(sdImageMainDirectory);// get orientation that image taken
BitmapFactory.Options options = new BitmapFactory.Options();
InputStream is = null;
Matrix m = new Matrix();
m.postRotate(orientation);//rotate image
is = new FileInputStream(sdImageMainDirectory);
options.inSampleSize = 4 //(original_image_size/4);
Bitmap bitmap = BitmapFactory.decodeStream(is,null,options);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), m, true);
// set bitmap to image view
//bitmap.recycle();
}
break;
}
default:
break;
}
}
private int getOrientationFromExif(String imagePath) {
int orientation = -1;
try {
ExifInterface exif = new ExifInterface(imagePath);
int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
orientation = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
orientation = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
orientation = 90;
break;
case ExifInterface.ORIENTATION_NORMAL:
orientation = 0;
break;
default:
break;
}
} catch (IOException e) {
//Log.e(LOG_TAG, "Unable to get image exif orientation", e);
}
return orientation;
}
File cameraFile = null;
public void openChooser() {
Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent takePhotoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraFile = new File(android.os.Environment.getExternalStorageDirectory(), "temp.jpg");
takePhotoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(cameraFile));
String pickTitle = "Select or take a new Picture"; // Or get from strings.xml
Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,new Intent[]{takePhotoIntent});
startActivityForResult(chooserIntent, SELECT_PHOTO);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case SELECT_PHOTO:
if (resultCode == Activity.RESULT_OK) {
Uri selectedImage = data.getData();
if (selectedImage != null) {
//from gallery
} else if (cameraFile != null) {
//from camera
Uri cameraPictureUri = Uri.fromFile(cameraFile);
}
}
break;
}
}
Try this tutorial. It works for me and use permission as usual in manifesto & also
check permission
https://androidkennel.org/android-camera-access-tutorial/
After a lot of vigorous research I finally reached to a conclusion.
For doing this, you should save the image captured to the external storage.
And then,retrieve while uploading.
This way the image res doesnt degrade and you dont get NullPointerException too!
I have used timestamp to name the file so we get a unique filename everytime.
private void fileChooser2() {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
Intent intent=new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File pictureDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String pictureName=getPictureName();
fi=pictureName;
File imageFile=new File(pictureDirectory,pictureName);
Uri pictureUri = Uri.fromFile(imageFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT,pictureUri);
startActivityForResult(intent,PICK_IMAGE_REQUEST2);
}
Function to create a file name :
private String getPictureName() {
SimpleDateFormat adf=new SimpleDateFormat("yyyyMMdd_HHmmss");
String timestamp = adf.format(new Date());
return "The New image"+timestamp+".jpg";//give a unique string so that the imagename cant be overlapped with other apps'image formats
}
and the onActivityResult:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==PICK_IMAGE_REQUEST2 && resultCode==RESULT_OK )//&& data!=null && data.getData()!=null)
{
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading");
progressDialog.show();
Toast.makeText(getApplicationContext(),"2",Toast.LENGTH_SHORT).show();
File picDir=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File imageFile=new File(picDir.getAbsoluteFile(),fi);
filePath=Uri.fromFile(imageFile);
try {
}catch (Exception e)
{
e.printStackTrace();
}
StorageReference riversRef = storageReference.child(mAuth.getCurrentUser().getUid()+"/2");
riversRef.putFile(filePath)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), "File Uploaded ", Toast.LENGTH_LONG).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
progressDialog.dismiss();
Toast.makeText(getApplicationContext(), exception.getMessage(), Toast.LENGTH_LONG).show();
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
progressDialog.setMessage("Uploaded " + ((int) progress) + "%...");
}
});
Edit: give permissions for camera and to write and read from storage in your manifest.
Related
I am writing a small Programm, where I would like to get a Picture from my Camera, display it in an image view (and save it later on). Therefore, I created an Intent in the onclick-Method of a Button:
File path;
#Override
public void onClick(View v) {
path = new File(getFilesDir(), "Gallery/MyImages/");
if (!path.exists()) path.mkdirs();
File image = new File(path, "image_capture.jpg");
Uri imageUri = FileProvider.getUriForFile(getApplicationContext(), CAPTURE_IMAGE_FILE_PROVIDER, image);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
providePermissionForProvider(cameraIntent, imageUri);
mCurrentPhotoPath = image.getAbsolutePath();
startActivityForResult(cameraIntent, ACTION_REQUEST_CAMERA);
}
private void providePermissionForProvider(Intent intent, Uri uri) {
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
}
When I click on the Button, the Camera-App opens, I can take a picture. After that, I would like to get this picture in a Bitmap in the onActivityResult-Method. But it does not work:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
int targetW = main.getWidth();
int targetH = main.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
Log.d("Facee", "afdadsfafdasfsfsfdsafdsafsdfdsafdsafdsafdsadsafdsadsf");
main.setImageBitmap(bitmap);
}
What am I doing wrong?
HELP
I think your are not getting exact path of your image. Use this:
File tempFile = File.createTempFile("camera", ".png", getExternalCacheDir());
mPath = tempFile.getAbsolutePath();
Uri uri = Uri.fromFile(tempFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
1 - First, you have to check if in your manifest has the permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
and the feature:
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
If you already have, you can follow my example of this, let's in the simply way.
2 - Imagine that you have an ImageView and a Button in your activity.
You'll initialize your components and create click button function.
private boolean isCamera = false;
private Uri fileUri;
private ImageView mImageView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mImageView = layout.findViewById(R.id.mImageView);
Button mTakePhotoButton = layout.findViewById(R.id.mImageView);
mTakePhotoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final CharSequence[] items = {"Take photo", "Cancel"};
isCamera = false;
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getContext());
alertDialog.setTitle("Select Picture");
alertDialog.setItems(items, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int item) {
Intent intent;
switch (item) {
case CAMERA:
isCamera = true;
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getContext().getPackageManager()) != null) {
try {
File photoFile = Utils.createImageFile();
fileUri = Uri.fromFile(photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, 1);
} catch (IOException ex) {
Log.e("PROJECT_TEST", e.getMessage());
}
}
break;
/*case GALLERY:
intent = new Intent();
// Show only images, no videos or anything else
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
// Always show the chooser (if there are multiple options available)
startActivityForResult(Intent.createChooser(intent, getString(R.string.select_picture)), imageBox);
break;*/
default:
dialog.dismiss();
break;
}
}
});
alertDialog.show();
}
});
}
My Utils.createImageFile, the function that creates file in device directory:
public static File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "img_" + timeStamp + ".png";
File storageDir = new File(Environment.getExternalStorageDirectory(), "MyFolder");
if (!storageDir.exists())
storageDir.mkdirs();
return new File(storageDir, imageFileName);
}
3 - You will return your image in imageView as onActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
try {
Bitmap selectedImage;
if (!isCamera && data != null && data.getData() != null) {
fileUri = data.getData();
}
selectedImage = MediaStore.Images.Media.getBitmap(getContext().getContentResolver(), fileUri);
if (selectedImage != null) {
mImage1.setImageBitmap(selectedImage);
String directory = fileUri.toString();
Log.d("PROJECT_TEST", directory);
}
} catch (IOException e) {
e.printStackTrace();
Log.e("PROJECT_TEST", e.getMessage());
}
}
}
Obs: I'm using Fragment, if you're using activity you'll change getContext() to this.
Your app only needs storage permission.Make sure you have it -
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
There is a problem in your folder creation.
Use something like this:
path = new File(getExternalStorageDirectory()+ "/Gallery/MyImages/");
if (!path.exists())path.mkdirs();
File image = new File(path, "image_capture.jpg");
Uri imageUri = FileProvider.getUriForFile(getApplicationContext(), CAPTURE_IMAGE_FILE_PROVIDER , image);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
mCurrentPhotoPath = image.getAbsolutePath();
startActivityForResult(cameraIntent, ACTION_REQUEST_CAMERA);
Point to note : inPurgeable has been deprecated in api 21
I have problem about capturing image on Android via camera. I show my source of my Android app below.
public class RegisterActivity extends AppCompatActivity {
private Kelolajson json;
private Button btnfoto;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
......
json = new KelolaJson();
btnfoto = (Button) findViewById(R.id.fotobtn);
btnfoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (isDeviceSupportCamera()) {
f_foto =txthp.getText().toString() +".jpg";
fname= txthp.getText().toString();
captureImage();
}
else {
Toast.makeText(getApplicationContext(),"Your Mobile don't support camera",Toast.LENGTH_LONG).show();
}
}
});
......
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// successfully captured the image display it in image view
String root = Environment.getExternalStorageDirectory().toString();
String path = root + "/Pictures/myapp";
gmbpath = fileUri.getPath().toString();
Bitmap tmp = BitmapFactory.decodeFile(gmbpath);
imgpreview.setImageBitmap(tmp);
} else if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(),
"You has been canceled capture.",
Toast.LENGTH_SHORT).show();
} else {
// failed to capture image
Toast.makeText(getApplicationContext(),
"Sorry, Can\'t get photo",
Toast.LENGTH_SHORT).show();
}
}
}
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
private static File getOutputMediaFile(int type) {
//External sdcard location
File mediaStorageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
"myapp");
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile = null;
if (type == MEDIA_TYPE_IMAGE) {
fname = "_" + timeStamp;
f_foto = tmp_hp + ".jpg";
mediaFile = new File(mediaStorageDir.getPath() + File.separator + f_foto);
} else {
mediaFile= null;
}
return mediaFile;
}
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
}
This source code has been running well on mobile Smartphone. But some smartphone's result of captured photo always changed orientation. For example, I capture image by smartphone portrait orientation but result of smartphone capture image is landscape orientation. Also, if landscape orientation, it is result changed to portrait orientation. This result don't follow smartphone orientation.
Checks for orientation associated with URI of the captured image from the camera.
try {
getContentResolver().notifyChange(imageUri, null);
File imageFile = new File(imagePath);
ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
Log.v(Common.TAG, "Exif orientation: " + orientation);
} catch (Exception e) {
e.printStackTrace();
}
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
Bitmap cropped = Bitmap.createBitmap(scaled, x, y, width, height, matrix, true);
Apparently Samsung phones set the EXIF orientation tag, rather than rotating individual pixels.Reading the Bitmap using BitmapFactory does not support this tag.What i found the solution to this problem was using ExifInterface in onActivityResult method of the activity.
Try this code:
private static final int CAMERA_PIC_REQUEST = 1337;
Button btnn;
ImageView imageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnn = (Button) findViewById(R.id.btn);
imageView = (ImageView) findViewById(R.id.Img);
sf = getSharedPreferences("photo", Context.MODE_PRIVATE);
String de = sf.getString("image", "");
byte[] c = Base64.decode(de, Base64.DEFAULT);
Bitmap bb = BitmapFactory.decodeByteArray(c, 0, c.length);
imageView.setImageBitmap(bb);
btnn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAMERA_PIC_REQUEST);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_PIC_REQUEST && resultCode == RESULT_OK && null != data) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
byte[] b = bytes.toByteArray();
String img = Base64.encodeToString(b, Base64.DEFAULT);
SharedPreferences.Editor editor = sf.edit();
editor.putString("image", img);
editor.commit();
imageView.setImageBitmap(thumbnail);
}
}
i have a radio button. when i click on radio button camera intent is opened after taking a image using camera. image is not updating to image view.
i have used all permissions in my manifest file.
RB_PhotoStatus
.setOnCheckedChangeListener(new android.widget.RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group,
int checkedId) {
switch (checkedId) {
case R.id.yes:
//photoCollected = "Yes";
// create intent with ACTION_IMAGE_CAPTURE action
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 0);
break;
case R.id.no:
photoCollected = "No";
break;
}
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Bitmap bp = (Bitmap) data.getExtras().get("data");
imageView1.setImageBitmap(bp);
}
Taking Photos Simply!
This answer explains how to capture photos using an existing camera application.
<manifest ... >
<uses-feature android:name="android.hardware.camera"
android:required="true" />
...
</manifest>
Request for camera application.
static final int REQUEST_IMAGE_CAPTURE = 1;
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
Camera return intent with data on Activity override function onActivityResult as bellow:-
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
mImageView.setImageBitmap(imageBitmap);
}
}
For more info follows this link given bellow:
http://developer.android.com/training/camera/photobasics.html
It doesn't work because Camera Intent won't return the entire BitMap, but only the reference (Uri) to the created file.
Uri selectedImage = data.getData();
From this Uri you may re-load the BitMap using BitmapFactory.decodeFile
On radiobuttonclick();
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
onActivityResult();
Uri originalUri = data.getData();
imageview.setImageURI(originalUri);
And If you want to get bitmap then
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), originalUri);
private String mCurrentPhotoPath;
final String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
final File image = create_directory();
// Save a file: path for use with ACTION_VIEW intents
try {
mCurrentPhotoPath = image.getAbsolutePath();
} catch (Exception e) {
e.printStackTrace();
}
final Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
if (image != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(image));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
} else {
snackbar = Snackbar.make(findViewById(android.R.id.content), "An error has occurred", Snackbar.LENGTH_SHORT);
snackbar.setAction("Dismiss", clickListener);
snackbar.show();
}
}
}
public File create_directory() {
// Create an image file name
final String imageFileName;
final String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(new Date());
final String user_id = "1_";
imageFileName = user_id + timeStamp + "_";
final String proj_name = "test";
final String folder_timeStamp = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH).format(new Date());
final String path = "/TEST/" + proj_name + "/" + folder_timeStamp;
final File dr = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), path);
if (!dr.exists()) {
dr.mkdirs();
}
File image = null;
try {
image = File.createTempFile(imageFileName, ".jpg", dr);
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
if (resultCode == RESULT_OK){
//do something with the image which is stored in mCurrentPhotoPath
}
}
}
I'm trying to make a simple app:
I made a button, its onClick should call the camera intent, save the picture in the internal storage and then i want to put the picture in a custom listview gallery... for now I haven't made the listview because I'm having problems with the intent. the camera doesn't open and I don't know why even if the right permissions are in the manifest file
any help is appreciated, I've tried a lot of tutorials but I can't find the problem.
public class MainActivity extends Activity implements View.OnClickListener {
public static final String LOG_TAG = "LOG_TAG" ;
public static final int CAMERA_REQUEST = 1; /* ci serve la richiesta per la camera*/
private Button btCamera;
private Button btSavePicture;
private ImageView imageViewShowPicture;
private File imageFile;
/*attributi per salvare foto*/
private String savePicturePath;
/*_____________________________________________________________________________________________oncreate*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*Collego oggetti alla grafica*/
btCamera = (Button)this.findViewById(R.id.btCamera);
btSavePicture = (Button) this.findViewById(R.id.btSalvaFoto);
this.imageViewShowPicture = (ImageView) this.findViewById(R.id.ivMostraFoto);
/*listener*/
btCamera.setOnClickListener(this);
btSavePicture.setOnClickListener(this);
}
/*___________________________________________________________________________________________metodo TAKE A PHOTO*/
private void startTakeAPictureIntent(){
Intent takeAPictureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, CAMERA_REQUEST);
}
}}
/*___________________________________________________________________________________________metodo crea image file*/
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
savePicturePath = "file:" + image.getAbsolutePath();
return image;
}
/*______________________________________________________________________________________metodo aggiungi alla gallery*/
private void addPicToGallery() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(savePicturePath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
/*______________________________________________________________________________________metodo decodificare un'immagine scalata*/
private void setPic() {
// Get the dimensions of the View
int targetW = imageViewShowPicture.getWidth();
int targetH = imageViewShowPicture.getHeight();
// Get the dimensions of the bitmap
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(savePicturePath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
// Determine how much to scale down the image
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
// Decode the image file into a Bitmap sized to fill the View
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeFile(savePicturePath, bmOptions);
imageViewShowPicture.setImageBitmap(bitmap);
}
/*_____________________________________________________________________________________________onclick*/
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btCamera: {
Log.d(LOG_TAG, "Ho premuto btcamera");
Toast.makeText(MainActivity.this, "Camera clicked", Toast.LENGTH_SHORT).show();
startTakeAPictureIntent();
/*Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, RICHIESTA_FOTOCAMERA);*/
} break;
case R.id.btSalvaFoto:{
Log.d(LOG_TAG, "Ho premuto btsalvafoto");
Toast.makeText(MainActivity.this, "salvafoto clicked", Toast.LENGTH_SHORT).show();
}
}
}
/*_____________________________________________________________________________________________onActivity result*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) { /* se la richiesta mi da risultati*/
Bundle extras = data.getExtras();
Bitmap immagineBitmap = (Bitmap)extras.get("data"); /* prendi gli extra */
imageViewShowPicture.setImageBitmap(immagineBitmap); /*setto la imageview per mostrarla*/
}
}
}// chiude activity
Please try to add following permission and see.
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Please refer to https://developer.android.com/guide/topics/media/camera.html#manifest to see anything other you need to declare.
I use this code and MediaStore return me bitmapimage with small size.
How to use mediastore to get normal size of photo?
Someone help me solve the problem? Need some help to solve this problem. Need normal size of photo.
public class ActivityPhoto extends Activity implements OnClickListener{
File directory;
final int TYPE_PHOTO = 1;
final int REQUEST_CODE_PHOTO = 1;
ImageView imageViewPhoto;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.schedule_of_subject_photo);
createDirectory();
imageViewPhoto = (ImageView) findViewById(R.id.imageViewPhoto);
}
public void onClickPhoto(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, generateFileUri(TYPE_PHOTO));
startActivityForResult(intent, REQUEST_CODE_PHOTO);
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if (requestCode == REQUEST_CODE_PHOTO) {
if (resultCode == RESULT_OK) {
if (intent == null) {
Log.d(TAG, "Intent is null");
} else {
Log.d(TAG, "Photo uri: " + intent.getData());
Bundle bndl = intent.getExtras();
if (bndl != null) {
Object obj = intent.getExtras().get("data");
if (obj instanceof Bitmap) {
Bitmap bitmap = (Bitmap) obj;
Log.d(TAG, "bitmap " + bitmap.getWidth() + " x " + bitmap.getHeight());
imageViewPhoto.setImageBitmap(bitmap);
}
}
}
} else if (resultCode == RESULT_CANCELED) {
Log.d(TAG, "Canceled");
}
}
}
private Uri generateFileUri(int type) {
File file = null;
switch (type) {
case TYPE_PHOTO:
file = new File(directory.getPath() + "/" + "photo_"
+ System.currentTimeMillis() + ".jpg");
break;
}
Log.d(TAG, "fileName = " + file);
return Uri.fromFile(file);
}
private void createDirectory() {
directory = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyFolder");
if (!directory.exists())
directory.mkdirs();
}
}
Looks like there's no way to get it from MediaStore.
As documentation for MediaStore.ACTION_IMAGE_CAPTURE says:
The caller may pass an extra EXTRA_OUTPUT to control where this image
will be written. If the EXTRA_OUTPUT is not present, then a small
sized image is returned as a Bitmap object in the extra field. This is
useful for applications that only need a small image. If the
EXTRA_OUTPUT is present, then the full-sized image will be written to
the Uri value of EXTRA_OUTPUT.
So, receiving smaller image (or no image at all as on my test device) is expected behavior. I think you need to decode image by yourself in order to get original dimensions. Like the following:
public class MyActivity extends Activity {
private static final String TAG = "MyActivity";
File directory;
final int TYPE_PHOTO = 1;
final int REQUEST_CODE_PHOTO = 1;
ImageView imageViewPhoto;
private Uri mFileUri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
createDirectory();
imageViewPhoto = (ImageView) findViewById(R.id.imageViewPhoto);
}
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.action_bar, menu);
return true;
}
public void onClickPhoto(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
mFileUri = generateFileUri(TYPE_PHOTO);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mFileUri);
startActivityForResult(intent, REQUEST_CODE_PHOTO);
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if (requestCode == REQUEST_CODE_PHOTO) {
if (resultCode == RESULT_OK) {
imageViewPhoto.setImageURI(mFileUri);
new SetPictureTask(getApplicationContext(), mFileUri, imageViewPhoto).execute();
} else if (resultCode == RESULT_CANCELED) {
Log.d(TAG, "Canceled");
}
}
}
private Uri generateFileUri(int type) {
File file = null;
switch (type) {
case TYPE_PHOTO:
file = new File(directory.getPath() + "/" + "photo_"
+ System.currentTimeMillis() + ".jpg");
break;
}
Log.d(TAG, "fileName = " + file);
return Uri.fromFile(file);
}
private void createDirectory() {
directory = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyFolder");
if (!directory.exists())
directory.mkdirs();
}
private static class SetPictureTask extends AsyncTask<Void, Void, Void> {
private final ImageView mImageView;
private final Uri mFileUri;
private final Context mContext;
private Bitmap mBitmap;
private int mWidth;
private int mHeight;
public SetPictureTask(final Context context, final Uri fileUri, final ImageView imageViewPhoto) {
mImageView = imageViewPhoto;
mFileUri = fileUri;
mContext = context;
}
#Override
protected Void doInBackground(final Void... params) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mFileUri.getPath(), opts);
mWidth = opts.outWidth;
mHeight = opts.outHeight;
// required width for image in order to decode faster and consume less memory
final int scaleFactor = Math.min(mWidth / mImageView.getWidth(), mHeight / mImageView.getHeight());
opts.inJustDecodeBounds = false;
opts.inSampleSize = scaleFactor;
opts.inPurgeable = true;
mBitmap = BitmapFactory.decodeFile(mFileUri.getPath(), opts);
return null;
}
#Override
protected void onPostExecute(final Void aVoid) {
mImageView.setImageBitmap(mBitmap);
Toast.makeText(mContext, "Bitmap dimensions are (" + mWidth + " x " + mHeight + ")", Toast.LENGTH_LONG).show();
}
}
}
Please note added AsyncTask for getting dimensions and decoded Bitmap.