I'm strugglin with this already all day :-( My current approach looks like this
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/image.jpg");
imagePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/image.jpg";
startActivityForResult(IntentUtils.dispatchTakePictureIntent(getActivity(), file), REQUEST_IMAGE_CAPTURE);
afterwards i do some unimportant stuff to make display the Bitmap correctly and then display it with this method
placeImageView.setImageBitmap(rotatedBitmap);
*EDIT This is how i create the Intent
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(context.getPackageManager()) != null) {
if (file != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(file));
return takePictureIntent;
}
}
return null;
}
This works so far.
But when i use this imagePath in the next activity, the bitmap won't load. I already tried before so many things with this file path before, at the moment i just feel owerwhelmed by all the possible ways to handle this ...
This may sound trivial, but you have checked if the image really gets recorded where you want it to be - i.e. have you checked for the image by using the standard phone file explorer? (I would have posted this as a comment, but my reputation is too low.)
Related
I am trying to take photo using IMAGE_CAPTURE intent and show this photo on the screen immediately. What I do:
File photoFile = createImageFile();
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(intent, REQUEST_CAMERA);
Create image file method:
private File createImageFile() {
File dir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File photoFile = null;
try {
photoFile = File.createTempFile("photo", ".jpg", dir);
mPhotoPath = photoFile.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
return photoFile;
}
When onActivityResult is called I execute:
Bitmap photo = BitmapFactory.decodeFile(mPhotoPath);
mPhoto.setImageBitmap(photo);
Here is a problem. Apparently IMAGE_CAPTURE activity saves image to a file in background and my onActivityResult gets executed before image is saved. Because of this my photo == null. Although it works if I put breakpoint before BitmapFactory.decodeFile call. I fixed it with an ugly hack:
while (photo == null) {
photo = BitmapFactory.decodeFile(mPhotoPath);
}
So, am I doing something wrong? Why it works this way?
I am testing on Marshmallow Nexus 5.
Apparently IMAGE_CAPTURE activity saves image to a file in background and my onActivityResult gets executed before image is saved
I would consider that to be a bug in the specific camera app that is handling your request. There are hundreds, if not thousands, of such camera apps, and bugs like this are somewhat common.
I fixed it with an ugly hack
Busy loops like that are never a good idea. Among other things, it will freeze your UI if done in the main application thread, and it will seriously chew up CPU even if done on a background thread.
I would try a FileObserver to watch for when the file is closed, to be more event-driven. If, for whatever reason, you can't get that to work:
make sure you are doing your watch-for-the-file logic in a background thread
add reasonable SystemClock.sleep() periods between tries (e.g., 50ms)
I'm currently trying to save images taken from a phone to its gallery, but the code below only works if I choose the stock camera app when the chooser dialog pops up. Whenever I choose another camera app(e.g., the Google camera), the taken picture doesn't get saved any where.
To make things even stranger, sometimes the picture does show up in its designated directory in the gallery, but after 15 mins or so, the same goes for when I use the stock camera app: the picture will get saved in the default camera shots directory, but takes quite a bit to show up in its designated directory, if it shows up there at all.
// Capturing Camera Image will launch camera app request image capture
void captureImage() {
//file uri to store image.
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
// Request camera app to capture image
Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
getActivity().startActivityForResult(captureIntent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
well ,
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
does not work anymore .
you should do something like this :
call Camera Activity :
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
and onActivityResult :
if (data.getData() == null) {
Bitmap bm = (Bitmap)
data.getExtras().get("data");
String timeStamp = new SimpleDateFormat(
"yyyyMMdd_HHmmss").format(new Date());
File pictureFile = new File(Environment
.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
.getAbsolutePath()
+ File.separator + "IMG_" + timeStamp);
try {
FileOutputStream fos = new FileOutputStream(
pictureFile);
bm.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
String filePath = pictureFile.getAbsolutePath();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} } else {
Uri imgUri =data.getData());
}
It turns out my code was working after all. The pictures were being saved in the new directory, but the problem was that the gallery wasn't being updated, which explains why the photos would randomly appear in the directory later on. Being new to this, it never occurred to me that I would have to update the gallery. I only came to this realization after using ES File Explorer to look through my files. To fix my problem, I just made a new method in my CameraFragment that would call on the media scanner. I called this method from onActivityResult().
Here's the new method, though there's nothing really "new" about it since I ran into the same code on other SO questions:
protected void mediaScan() {
getActivity().sendBroadcast(
new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse(fileUri.toString())));
}
I also don't need to call the package manager and iterate through the apps that could handle the camera intent if I'm not giving the option to use choose a picture from a gallery, so I'm going to remove all that from my question.
I do not know how to open saved image and display it into gridView.
I make an intent to take a photo:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null && file != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
And file is saved in /data/data/package/files/...
But when I tried to open file and create a bitmap it always return null.
try {
is = this.getContentResolver().openInputStream(Uri.fromFile(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap bitmap = BitmapFactory.decodeStream(is);}
even if I use decodeFile method() I still have a null bitmap.
Files exist in data/data/ ... I checked it.
My question is: how can I get dispaly taken image?
Actually you can't store Pictures caught on camera directly on your app memory, you should write it to sdcard and copy it to your space and delete the original. Because camera is a another app that has no privillege to write on your apps storage space. You can check that if you have root permissions.
If you specify your app memory for camera intent it will always return NULL
You can read this for WORLD_WRITEABLE
I'm writing an app for school, of which one of the biggest parts is taking pictures. I came to conclusion that it would be perfect if I could just save them on Internal Storage, so they would be automatically removed during uninstall process.
I ran across few code samples, proving me there is no easy way to do that (and I realized saving images on external memory is a piece of cake too). However, I managed to find that question: Trouble writing internal memory android and came up with something similiar. After some time testing I ran across "Unable to resume activity" exception, but fortunately I've found a tweak: image from camera intent issue in android
Now my code looks like this:
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), FITPAL_TEMP_PICTURE_NAME);
Uri outputFileUri = Uri.fromFile(file);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(takePictureIntent, actionCode);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case ACTION_TAKE_PHOTO_B: {
if (resultCode == RESULT_OK) {
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), FITPAL_TEMP_PICTURE_NAME);
Bitmap picture = BitmapFactory.decodeFile(file.getAbsolutePath());
if (picture == null) {
showShortToast(R.string.problem_with_taking_a_picture);
return;
}
File dir = getDir(Environment.DIRECTORY_PICTURES, Context.MODE_PRIVATE);
File internalFile = null;
internalFile = new File(dir, generateUniqueFilename());
internalFile.setReadable(true);
internalFile.setWritable(true);
internalFile.setExecutable(true);
try {
internalFile.createNewFile();
FileOutputStream fos = new FileOutputStream(internalFile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
picture.compress(Bitmap.CompressFormat.JPEG, JPEG_FILE_QUALITY, bos);
bos.flush();
bos.close();
String filePath = internalFile.getAbsolutePath();
pictureFilePaths.add(filePath);
addPictureThumbnail(filePath);
Log.d("mounted?", "" + Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED));
Log.d("delete test 23123123", "" + file.getAbsolutePath() + " " + file.delete());
} catch (Exception e) {
Log.e("eks", e.getMessage());
showShortToast(R.string.problem_with_taking_a_picture);
}
}
else if (resultCode == RESULT_CANCELED) {
showShortToast(R.string.taking_picture_has_been_cancelled);
}
break;
}
default:
break;
}
}
Basically what I'm trying to do is write a picture to External Storage and move it to Internal Storage. It works in 80% of cases, it's not 100% because it sometimes just "resets" the activity - the new empty layout shows up, just as if it was just created. I have no idea what is happening. I realized that both onSaveInstanceState and onRestoreInstanceState fire in that case and I've no idea why (no exceptions are thrown along the way).
The activity that is invoking all that code is extending FragmentActivity. I've read there are some bugs that might cause that in older versions of Android Support Package, but I've just updated it to version 13 and the problem still persists.
The other thing is that the file saved on external storage won't delete - file.delete() always returns false. Is it a matter of me not having an sdcard? (I mean I have a slot in my phone, but I just have Internal Storage of 16GB). The file gets saved to /mnt/sdcard/Pictures/ folder as if it was emulated somehow.
In advance to the questions: I have both android.permission.READ_EXTERNAL_STORAGE and android.permission.WRITE_EXTERNAL_STORAGE permissions set:
I tried replacing Environment.getExternalStoragePublicDirectory with getCacheDir, getExternalCacheDir and none of them worked either..
I'm testing all that stuff on my Samsung Galaxy SII with Android 4.0.4 (stock)
I have a following question. I'm using camera intent that starts from a menu button like this
case R.id.camera:
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(getTempFile(this)));
startActivityForResult(intent, TAKE_PHOTO_CODE);
return true;
This is working just fine and it saves original image (original size which I want).
Than I also have the following code
private File getTempFile(LovneDobe lovneDobe) {
final File path = new File( Environment.getExternalStorageDirectory(), lovneDobe.getPackageName() );
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
if(!path.exists()){
path.mkdir();
}
return new File(path, "image.jpg");
}
and this code saves the picture on SDcard and it also puts it into my gallery. But the problem I'm facing is that it saves only one picture. When I take another one it overwrites the previous one.
And now my question is how can I modify this so that it would save every picture I would take?
Thank in advance to anyone who is willing to help.
I'm pretty sure It's because you are explicitly overriding the file. In your method "getTempFile", you always give the same path and name for every time you call the method. Try having a static counter, for example, to know how many pictures you have done, and in the return, put something like
return new File(path, "image"+counter+".jpg");