How to Save Data from Camera to Disk Using Mediastore on Android

How do I save data from Camera to disk using MediaStore on Android?

This worked with the following code, granted I was being a little dumb with the last one. I still think there's got to be a better way so that the original image is still saved somewhere. It still sends me the smaller 25% size image.

public class CameraTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button cameraButton = (Button) findViewById(R.id.cameraButton);
cameraButton.setOnClickListener( new OnClickListener(){
public void onClick(View v ){

Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");

startActivityForResult(intent,0);
}
});

}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode== 0 && resultCode == Activity.RESULT_OK) {
Bitmap x = (Bitmap) data.getExtras().get("data");
((ImageView)findViewById(R.id.pictureView)).setImageBitmap(x);
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, "title");
values.put(Images.Media.BUCKET_ID, "test");
values.put(Images.Media.DESCRIPTION, "test Image taken");
values.put(Images.Media.MIME_TYPE, "image/jpeg");
Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
OutputStream outstream;
try {
outstream = getContentResolver().openOutputStream(uri);
x.compress(Bitmap.CompressFormat.JPEG, 70, outstream);
outstream.close();
} catch (FileNotFoundException e) {
//
} catch (IOException e) {
//
}
}
}

Also, I do know that the cupcake release of Android should fix the small image size soon.

How to save a bitmap that I got from camera, to the sd card without losing it's original size and quality

Visit following link

How do I save data from Camera to disk using MediaStore on Android?

It may help

Saving Camera Intent Image To Internal Data Custom Directory

So this is how I solved it. Thanks goes to @AppMobiGurmeet also.

Save the photo to a file on the SDCard like below.

        File directory= new File(Environment.getExternalStorageDirectory()+File.separator+"MyApplication"+File.separator+"TemporaryImages");//+File.separator+CCPhotoManager.getInstance().getNewPhotoFileName()+CCPhotoManager.JPEG_FILE_SUFFIX);
directory.mkdirs();

File externalFile = new File(Environment.getExternalStorageDirectory()+File.separator+"MyApplication"+File.separator+"TemporaryImages"+File.separator+CCPhotoManager.getInstance().getNewPhotoFileName()+CCPhotoManager.JPEG_FILE_SUFFIX);

Uri uriSavedImage=Uri.fromFile(externalFile);
Log.d("PhotoManager", "adding extra to intent: "+uriSavedImage.toString());
Intent launchcameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
launchcameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(launchcameraIntent,CAMERA_PIC_REQUEST);

Then on activity result. (when the intent is returned)

            // SAVE THE PHOTO TO THE INTERNAL DATA DIRECTORY
File to = new File(MyApplication.getAppContext().getFilesDir()+File.separator+"MyApplication"+File.separator+DIRECTORY+File.separator+this._currentPhotoName+JPEG_FILE_SUFFIX);
File from = new File(Environment.getExternalStorageDirectory()+File.separator+"MyApplication"+File.separator+"TemporaryImages"+File.separator+this._currentPhotoName+JPEG_FILE_SUFFIX);

try {
FileChannel destination = new FileOutputStream(to).getChannel();
FileChannel source = new FileInputStream(from).getChannel();
if (destination != null && source != null) {
destination.transferFrom(source,0,source.size());
from.delete();
}
destination.close();
source.close();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

I have now decided however, after all this faffing around, that the internal data directory is not the best place to store things like Images and Files due to, on some devices, there being a very small amount of internal space (Samsung Galaxy Ace approx 200MB).

I hope this helps someone.

Save captured image in specific folder on sd card

You can add this code in onActivityResult. This will store your image in a folder named "YourFolderName"

String extr = Environment.getExternalStorageDirectory().toString()
+ File.separator + "YourFolderName";
File myPath = new File(extr, fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myPath);
bitMap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
MediaStore.Images.Media.insertImage(context.getContentResolver(),
bitMap, myPath.getPath(), fileName);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

also need to set permission on Manifest

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Captured Image is not storing in android 11

Your phone's camera doesnot have permission to write in the specified location. So to fix this, you need to use file provider and give it appropriate permissions so that the camera can write the image to your file.

To do that,

  1. create a FileProvider. In your manifest file, add:
        <provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" /> // <-------- see this
</provider>

Now create a files.xml file in your res/xml folder. In it, write some code:

<?xml version="1.0" encoding="utf-8"?>
<paths>
<cache-path
name="camera"
path="Camera/" />
<cache-path
name="cache"
path="/" />
<files-path
name="files"
path="." />
<external-path
name="external"
path="." />
<external-files-path
name="my_images"
path="/"/>
// todo: add necessary folders according to your requirements...
// also, this is an old example. Consider googling for the latest style. I'm just copying from an old project I have, and it kinda works...
</paths>

So here we are giving the FileProvider the folders that can be shared with external apps.
2. Now create a uri where you want to store the photo. in your activity:

Context applicationContext = getApplicationContext();
File root = getCachedDir(); // consider using getExternalFilesDir(Environment.DIRECTORY_PICTURES); you need to check the file_paths.xml
File capturedPhoto = new File(root, "some_photo.jpeg");
if(!photoFile.exists()) {
photoFile.mkdirs();
}
Uri photoURI = FileProvider.getUriForFile(applicationContext, applicationContext.getPackageName() + ".fileprovider", capturedPhoto);

Please note that my project needed to save picture temporarily, so I had used cachedDir. If you save photo permanently, use getExternalFilesDir(Environment.DIRECTORY_PICTURES); and modify file_paths.xml properly.


  1. Now that we have the correct uri, we can call the camera intent:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,photoURI);
startActivityForResult(takePictureIntent, REQUEST_CODE);

  1. Finally, in activty result, do something:
    @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
// todo: maybe show photo in an imageView
}
}

I hope this works.

Edit

If you are using this app in production, relying on android's default camera app is a bad idea. Our app previously used this way, and it works with, say, samsung's defaul camera. But a lot of our users used third party apps, such as PixArt, which doesnot save photo to our given location. So we had to implement a builtin camera using CameraX. So consider using CameraX or some other camera library.

Camera Intent doesn't save image to gallery

Your file exist in memory but not on disk. Create the file before returning the object

private static File getOutputMediaFile() { 
...
...
//create file on disk
if(!mediaFile.exists()) mediaFile.createNewFile();

return mediaFile;
}

Android Camera Intent on Glass - Save image in custom file path

The file may not be completely written when you look at it, so use a FileWatcher like the one in the GDK docs:

private static final int TAKE_PICTURE_REQUEST = 1;

private void takePicture() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, TAKE_PICTURE_REQUEST);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == TAKE_PICTURE_REQUEST && resultCode == RESULT_OK) {
String picturePath = data.getStringExtra(
CameraManager.EXTRA_PICTURE_FILE_PATH);
processPictureWhenReady(picturePath);
}

super.onActivityResult(requestCode, resultCode, data);
}

private void processPictureWhenReady(final String picturePath) {
final File pictureFile = new File(picturePath);

if (pictureFile.exists()) {
// The picture is ready; process it.
} else {
// The file does not exist yet. Before starting the file observer, you
// can update your UI to let the user know that the application is
// waiting for the picture (for example, by displaying the thumbnail
// image and a progress indicator).

final File parentDirectory = pictureFile.getParentFile();
FileObserver observer = new FileObserver(parentDirectory.getPath()) {
// Protect against additional pending events after CLOSE_WRITE is
// handled.
private boolean isFileWritten;

@Override
public void onEvent(int event, String path) {
if (!isFileWritten) {
// For safety, make sure that the file that was created in
// the directory is actually the one that we're expecting.
File affectedFile = new File(parentDirectory, path);
isFileWritten = (event == FileObserver.CLOSE_WRITE
&& affectedFile.equals(pictureFile));

if (isFileWritten) {
stopWatching();

// Now that the file is ready, recursively call
// processPictureWhenReady again (on the UI thread).
runOnUiThread(new Runnable() {
@Override
public void run() {
processPictureWhenReady(picturePath);
}
});
}
}
}
};
observer.startWatching();
}
}


Related Topics



Leave a reply



Submit