How clear gallery thumbnails after deleting image from DCIM in Android - java

I am deleting image after capture and doing some work on it.But after deleting the image Gallery till hold the thumbnails. How clear gallery thumbnails after deleting image from DCIM in Android.
private boolean deleteLastFromDCIM() {
boolean success = false;
try {
File[] images = new File(Environment.getExternalStorageDirectory() + File.separator + "DCIM"+File.separator+"Camera").listFiles();
File latestSavedImage = images[0];
for (int i = 1; i < images.length; ++i) {
if (images[i].lastModified() > latestSavedImage.lastModified()) {
latestSavedImage = images[i];
}
}
// OR JUST Use success = latestSavedImage.delete();
success = new File(Environment.getExternalStorageDirectory()
+ File.separator + "DCIM/Camera/"
+ latestSavedImage.getAbsoluteFile()).delete();
return success;
} catch (Exception e) {
e.printStackTrace();
return success;
}}
if(file.exists()){
Calendar time = Calendar.getInstance();
time.add(Calendar.DAY_OF_YEAR,-7);
//I store the required attributes here and delete them
Date lastModified = new Date(file.lastModified());
if(lastModified.before(time.getTime()))
{
//file is older than a week
}
file.delete();
}else{
file.createNewFile();
}

Just you need to write a method for delete file and replace the code file.delete(); with deleteFileFromMediaStore(this.getContentResolver(),file);
public void deleteFileFromMediaStore(final ContentResolver contentResolver, final File file) {
String canonicalPath;
try {
canonicalPath = file.getCanonicalPath();
} catch (IOException e) {
canonicalPath = file.getAbsolutePath();
}
final Uri uri = MediaStore.Files.getContentUri("external");
final int result = contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[] {canonicalPath});
if (result == 0) {
final String absolutePath = file.getAbsolutePath();
if (!absolutePath.equals(canonicalPath)) {
contentResolver.delete(uri,
MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath});
}
}
}

Related

Trying to save images to directory, Saving into an unknown place

I am trying to create a facial/emotion detection application for my dissertation and have hit the wall that has stopped me from progressing and I cant figure out the reason why it is preventing the image saving to the directory of the phone. It seems to be saving to the SD card, but I dont use an SDcard in my phone / an emulated DCIM.
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)+ "/" + UUID.randomUUID(), toString()+ ".jpg");
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader imageReader) {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes() [0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
} catch (IOException e)
{
e.printStackTrace();
}
finally {
{
if (image != null)
image.close();
}
}
}
This is the code I have to create the file and save to the location, I have tried other solutions but they throw out errors.
File folder = new File(Environment.getExternalStorageDirectory() + "/CustomFolder");
File file;
if (!folder.exists()) {
boolean success = folder.mkdir();
if (success){
file = new File(folder.getPath() + "/" + UUID.randomUUID(), toString()+ ".jpg");
}else {
Toast.makeText(FacialDetection.this, "Failed to save file to folder", Toast.LENGTH_SHORT).show();
}
}else{
file = new File(folder.getPath() + "/" + UUID.randomUUID(), toString()+ ".jpg");
}
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader imageReader) {
Image image = null;
try {
image = reader.acquireLatestImage();
ByteBuffer buffer = image.getPlanes() [0].getBuffer();
byte[] bytes = new byte[buffer.capacity()];
buffer.get(bytes);
save(bytes);
} catch (IOException e)
{
e.printStackTrace();
}
finally {
{
if (image != null)
image.close();
}
}
}
private void save(byte[] bytes) throws IOException {
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(***file***);
outputStream.write(bytes);
}finally {
if (outputStream != null)
outputStream.close();
}
}
};
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
final CameraCaptureSession.CaptureCallback captureListener = new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureCompleted(#NonNull CameraCaptureSession session, #NonNull CaptureRequest request, #NonNull TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
Toast.makeText(FacialDetection.this, "Saved " + ***file***, Toast.LENGTH_SHORT).show();
createCameraPreview();
}
};
The updated code, stuff bold and italic is what is throwing errors
I will advise you to create your own custom folder location this way:
File folder = new File(Environment.getExternalStorageDirectory() + "/CustomFolder");
File file;
if (!folder.exists()) {
boolean success = folder.mkdir();
if (success){
file = new File(folder.getPath() + "/" + UUID.randomUUID(), toString()+ ".jpg");
}else {
//Some message
}
}else {
file = new File(folder.getPath() + "/" + UUID.randomUUID(), toString()+ ".jpg");
}
//The rest of your code...
You're calling:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)
I would speculate that .getExternalStoragePublicDirectory() means get directory on SD card. Is there a getInternal... method?
//Create folder !exist
String folderPath = Environment.getExternalStorageDirectory() +"/myFoldername";
File folder = new File(folderPath);
if (!folder.exists()) {
File wallpaperDirectory = new File(folderPath);
wallpaperDirectory.mkdirs();
}
//create a new file
newFile = new File(folderPath, newPhoto.getName());
if (newFile != null) {
// save image here
Uri relativePath = Uri.fromFile(newFile);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, relativePath);
startActivityForResult(intent, CAMERA_REQUEST);
}

How to Save images in an specific folder android

I'm a newbie about android programming
I would like to create folder for store image from my app when user click save
I can save image to my device
but I have no idea to create specific folder ,How to create folder??
thanks for your help!
and sorry my english is not good.
My code
CapturePhotoUtils.insertImage(context.getContentResolver(), myBitmap, title ,des);
and CapturePhotoUtils.java
public class CapturePhotoUtils {
public static final String insertImage(ContentResolver cr,
Bitmap source,
String title,
String description) {
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, title);
values.put(Images.Media.DISPLAY_NAME, title);
values.put(Images.Media.DESCRIPTION, description);
values.put(Images.Media.MIME_TYPE, "image/jpeg");
// Add the date meta data to ensure the image is added at the front of the gallery
values.put(Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis());
Uri url = null;
String stringUrl = null; /* value to be returned */
try {
url = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
if (source != null) {
OutputStream imageOut = cr.openOutputStream(url);
try {
source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut);
} finally {
imageOut.close();
}
long id = ContentUris.parseId(url);
// Wait until MINI_KIND thumbnail is generated.
Bitmap miniThumb = Images.Thumbnails.getThumbnail(cr, id, Images.Thumbnails.MINI_KIND, null);
// This is for backward compatibility.
storeThumbnail(cr, miniThumb, id, 50F, 50F,Images.Thumbnails.MICRO_KIND);
} else {
cr.delete(url, null, null);
url = null;
}
} catch (Exception e) {
if (url != null) {
cr.delete(url, null, null);
url = null;
}
}
if (url != null) {
stringUrl = url.toString();
}
return stringUrl;
}
private static final Bitmap storeThumbnail(
ContentResolver cr,
Bitmap source,
long id,
float width,
float height,
int kind) {
// create the matrix to scale it
Matrix matrix = new Matrix();
float scaleX = width / source.getWidth();
float scaleY = height / source.getHeight();
matrix.setScale(scaleX, scaleY);
Bitmap thumb = Bitmap.createBitmap(source, 0, 0,
source.getWidth(),
source.getHeight(), matrix,
true
);
ContentValues values = new ContentValues(4);
values.put(Images.Thumbnails.KIND,kind);
values.put(Images.Thumbnails.IMAGE_ID,(int)id);
values.put(Images.Thumbnails.HEIGHT,thumb.getHeight());
values.put(Images.Thumbnails.WIDTH,thumb.getWidth());
Uri url = cr.insert(Images.Thumbnails.EXTERNAL_CONTENT_URI, values);
try {
OutputStream thumbOut = cr.openOutputStream(url);
thumb.compress(Bitmap.CompressFormat.JPEG, 100, thumbOut);
thumbOut.close();
return thumb;
} catch (FileNotFoundException ex) {
return null;
} catch (IOException ex) {
return null;
}
}
try this
addToFav("/Favorite", "add to favoriote");
create this function
public void addToFav(String dirName, String str) {
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmmss").format(new Date());
String fileName = "fav" + timeStamp + ".JPG";
File direct = new File(Environment.getExternalStorageDirectory() + dirName);
if (!direct.exists()) {
File wallpaperDirectory = new File(Environment.getExternalStorageDirectory() + dirName);
wallpaperDirectory.mkdirs();
}
File file = new File(new File(Environment.getExternalStorageDirectory() + dirName), fileName);
if (file.exists()) {
file.delete();
}
try {
FileOutputStream out = new FileOutputStream(file);
Bitmap bitmap = BitmapFactory.decodeFile(imagesPathArrayList.get(pos));
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, "title");
values.put(Images.Media.DESCRIPTION, "description");
values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(Images.ImageColumns.BUCKET_ID, file.toString().toLowerCase(Locale.US).hashCode());
values.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, file.getName().toLowerCase(Locale.US));
values.put("_data", file.getAbsolutePath());
ContentResolver cr = getContentResolver();
cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
and don't forget to add permission in manifest file

Android copy images to zip

I have a code here it pick image on the gallery and copy the images it pick and zip those. It run smoothly on copying the file. When i include the zip function it gets error on
Compress c = new Compress(path, targetPath+ picturename);.
Here is the code:
public class MainActivity extends AppCompatActivity {
private static final int PICK_IMAGE_MULTIPLE = 100;
public static String ExternalStorageDirectoryPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/";
//Setting a directory that is already created on the Storage to copy the file to.
public static String targetPath = ExternalStorageDirectoryPath + "BrokenDave" + File.separator;
String picturename = getPicturename();
String path;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void OnClickGallery(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_PICK);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_MULTIPLE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch(requestCode){
case PICK_IMAGE_MULTIPLE:
if (data != null && data.getData() != null) {
Uri uri = data.getData();
path = getPath(uri);
copyFileOrDirectory(path, targetPath + picturename);
Compress c =new Compress(path, targetPath + picturename); //first parameter is d files second parameter is zip file name
c.zip(); //call the zip function
Toast.makeText(this, "File zipped" + path, Toast.LENGTH_SHORT).show();
//get error on calling the zip function
} else {
// Select Multiple
ClipData clipdata = data.getClipData();
if (clipdata != null) {
for (int i = 0; i < clipdata.getItemCount(); i++) {
ClipData.Item item = clipdata.getItemAt(i);
Uri uri = item.getUri();
//ito un path
path = getPath(uri);
//ito un pag copy
copyFileOrDirectory(path, targetPath + picturename);
Compress c =new Compress(path, targetPath + picturename);
c.zip(); //call the zip function
Toast.makeText(this, "Files Deleted" + path, Toast.LENGTH_SHORT).show();
}
}
}
break;
}
}
}
public String getPath(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":") + 1);
cursor.close();
cursor = getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
return path;
}
public void copyFileOrDirectory(String srcDir, String dstDir) {
try {
File src = new File(srcDir);
File dst = new File(dstDir, src.getName());
if (src.isDirectory()) {
String files[] = src.list();
int filesLength = files.length;
for (int i = 0; i < filesLength; i++) {
String src1 = (new File(src, files[i]).getPath());
String dst1 = dst.getPath();
copyFileOrDirectory(src1, dst1);
}
} else {
copyFile(src, dst);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void copyFile(File sourceFile, File destFile) throws IOException {
if (!destFile.getParentFile().exists())
destFile.getParentFile().mkdirs();
if (!destFile.exists()) {
destFile.createNewFile();
}
InputStream in = new FileInputStream(sourceFile);
OutputStream out = new FileOutputStream(destFile);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
if (destFile != null) {
// pag delete ng file
sourceFile.delete();
Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
scanIntent.setData(Uri.fromFile(sourceFile));
sendBroadcast(scanIntent);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}
}
private String getPicturename() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmm");
String timestamp = sdf.format(new Date());
return "Img" + timestamp + ".jpg";
}
}
Here is the compress.java
public class Compress {
private static final int BUFFER = 2048;
public static String ExternalStorageDirectoryPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/";
//Setting a directory that is already created on the Storage to copy the file to.
public static String targetPath = ExternalStorageDirectoryPath + "BrokenDave" + File.separator;
private String[] _files;
// private String targetPath;
public Compress(String[] files, String targetPath) {
_files = files;
}
public void zip() {
try {
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(targetPath);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
byte data[] = new byte[BUFFER];
for(int i=0; i < _files.length; i++) {
Log.v("Compress", "Adding: " + _files[i]);
FileInputStream fi = new FileInputStream(_files[i]);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(_files[i].substring(_files[i].lastIndexOf("/") + 1));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
out.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}

AWS Unable to calculate MD5 hash Android

I am uploading image file to S3 via the AWS java SDK, but i am getting the below error while uploading , i have checked my credentials and my bucket they are fine
Unable to calculate MD5 hash: /data/user/0/competent.groove.feetport/files/data/user/0/competent.groove.feetport/app_imageDir/IMG_20161122_073058.jpg: open failed: ENOENT (No such file or directory)
I am capturing the image from camera and saving the image in phone , here is my code
#Override
public void onPictureTaken(CameraView cameraView, final byte[] data) {
Log.d(TAG, "onPictureTaken " + data.length);
//Toast.makeText(cameraView.getContext(), R.string.picture_taken, Toast.LENGTH_SHORT) .show();
getBackgroundHandler().post(new Runnable() {
#Override
public void run() {
// This demo app saves the taken picture to a constant file.
// $ adb pull /sdcard/Android/data/com.google.android.cameraview.demo/files/Pictures/picture.jpg
///storage/7A52-13E8/Android/data/competent.groove.feetport/files/Pictures/picture.jpg
//make a new picture file
File pictureFile = getOutputMediaFile();
if (pictureFile == null) {
Toast toast = Toast.makeText(getActivity(), "Picture Not saved", Toast.LENGTH_LONG);
toast.show();
return;
}
try {
//write the file
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Toast toast = Toast.makeText(getActivity(), "Picture saved: " + pictureFile.getName(), Toast.LENGTH_LONG);
toast.show();
Log.e("-pictureFile--length-----",""+pictureFile.length());
Log.e("---pictureFile-----"+pictureFile.getName(),""+pictureFile.getAbsolutePath());
Log.e("-fileName--",""+fileName);
editor = sharedPref.edit();
editor.putString(Constants.PIC_PATH,""+fileName);
editor.commit();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
});
}
};
String fileName="";
//make picture and save to a folder
private File getOutputMediaFile() {
//make a new file directory inside the "sdcard" folder
/* File mediaStorageDir = new File("/sdcard/", "JCG Camera");
//if this "JCGCamera folder does not exist
if (!mediaStorageDir.exists()) {
//if you cannot make this folder return
if (!mediaStorageDir.mkdirs()) {
return null;
}
}*/
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
ContextWrapper cw = new ContextWrapper(getActivity());
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
Log.e("---directory-----", "" + directory);
//take the current timeStamp
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
///data/user/0/competent.groove.biometric/files/IMG_20160803_181740.jpg
//and make a media file:
fileName = directory + File.separator + "IMG_" + timeStamp + ".jpg";
mediaFile = new File(directory + File.separator + "IMG_" + timeStamp + ".jpg");
Log.e("---extStorageDirectory-----", "" + extStorageDirectory);
//Log.e("---mediaFile-----",""+mediaFile.length());
//Log.e("---mediaFile-----"+mediaFile.getName(),""+mediaFile.getAbsolutePath());
return mediaFile;
}
and my aws code to upload file is
public class UploadAws extends AsyncTask{
private int total, percentage = 0;
Context context;
String s3_server_path = "";
ObscuredSharedPreferences shrdpref;
ObscuredSharedPreferences.Editor editor;
String res = "";
public UploadAws(Context context){
Log.e(""+getClass(), "UploadAws constructor called");
this.context = context;
shrdpref = new ObscuredSharedPreferences(context, context.getSharedPreferences(Constants.PREFERENCES, Context.MODE_PRIVATE));
}
#Override
protected Object doInBackground(Object... params) {
try {
Log.d("" + getClass(), "UploadAws doInBackground called");
File pictures = null;
AmazonS3Client s3Client = null;
TransferUtility tx = null;
percentage = 0;
try {
s3_server_path = shrdpref.getString(Constants.PIC_PATH,"");
File dir = context.getFilesDir();
pictures = new File(dir, s3_server_path);
s3Client = new AmazonS3Client(new BasicAWSCredentials(shrdpref.getString(Constants.AWS_Access_Key,""),shrdpref.getString(Constants.AWS_Secret_Key,"")));
tx = new TransferUtility(s3Client,context);
} catch (NullPointerException e) {
e.printStackTrace();
}
try {
Log.e("------File length--------=", "" + pictures.length());
Log.e("------File getName--------=", "" + pictures.getName());
Log.e("------File getAbsolutePath--------=", "" + pictures.getAbsolutePath());
s3Client.setEndpoint("s3.amazonaws.com");
String Feetport_bucket = shrdpref.getString(Constants.fs_bucket, "");
if (s3Client.doesBucketExist(Feetport_bucket)) {
Log.e("Warn", "service called bucket exist");
} else {
s3Client.createBucket(Feetport_bucket);
Log.e("FOS signature", "Bucket created");
}
int imageIndex = pictures.toString().lastIndexOf("/");
String pictureString = pictures.toString().substring(imageIndex + 1, pictures.toString().length());
String selfie_url = "FeetPort/" + shrdpref.getString(Constants.company_name, "") + "/attend/" + Utils.getCurrentDate() + "/" + pictureString;
Log.d("UploadAws selfie_url called: ", "" + selfie_url);
//https://feetport.s3.amazonaws.com/8632/17/20161122/mayank1_I_1624_065610_COL22.jpeg
final TransferObserver observer = tx.upload(Feetport_bucket, pictures.getName(), pictures);
observer.setTransferListener(new TransferListener() {
#Override
public void onStateChanged(int arg0, TransferState state) {
Log.e("onStateChanged", "on state changed " + state);
}
#Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
Log.e("onProgressChanged", "total bytes " + observer.getBytesTotal());
Log.e("onProgressChanged", "total bytes transfered " + observer.getBytesTransferred());
percentage = (int) (bytesCurrent / bytesTotal * 100);
Log.e("onProgressChanged", "total percentage " + percentage);
}
#Override
public void onError(int arg0, Exception arg1) {
Log.e("onError=" + arg0, "on Error " + arg1.toString());
percentage = 101;
}
});
do {
} while (percentage < 100);
Log.e("percentage", "percentage " + percentage);
if (percentage == 100) {
/**
* CGPL-17 9-5-2016 dynamic bucket and url.
*/
String S3_SERVER = "https://".concat(Feetport_bucket).concat(".s3.amazonaws.com/");
String imageUrl = S3_SERVER + selfie_url;
//Session.setselfie_url(shrdpref, imageUrl);
editor = shrdpref.edit();
editor.putString(Constants.PIC_PATH, "" + imageUrl);
editor.commit();
Log.e("Selfie url ", "imageUrl --- " + imageUrl);
/*JsonParameters object = new JsonParameters(context);
object.markedAttendance(callback);*/
} else {
/*JsonParameters object = new JsonParameters(context);
object.markedAttendance(callback);*/
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception exception) {
exception.printStackTrace();
}
return null;
}
}
This isn't anything related to S3.
ENOENT (No such file or directory) is a local error: file not found.
Take a very close look at the path in the error message. I've included the path here, and added some line breaks for readability. I did not otherwise edit this, and, importantly, I did not paste any of it here more than once:
/data/user/0
/competent.groove.feetport
/files/data/user/0
/competent.groove.feetport
/app_imageDir/IMG_20161122_073058.jpg
I'm not saying that this is wrong, but it certainly looks wrong. It certainly looks like you're trying to upload the file from a path that you have incorrectly constructed, with some duplication in the directory structure... and there's no such directory, no such file.

how to save bitmap to android gallery

unfortunately the solutions I've found didn't work on android 5.1.1.
I have a bitmap called source. I need to save it directly to my phone's gallery. My manifest contains <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Can you give me a working method to do this?
There were several different ways to do it before API 29 (Android Q) but all of them involved one or a few APIs that are deprecated with Q. In 2019, here's a way to do it that is both backward and forward compatible:
(And since it is 2019 so I will write in Kotlin)
/// #param folderName can be your app's name
private fun saveImage(bitmap: Bitmap, context: Context, folderName: String) {
if (android.os.Build.VERSION.SDK_INT >= 29) {
val values = contentValues()
values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/" + folderName)
values.put(MediaStore.Images.Media.IS_PENDING, true)
// RELATIVE_PATH and IS_PENDING are introduced in API 29.
val uri: Uri? = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
if (uri != null) {
saveImageToStream(bitmap, context.contentResolver.openOutputStream(uri))
values.put(MediaStore.Images.Media.IS_PENDING, false)
context.contentResolver.update(uri, values, null, null)
}
} else {
val directory = File(Environment.getExternalStorageDirectory().toString() + separator + folderName)
// getExternalStorageDirectory is deprecated in API 29
if (!directory.exists()) {
directory.mkdirs()
}
val fileName = System.currentTimeMillis().toString() + ".png"
val file = File(directory, fileName)
saveImageToStream(bitmap, FileOutputStream(file))
if (file.absolutePath != null) {
val values = contentValues()
values.put(MediaStore.Images.Media.DATA, file.absolutePath)
// .DATA is deprecated in API 29
context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
}
}
}
private fun contentValues() : ContentValues {
val values = ContentValues()
values.put(MediaStore.Images.Media.MIME_TYPE, "image/png")
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
return values
}
private fun saveImageToStream(bitmap: Bitmap, outputStream: OutputStream?) {
if (outputStream != null) {
try {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
outputStream.close()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
Also, before calling this, you need to have WRITE_EXTERNAL_STORAGE first.
Use this one:
private void saveImage(Bitmap finalBitmap, String image_name) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root);
myDir.mkdirs();
String fname = "Image-" + image_name+ ".jpg";
File file = new File(myDir, fname);
if (file.exists()) file.delete();
Log.i("LOAD", root + fname);
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Use this code this we help you to store images into a particular folder which is saved_images and that folder images show in gallery immediately.
private void SaveImage(Bitmap finalBitmap) {
String root = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
// sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
// Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(this, new String[]{file.toString()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
}
From Android Q there are changes in saving image to gallery.Thanks to #BaoLei, here is my answer in java if anybody needs it.
private void saveImage(Bitmap bitmap) {
if (android.os.Build.VERSION.SDK_INT >= 29) {
ContentValues values = contentValues();
values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/" + getString(R.string.app_name));
values.put(MediaStore.Images.Media.IS_PENDING, true);
Uri uri = this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
if (uri != null) {
try {
saveImageToStream(bitmap, this.getContentResolver().openOutputStream(uri));
values.put(MediaStore.Images.Media.IS_PENDING, false);
this.getContentResolver().update(uri, values, null, null);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
} else {
File directory = new File(Environment.getExternalStorageDirectory().toString() + '/' + getString(R.string.app_name));
if (!directory.exists()) {
directory.mkdirs();
}
String fileName = System.currentTimeMillis() + ".png";
File file = new File(directory, fileName);
try {
saveImageToStream(bitmap, new FileOutputStream(file));
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
private ContentValues contentValues() {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
}
return values;
}
private void saveImageToStream(Bitmap bitmap, OutputStream outputStream) {
if (outputStream != null) {
try {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here is a fully working solution in Kotlin:
fun saveToGallery(context: Context, bitmap: Bitmap, albumName: String) {
val filename = "${System.currentTimeMillis()}.png"
val write: (OutputStream) -> Boolean = {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, it)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
put(MediaStore.MediaColumns.RELATIVE_PATH, "${Environment.DIRECTORY_DCIM}/$albumName")
}
context.contentResolver.let {
it.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)?.let { uri ->
it.openOutputStream(uri)?.let(write)
}
}
} else {
val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString() + File.separator + albumName
val file = File(imagesDir)
if (!file.exists()) {
file.mkdir()
}
val image = File(imagesDir, filename)
write(FileOutputStream(image))
}
}
Do it in One Line
MediaStore.Images.Media.insertImage(applicationContext.getContentResolver(), IMAGE ,"nameofimage" , "description");
Now we have android10 and android11, so here is an updated version, that will work in all android devices.
Make sure you have the WRITE_EXTERNAL_STORAGE permission before calling this function.
private fun saveMediaToStorage(bitmap: Bitmap) {
val filename = "${System.currentTimeMillis()}.jpg"
var fos: OutputStream? = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
contentResolver?.also { resolver ->
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpg")
put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
}
val imageUri: Uri? =
resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
fos = imageUri?.let { resolver.openOutputStream(it) }
}
} else {
val imagesDir =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
val image = File(imagesDir, filename)
fos = FileOutputStream(image)
}
fos?.use {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, it)
toast("Saved to Photos")
}
}
Its kotlin, and I think very straight forward and self explaining code. But still if you have a problem, comment below and I will explain.
Reference: Android Save Bitmap to Gallery Tutorial.
I'd like to add Java code based on #Bao Lei 's answer that I used in my app.
private void saveImage(Bitmap bitmap, Context context, String folderName) throws FileNotFoundException {
if (android.os.Build.VERSION.SDK_INT >= 29) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/" + folderName);
values.put(MediaStore.Images.Media.IS_PENDING, true);
// RELATIVE_PATH and IS_PENDING are introduced in API 29.
Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
if (uri != null) {
saveImageToStream(bitmap, context.getContentResolver().openOutputStream(uri));
values.put(MediaStore.Images.Media.IS_PENDING, false);
context.getContentResolver().update(uri, values, null, null);
}
} else {
dir = new File(getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES),"");
// getExternalStorageDirectory is deprecated in API 29
if (!dir.exists()) {
dir.mkdirs();
}
java.util.Date date = new java.util.Date();
imageFile = new File(dir.getAbsolutePath()
+ File.separator
+ new Timestamp(date.getTime()).toString()
+ "Image.jpg");
imageFile = new File(dir.getAbsolutePath()
+ File.separator
+ new Timestamp(date.getTime()).toString()
+ "Image.jpg");
saveImageToStream(bitmap, new FileOutputStream(imageFile));
if (imageFile.getAbsolutePath() != null) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATA, imageFile.getAbsolutePath());
// .DATA is deprecated in API 29
context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
}
}
private ContentValues contentValues() {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis() / 1000);
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
return values;
}
private void saveImageToStream(Bitmap bitmap, OutputStream outputStream) {
if (outputStream != null) {
try {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
This one worked fine in my app.
For Media Scanning, you can simply do
val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
intent.data = Uri.fromFile(path) // path must be of File type
context.sendBroadcast(intent)

Categories

Resources