I've created an activity that allows the user to add a picture to an ImageView in that activity. I've created a button, that opens a context menu for the activity and gives the user options to either pick a picture from the gallery or take a picture with camera.
If I choose the first option - to pick a picture from the gallery, it works without problems. Gallery is opened, I pick the picture, my activity is resumed and the picture is added to the ImageView.
Strange things start happening after choosing the second option, taking the picture and resuming to my activity:
If I open the context menu again and try to open the gallery, camera
activity gets opened instead
I close the camera activity and resume to my activity, "Complete action using" dialog is shown
I open the gallery, pick a picture and NullPointerException is thrown
Why am I having this behavior and an exception? I've tried searching for similar topics but haven't found a solution.
Below are the methods for my activity
public boolean onContextItemSelected(MenuItem item) {
super.onContextItemSelected(item);
switch(item.getItemId()) {
case R.id.cm_Select_picture: {
// TODO open gallery
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, ""), RC_SELECT_PICTURE);
}
case R.id.cm_Take_picture: {
// TODO open camera
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, RC_TAKE_PICTURE);
}
default: return false;
}
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK) {
switch(requestCode) {
case RC_SELECT_PICTURE: {
Log.d(TAG, "Case select picture");
Uri selectedImageUri = data.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImageUri
, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
Bitmap pic = BitmapFactory.decodeFile(filePath);
goodsImage.setImageBitmap(pic);
}
case RC_TAKE_PICTURE: {
Log.d(TAG, "Case take picture");
if(data.getExtras().get("data") != null) {
Bitmap pic = (Bitmap) data.getExtras().get("data");
goodsImage.setImageBitmap(pic);
}
}
}
}
}
04-26 01:34:59.529: E/AndroidRuntime(20531): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=3, result=-1, data=Intent { dat=content://media/external/images/media/9 }} to activity {com.forestassistant/com.statistics.GoodsActivity}: java.lang.NullPointerException
i used to call camera activity from my activity, and it worked well, here is my code:
setMediaUri(getNewMediaFilePath(actOwner.getContentResolver()));
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, getMediaUri());
startActivityForResult(cameraIntent, CAMERA_CAPTURE_REQUEST_CODE);
and when result callback
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK
&& requestCode == CAMERA_CAPTURE_REQUEST_CODE) {
Drawable toRecycle= imgView.getDrawable();
if (toRecycle != null) {
((BitmapDrawable)imgView.getDrawable()).getBitmap().recycle();
}
mImg = decodeFileIntoRequiredSize(getPath(getMediaUri(),this), requiredSizeForImage);
imgView.setImageBitmap(mImg);
}
public Bitmap decodeFileIntoRequiredSize(String filePath,int requiredSize){
Bitmap b = null;
try {
File f = new File(filePath);
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int scale = 1;
if (o.outHeight > requiredSize || o.outWidth > requiredSize) {
scale = (int)Math.pow(2, (int) Math.round(Math.log(requiredSize / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
//Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
fis.close();
} catch (IOException e) {
}
return b;
}
public String getPath(Uri uri,Activity act) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = act.managedQuery(uri, projection, null, null, null);
if (cursor != null) {
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} else
return null;
}
public Uri getNewMediaFilePath(ContentResolver contentResolver) {
ContentValues values = new ContentValues();
//create the directory
// /mnt/sdcard/DCIM/Camera/IMG_20111101_111922.jpg
String cameraDir = "/Camera";
//File dir1 = act.getExternalFilesDir(Environment.DIRECTORY_DCIM);
File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath()+cameraDir);
if(!dir.exists()) dir.mkdir();
//use date as filename
String name = "IMG_" + (String) android.text.format.DateFormat.format("yyyyMMdd_hhmmss",new Date());
String path = dir.getPath()+File.separator + name;
values.put(MediaStore.MediaColumns.TITLE, name);
values.put(MediaStore.MediaColumns.DATE_ADDED, System.currentTimeMillis());
Uri base = null;
path += ".jpg";
base = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA, path);
return contentResolver.insert(base, values);
}
Hope this help you.
Related
My app is working properly on all api till Kitkat but it's not working in lollipop. The moment i clicks for capturing a photo using camera in my app, it crashes.
cam.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
});
This is my onActivityResult()
case CAMERA_REQUEST: {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(picturePath, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
options.inSampleSize = calculateInSampleSize(options,200,100);//512 and 256 whatever you want as scale
options.inJustDecodeBounds = false;
Bitmap yourSelectedImage = BitmapFactory.decodeFile(picturePath,options);
File pngDir = new File(Environment.getExternalStorageDirectory(),"PicUploadTemp");
if (!pngDir.exists()) {
pngDir.mkdirs();
}
File pngfile = new File(pngDir,"texture1.jpg");
FileOutputStream fOut;
try {
fOut = new FileOutputStream(pngfile);
yourSelectedImage.compress(Bitmap.CompressFormat.JPEG, 50,fOut);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Drawable d = Drawable.createFromPath(pngfile.getPath().toString());
rlLayout.setBackground(d);
yourSelectedImage.recycle();
// resizedBitmap.recycle();
xfile = pngfile;
}
break;
I want to compress the image and this above code is working amazingly for gingerbread, ICS , kitkat but not for Android L
I am getting null pointer Exception
Please suggest me some solution
Thanks in advance
Cannot really say anything about this without the logcat output, It may be becoming null in as a result of you using on of the deprecated method in the BitmapFacotry class.
Define these globally in your activity,
Intent cameraIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
private static final int CAMERA_REQUEST = 1888;
in button click call your camera intent like this
startActivityForResult(cameraIntent, CAMERA_REQUEST);
make sure to use
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
use this to retrieve photo
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == getActivity().RESULT_OK) {
//get photo
Bitmap photo = (Bitmap) data.getExtras().get("data");
}
Hi am capturing an image through camera intent it works good but my problem is that am not getting preview of that image
my requirement is very simple, after clicking of photo through camera it must ask me to SAVE or DISCARD this image if i press SAVE then it get save into sd card thats it...
here is my code
private void openCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
capturedFile = new File(Environment.getExternalStorageDirectory(),
"tmp_nookster_profilepic"
+ String.valueOf(System.currentTimeMillis()) + ".jpg");
mImageCaptureUri = Uri.fromFile(capturedFile);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
mImageCaptureUri);
try {
intent.putExtra("return-data", true);
startActivityForResult(intent, PICK_FROM_CAMERA_NO_CROP);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK)
return;
switch (requestCode) {
case PICK_FROM_CAMERA_NO_CROP: {
iu.SaveCapturedImage(BitmapFactory.decodeFile(capturedFile
.getAbsolutePath()));
try {
if (capturedFile.exists())
capturedFile.delete();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
break;
here "iu" is object of ImageUtility class and "SaveCapturedImage" is method to store that captured image in SdCard
You can get a preview of the captured File as this:
Bitmap getPreview(File image) {
final int THUMBNAIL_SIZE = 72;
BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image.getPath(), bounds);
if ((bounds.outWidth == -1) || (bounds.outHeight == -1))
return null;
int originalSize = (bounds.outHeight > bounds.outWidth) ? bounds.outHeight
: bounds.outWidth;
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = originalSize / THUMBNAIL_SIZE;
return BitmapFactory.decodeFile(image.getPath(), opts);
}
then you can show the Bitmap in an ImageView and present the user with Save/Delete buttons.
You have to remove line from your code.
if (resultCode != RESULT_OK)
return;
Use following code :
if (resultCode == RESULT_OK)
{
try
{
Bitmap bitmap=null;
String imageId = convertImageUriToFile(imageUri,AddRecipes.this);
bitmap = BitmapFactory.decodeFile(imageId);
}}
public static String convertImageUriToFile (Uri contentUri, Activity activity)
{
String[] proj = { MediaStore.Images.Media.DATA };
CursorLoader cursorLoader = new CursorLoader(activity.getApplicationContext(),contentUri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
I use below code to start camera capture on a button clicked:
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(captureIntent, Variables.CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
On activity result, I just simply start "crop" activity.
if (requestCode == Variables.CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
picUri = data.getData();
performCrop();
}
When the camera first started, I pressed the back button to go back to the caller activity (A.class). And then start another activity, say B.class, causes window leak. Sometimes when B.class is called, the screen keep flashing....What's wrong with the code? Please HELP! Many thanks.
There are some alert dialogs I created, but it is already dismissed.
Try this is working like charm with me
private String selectedImagePath = "";
final private int PICK_IMAGE = 1;
final private int CAPTURE_IMAGE = 2;
public 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;
}
public String getImagePath() {
return imgPath;
}
btnGallery.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, ""), PICK_IMAGE);
}
});
btnCapture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, setImageUri());
startActivityForResult(intent, CAPTURE_IMAGE);
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_CANCELED) {
if (requestCode == PICK_IMAGE) {
selectedImagePath = getAbsolutePath(data.getData());
imgUser.setImageBitmap(decodeFile(selectedImagePath));
} else if (requestCode == CAPTURE_IMAGE) {
selectedImagePath = getImagePath();
imgUser.setImageBitmap(decodeFile(selectedImagePath));
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
public Bitmap decodeFile(String path) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 70;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while (o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE)
scale *= 2;
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeFile(path, o2);
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
public String getAbsolutePath(Uri uri) {
String[] projection = { MediaColumns.DATA };
#SuppressWarnings("deprecation")
Cursor cursor = managedQuery(uri, projection, null, null, null);
if (cursor != null) {
int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} else
return null;
}
I am making an android application that takes image from the camera and saves it in the gallery. What i want is to get path of the saved image. I have tried using intent.getData() but is not working..
I have tried using intent.getData() but is not working..
you Will get intent as NULL in Some Samsung Devices Like Samsung Galaxy S3 with Android OS Version 4.1.1.
i have face this Problems and Solve it by Below way you can try it out if it helps you.
While Calling intent for Image Capture :
String storageState = Environment.getExternalStorageState();
if (storageState.equals(Environment.MEDIA_MOUNTED)) {
Intent intent = new Intent(
MediaStore.ACTION_IMAGE_CAPTURE);
String filename = System.currentTimeMillis() + ".jpg";
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, filename);
mImageCaptureUri = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values);
intent.putExtra(
android.provider.MediaStore.EXTRA_OUTPUT,
mImageCaptureUri);
try {
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
}
} else {
new AlertDialog.Builder(BuildInukshk_4_Camera.this)
.setMessage(
"External Storeage (SD Card) is required.\n\nCurrent state: "
+ storageState)
.setCancelable(true).create().show();
}
} else { // pick from file
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Complete action using"), PICK_FROM_FILE);
}
Inside OnActivityResult Method :
case PICK_FROM_CAMERA:
Log.i("TAG", "Inside PICK_FROM_CAMERA");
// Final Code As Below
try {
Log.i("TAG", "inside Samsung Phones");
String[] projection = {
MediaStore.Images.Thumbnails._ID, // The columns we want
MediaStore.Images.Thumbnails.IMAGE_ID,
MediaStore.Images.Thumbnails.KIND,
MediaStore.Images.Thumbnails.DATA };
String selection = MediaStore.Images.Thumbnails.KIND + "=" + // Select
// only
// mini's
MediaStore.Images.Thumbnails.MINI_KIND;
String sort = MediaStore.Images.Thumbnails._ID + " DESC";
// At the moment, this is a bit of a hack, as I'm returning ALL
// images, and just taking the latest one. There is a better way
// to
// narrow this down I think with a WHERE clause which is
// currently
// the selection variable
Cursor myCursor = this.managedQuery(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
projection, selection, null, sort);
long imageId = 0l;
long thumbnailImageId = 0l;
String thumbnailPath = "";
try {
myCursor.moveToFirst();
imageId = myCursor
.getLong(myCursor
.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.IMAGE_ID));
thumbnailImageId = myCursor
.getLong(myCursor
.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID));
thumbnailPath = myCursor
.getString(myCursor
.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));
} finally {
// myCursor.close();
}
// Create new Cursor to obtain the file Path for the large image
String[] largeFileProjection = {
MediaStore.Images.ImageColumns._ID,
MediaStore.Images.ImageColumns.DATA };
String largeFileSort = MediaStore.Images.ImageColumns._ID
+ " DESC";
myCursor = this.managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
largeFileProjection, null, null, largeFileSort);
String largeImagePath = "";
try {
myCursor.moveToFirst();
// This will actually give yo uthe file path location of the
// image.
largeImagePath = myCursor
.getString(myCursor
.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA));
mImageCaptureUri_samsung = Uri.fromFile(new File(
largeImagePath));
mImageCaptureUri = null;
} finally {
// myCursor.close();
}
// These are the two URI's you'll be interested in. They give
// you a
// handle to the actual images
Uri uriLargeImage = Uri.withAppendedPath(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
String.valueOf(imageId));
Uri uriThumbnailImage = Uri.withAppendedPath(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
String.valueOf(thumbnailImageId));
// I've left out the remaining code, as all I do is assign the
// URI's
// to my own objects anyways...
} catch (Exception e) {
mImageCaptureUri_samsung = null;
Log.i("TAG",
"inside catch Samsung Phones exception " + e.toString());
}
try {
Log.i("TAG",
"URI Samsung:" + mImageCaptureUri_samsung.getPath());
} catch (Exception e) {
Log.i("TAG", "Excfeption inside Samsung URI :" + e.toString());
}
try {
Log.i("TAG", "URI Normal:" + mImageCaptureUri.getPath());
} catch (Exception e) {
Log.i("TAG", "Excfeption inside Normal URI :" + e.toString());
}
break;
After Running Below Code you Will get Two URIs mImageCaptureUri_samsung and mImageCaptureUri
you will get the mImageCaptureUri as your Path if you are running the App with Simple Devices and you will get your Cpatured Image path in mImageCaptureUri_samsung if you are running with Devices Like Samsung Galaxy S3.
Further you all can go ahead with your Code. it Works For me Very Fine With all the Devices i have tested on.
Also if Someone is having Problem with Above Code than they can reference the Below Great Link Solution of Samsung Galaxy S3
Hope it will Help.
try this one :
public class Camera extends Activity {
private static final int CAMERA_REQUEST = 1888;
private String selectedImagePath;
String fileName = "capturedImage.jpg";
private static Uri mCapturedImageURI;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
TakePhoto();
}
public void TakePhoto()
{
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, fileName);
mCapturedImageURI = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK)
{
if (requestCode == CAMERA_REQUEST)
{
selectedImagePath = getPath(mCapturedImageURI);
Log.v("selectedImagePath: ", ""+selectedImagePath);
//Save the path to pass between activities
}
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}
This is how I have done:
First create the image uri and with the intent ACTION_IMAGE_CAPTURE pass an extra MediaStore.EXTRA_OUTPUT with this value.
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
capturedImageURI = ImageUtils.takePicture(ReceiptFormActivity.this);
}
});
Then onActivityResult convert this uri path to String path and call the method which will fetch the bitmap from this string path and set it on your imageView.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CONSTANTS.TAKE_PICTURE)
{
if (resultCode == RESULT_OK)
{
if(capturedImageURI != null)
{
Utils.imagePath = ImageUtils.getStringPathFromURI(ReceiptFormActivity.this, capturedImageURI);;
setThumbnail();
}
}
}
}
void setThumbnail()
{
try{
if(Utils.imagePath != null)
{
((TextView)findViewById(R.id.display_image)).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
File f = new File(Utils.imagePath);
if(f.exists())
{
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri imgUri = Uri.fromFile(f);
intent.setDataAndType(imgUri, "image/*");
startActivityForResult(intent,2000);
}
}
});
File imgFilePath = new File(Utils.imagePath);
if(imgFilePath != null && imgFilePath.exists())
{
Bitmap bitmap = ImageUtils.decodeFile(imgFilePath, CONSTANTS.THUMBNAIL_HEIGHT, CONSTANTS.THUMBNAIL_WIDTH);
if(bitmap != null)
{
receipt_thumbnail.setImageBitmap(bitmap);
return;
}
}
}
}
catch (Exception e) {
receipt_thumbnail.setImageResource(R.drawable.some_img);
}
/*
* default img incase of not any exception and no bitmap either.
*/
receipt_thumbnail.setImageResource(R.drawable.some_img);
}
ImageUtils.java
public class ImageUtils {
public static Uri takePicture(Context context)
{
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "Receipt_" + System.currentTimeMillis());
Uri mCapturedImageURI = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Intent intentPicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intentPicture.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
((Activity) context).startActivityForResult(intentPicture,CONSTANTS.TAKE_PICTURE);
return mCapturedImageURI;
}
public static String getStringPathFromURI(Context context, Uri contentUri)
{
try
{
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
catch (Exception e)
{
return contentUri.getPath();
}
}
public static Bitmap decodeFile(File f, int thumbnailReqHeight, int thumbnailReqWidth)
{
Bitmap b = null;
try {
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int scale = 1;
if (o.outHeight > thumbnailReqHeight || o.outWidth > thumbnailReqWidth)
{
scale = (int)Math.pow(2, (int) Math.round(Math.log(thumbnailReqHeight / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
//Decode with inSampleSize
o.inJustDecodeBounds = false;
o.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o);
fis.close();
} catch (IOException e) {
}
return b;
}
}
The code is very fine. Try giving permission of android.permission.WRITE_EXTERNAL_STORAGE and android.permission.READ_EXTERNAL_STORAGE in android manifest.
This question was originally asked for Android 1.6.
I am working on photos options in my app.
I have a button and an ImageView in my Activity. When I click the button it would redirect to the gallery and I would be able to select an image. The selected image would appear in my ImageView.
Updated answer, nearly 5 years later:
The code in the original answer no longer works reliably, as images from various sources sometimes return with a different content URI, i.e. content:// rather than file://. A better solution is to simply use context.getContentResolver().openInputStream(intent.getData()), as that will return an InputStream that you can handle as you choose.
For example, BitmapFactory.decodeStream() works perfectly in this situation, as you can also then use the Options and inSampleSize field to downsample large images and avoid memory problems.
However, things like Google Drive return URIs to images which have not actually been downloaded yet. Therefore you need to perform the getContentResolver() code on a background thread.
Original answer:
The other answers explained how to send the intent, but they didn't explain well how to handle the response. Here's some sample code on how to do that:
protected void onActivityResult(int requestCode, int resultCode,
Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case REQ_CODE_PICK_IMAGE:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(
selectedImage, filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
Bitmap yourSelectedImage = BitmapFactory.decodeFile(filePath);
}
}
}
After this, you've got the selected image stored in "yourSelectedImage" to do whatever you want with. This code works by getting the location of the image in the ContentResolver database, but that on its own isn't enough. Each image has about 18 columns of information, ranging from its filepath to 'date last modified' to the GPS coordinates of where the photo was taken, though many of the fields aren't actually used.
To save time as you don't actually need the other fields, cursor search is done with a filter. The filter works by specifying the name of the column you want, MediaStore.Images.Media.DATA, which is the path, and then giving that string[] to the cursor query. The cursor query returns with the path, but you don't know which column it's in until you use the columnIndex code. That simply gets the number of the column based on its name, the same one used in the filtering process. Once you've got that, you're finally able to decode the image into a bitmap with the last line of code I gave.
private static final int SELECT_PHOTO = 100;
Start intent
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
Process result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
switch(requestCode) {
case SELECT_PHOTO:
if(resultCode == RESULT_OK){
Uri selectedImage = imageReturnedIntent.getData();
InputStream imageStream = getContentResolver().openInputStream(selectedImage);
Bitmap yourSelectedImage = BitmapFactory.decodeStream(imageStream);
}
}
}
Alternatively, you can also downsample your image to avoid OutOfMemory errors.
private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 140;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE) {
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);
}
You have to start the gallery intent for a result.
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, ACTIVITY_SELECT_IMAGE);
Then in onActivityForResult, call intent.getData() to get the Uri of the Image. Then you need to get the Image from the ContentProvider.
Here is a tested code for image and video.It will work for all APIs less than 19 and greater than 19 as well.
Image:
if (Build.VERSION.SDK_INT <= 19) {
Intent i = new Intent();
i.setType("image/*");
i.setAction(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(i, 10);
} else if (Build.VERSION.SDK_INT > 19) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 10);
}
Video:
if (Build.VERSION.SDK_INT <= 19) {
Intent i = new Intent();
i.setType("video/*");
i.setAction(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(i, 20);
} else if (Build.VERSION.SDK_INT > 19) {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 20);
}
.
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == 10) {
Uri selectedImageUri = data.getData();
String selectedImagePath = getRealPathFromURI(selectedImageUri);
} else if (requestCode == 20) {
Uri selectedVideoUri = data.getData();
String selectedVideoPath = getRealPathFromURI(selectedVideoUri);
}
}
}
public String getRealPathFromURI(Uri uri) {
if (uri == null) {
return null;
}
String[] projection = {MediaStore.Images.Media.DATA};
Cursor cursor = getActivity().getContentResolver().query(uri, projection, null, null, null);
if (cursor != null) {
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
return uri.getPath();
}
Do this to launch the gallery and allow the user to pick an image:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK);
Then in your onActivityResult() use the URI of the image that is returned to set the image on your ImageView.
public class EMView extends Activity {
ImageView img,img1;
int column_index;
Intent intent=null;
// Declare our Views, so we can access them later
String logo,imagePath,Logo;
Cursor cursor;
//YOU CAN EDIT THIS TO WHATEVER YOU WANT
private static final int SELECT_PICTURE = 1;
String selectedImagePath;
//ADDED
String filemanagerstring;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
img= (ImageView)findViewById(R.id.gimg1);
((Button) findViewById(R.id.Button01))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// in onCreate or any event where your want the user to
// select a file
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}
});
}
//UPDATED
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
//OI FILE Manager
filemanagerstring = selectedImageUri.getPath();
//MEDIA GALLERY
selectedImagePath = getPath(selectedImageUri);
img.setImageURI(selectedImageUri);
imagePath.getBytes();
TextView txt = (TextView)findViewById(R.id.title);
txt.setText(imagePath.toString());
Bitmap bm = BitmapFactory.decodeFile(imagePath);
// img1.setImageBitmap(bm);
}
}
}
//UPDATED!
public String getPath(Uri uri) {
String[] projection = { MediaColumns.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
column_index = cursor
.getColumnIndexOrThrow(MediaColumns.DATA);
cursor.moveToFirst();
imagePath = cursor.getString(column_index);
return cursor.getString(column_index);
}
}
public class BrowsePictureActivity extends Activity {
private static final int SELECT_PICTURE = 1;
private String selectedImagePath;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((Button) findViewById(R.id.Button01))
.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), SELECT_PICTURE);
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == SELECT_PICTURE) {
Uri selectedImageUri = data.getData();
selectedImagePath = getPath(selectedImageUri);
}
}
}
public String getPath(Uri uri) {
if( uri == null ) {
return null;
}
// this will only work for images selected from gallery
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if( cursor != null ){
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
return uri.getPath();
}
}
For some reasons, all of the answers in this thread, in onActivityResult() try to post-process the received Uri, like getting the real path of the image and then use BitmapFactory.decodeFile(path) to get the Bitmap.
This step is unnecessary. The ImageView class has a method called setImageURI(uri). Pass your uri to it and you should be done.
Uri imageUri = data.getData();
imageView.setImageURI(imageUri);
For a complete working example you could take a look here: http://androidbitmaps.blogspot.com/2015/04/loading-images-in-android-part-iii-pick.html
PS:
Getting the Bitmap in a separate variable would make sense in cases where the image to be loaded is too large to fit in memory, and a scale down operation is necessary to prevent OurOfMemoryError, like shown in the #siamii answer.
call chooseImage method like-
public void chooseImage(ImageView v)
{
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, SELECT_PHOTO);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, imageReturnedIntent);
if(imageReturnedIntent != null)
{
Uri selectedImage = imageReturnedIntent.getData();
switch(requestCode) {
case SELECT_PHOTO:
if(resultCode == RESULT_OK)
{
Bitmap datifoto = null;
temp.setImageBitmap(null);
Uri picUri = null;
picUri = imageReturnedIntent.getData();//<- get Uri here from data intent
if(picUri !=null){
try {
datifoto = android.provider.MediaStore.Images.Media.getBitmap(this.getContentResolver(), picUri);
temp.setImageBitmap(datifoto);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (OutOfMemoryError e) {
Toast.makeText(getBaseContext(), "Image is too large. choose other", Toast.LENGTH_LONG).show();
}
}
}
break;
}
}
else
{
//Toast.makeText(getBaseContext(), "data null", Toast.LENGTH_SHORT).show();
}
}
#initialize in main activity
path = Environment.getExternalStorageDirectory()
+ "/images/make_machine_example.jpg"; #
ImageView image=(ImageView)findViewById(R.id.image);
//--------------------------------------------------||
public void FromCamera(View) {
Log.i("camera", "startCameraActivity()");
File file = new File(path);
Uri outputFileUri = Uri.fromFile(file);
Intent intent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 1);
}
public void FromCard() {
Intent i = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(i, 2);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2 && resultCode == RESULT_OK
&& null != data) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
bitmap = BitmapFactory.decodeFile(picturePath);
image.setImageBitmap(bitmap);
if (bitmap != null) {
ImageView rotate = (ImageView) findViewById(R.id.rotate);
}
} else {
Log.i("SonaSys", "resultCode: " + resultCode);
switch (resultCode) {
case 0:
Log.i("SonaSys", "User cancelled");
break;
case -1:
onPhotoTaken();
break;
}
}
}
protected void onPhotoTaken() {
// Log message
Log.i("SonaSys", "onPhotoTaken");
taken = true;
imgCapFlag = true;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
bitmap = BitmapFactory.decodeFile(path, options);
image.setImageBitmap(bitmap);
}