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
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 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.)
Regardless of whether I use an emulated camera or use my webcam as the emulated device's camera, I cannot save photos. My code sets up a new file to save the photo, the camera activity pops up, but after I take the picture, hitting the 'save' or 'accept picture' button doesn't do anything. The only way I can return to my app's activity it by hitting cancel. This code works when I run it on my Galaxy S3, but not an emulated Nexus device. When I set up the device in AVD Manager, I always make sure to enable to set both cameras to either emulated or webcam0, whichever I am using, and I make sure to have an SD card (even though I save to internal memory) and internal storage sufficient for photos. In my manifest, I declare android.permission.INTERNET, android.permission.WRITE_EXTERNAL_STORAGE, and android.permission.CAMERA. Any ideas?
Here's my code where I start the camera intent:
private void dispatchTakePictureIntent(int position) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile(position);
} catch (IOException ex) {
Log.v("photo", "photoFile failed.");
}
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
} else {
Log.v("tag", "photoFile was equal to null.");
}
}
}
Found a solution! The emulated camera wasn't returning because I used a bad directory (selected in createImageFile above) for saving the File. I started using the directory returned by Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) and that solved the problem.
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 am trying to invoke the default device camera from my application to take picture using intent android.provider.MediaStore.ACTION_IMAGE_CAPTURE. Everything seems to be working fine except for when i click and save a particular image it gets stored at two location
1. At the default camera location.
2. At the location which i am passing with intent.
I just want the 2nd option to happen and not the 1st one. I thought creating a .nomedia file in used defined location would make sure that the picture would not be listed as part of gallery but later i found that the pic is getting stored at both the location.
My relevant portion of code is:
In the Activity:
Intent intentCamera = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
try {
tempDir = Environment.getExternalStorageDirectory();
// place where to store camera taken picture
photo = createTemporaryFile("picture", ".jpg", tempDir);
photo.delete();
} catch (Exception e) {
Toast.makeText(this, "Please check SD card! Error in fetching image",
Toast.LENGTH_SHORT).show();
}
if (photo != null) {
Uri mImageUri = Uri.fromFile(photo);
Log.i(TAG, "" + mImageUri.toString());
intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
}
startActivityForResult(intentCamera, CAMERA_PIC_REQUEST);
The corresponding method.
public File createTemporaryFile(String part, String ext,File tempDir) throws Exception {
tempDir = new File(tempDir.getAbsolutePath() +"/temp/");
if (!tempDir.exists()) {
tempDir.mkdir();
}
createNoMediaFile(tempDir.getAbsolutePath());
return File.createTempFile(part, ext, tempDir);
}
Is there a way i can avoid 1 i.e. saving the image to the default gallery location. Thanks.
onActivityResult returns you the Uri of Image you can retrieve the path of Image copy the image from that location and save at your desired location and after that delete that from Gallery.