We have an Android app where field workers take photographs which are stored on their phone and also uploaded via a web api.
If the uploads fail they do have retry mechanisms but sometimes they need to resort to pulling the images off their phone.
In order to bring the app up to Android 10 version without deprecation I was forced to write the images to an app internal directory.
The problem is that when they upgrade their app they lose their photos from the app.
(I do also copy the images to a backup directory but this is all looking a bit klutzy)
I would like to write the images to :
/storage/emulated/0/DCIM/GoTrialImages
Instead they are going to :
/storage/emulated/0/Android/data/au.come.aceware.ktr.ktr/files/DCIM/GoTrialImages/photoIntent
(where photoIntent is the activity that this is occurring in)
Here is the code I have copied and tweaked from an online article:
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String fileName = "JPEG_" + timeStamp + ".jpg";
File mediaStorageDir = new File(getExternalFilesDir(Environment.DIRECTORY_DCIM + File.separator +"GoTrialPhotos"), TAG);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists() && !mediaStorageDir.mkdirs()){
Log.d(TAG, "failed to create directory");
}
// Return the file target for the photo based on filename
File file = new File(mediaStorageDir.getPath() + File.separator + fileName);
Uri bmpUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", file);
Here is my file provider entry in the manifest:
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>```
and here is #xml/provider_paths:
```<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>```
1) Is it possible to do what I am seeking to do ?
2) How do I do it without using deprecated code
Many thanks in advance
Tony
Following the suggestion to use media store I kept most of the code for creating the app internal file name
(mainly because I wanted the randomised display name):
private File createImageFileV2() throws IOException
{
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
imageFileNameToUseAtWebServerEnd = strTrial + "_" + timeStamp + "_" + strUserId + ".jpg";
File[] storageDir = getExternalMediaDirs();
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir[0] /* directory */
);
return image;
}
I then passed the file object in to the following code:
public Uri testgetPhotoFileUri2(File f)
{
Uri uri = null;
String strDisplayName = f.getName();
final ContentValues values = new ContentValues();
values.put(MediaStore.MediaColumns.DISPLAY_NAME, strDisplayName);
values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM );
final ContentResolver resolver = thisContext.getContentResolver();
try
{
final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
uri = resolver.insert(contentUri, values);
if (uri == null)
throw new IOException("Failed to create new MediaStore record.");
return uri;
}
catch (IOException e)
{
if (uri != null) {
// Don't leave an orphan entry in the MediaStore
resolver.delete(uri, null, null);
}
}
return uri;
}
I then used the resulting uri as my camera uri:
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
However, when the OnActivityResult calls HandleBigCameraPhoto and attempts to extract the bitmap using the CameraUri:
private void handleBigCameraPhoto() {
Bitmap bitmap = null;
if (cameraUri != null)
{
if (Build.VERSION.SDK_INT >= 29) {
ImageDecoder.Source source = ImageDecoder.createSource(getApplicationContext().getContentResolver(), cameraUri);
try {
bitmap = ImageDecoder.decodeBitmap(source);
} catch (IOException e) {
e.printStackTrace();
}
It error traps to "no such file or directory"
Does this mean that I need to most of my work (image resizing, rotation, etc) using my app private file only and then as a last step insert the bitmap in to media store (and then delete the app private file so the user does not see the file name twice under gallery, recents)?
You will not make use of a deprecated function:
File file = new File(getExternalFilesDir(null)
.getParentFile()
.getParentFile()
.getParentFile()
.getParentFile(), "DCIM");
;-).
when I get file path of file in Android 11 .
protected File getOutputMediaFile() {
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmmss").format(new Date());
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, timeStamp + ".jpg");
fileUri = getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
Log.e("File Uri Path", "Uri inserted into media store = " + fileUri);
Toast.makeText(getActivity(), "File uri = "+fileUri, Toast.LENGTH_LONG).show();
String path = getImageRealPathFromURI(fileUri);
File file = new File(path);
return file;
}
private String getImageRealPathFromURI(Uri contentUri) {
String realPath = "";
Cursor cursor = null;
try {
String[] proj = {MediaStore.Images.Media.DATA};
cursor = getActivity().getContentResolver().query(contentUri, proj, null, null, null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
realPath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
} else {
Log.e("Image Real Path", "Cursor count appearing to be zero");
Toast.makeText(getActivity(), "Cursor count appearing to be zero", Toast.LENGTH_LONG).show();
realPath = "";
}
} catch (Exception e) {
Log.e("Image Real Path", "Exception fetching getImageRealPathFromURI() due to " + e.toString());
Toast.makeText(getActivity(),"Exception fetching getImageRealPathFromURI() due to "+e.toString(), Toast.LENGTH_LONG).show();
realPath = "";
} finally {
cursor.close();
}
return realPath;
}
I meet error : /storage/emulated/0/Pictures/1614237849822.jpg: open failed: EEXIST (File exists).
at libcore.io.IoBridge.open(IoBridge.java:492).
When I getOutputMediaFile().getpath.
Anyone help me?
add this line in manifest file :
android:requestLegacyExternalStorage="true"
and make sure that you add Read external storage permission and also allow this permission
The getContentResolver().insert() will give you a nice fresh uri to write the content of a file to.
It gives an uri you can use. It does not create a file for you.
Even if you get the path of the yet non existing file with the .DATA column, that file does not exist yet.
You can simply check that with File.exists().
Only if you open an OutputStream for the obtained uri and write to it the file will be created.
Use the uri! For what do you need that data path?
You can use this type to set mMediaRecoder's path:
final ParcelFileDescriptor parcelFileDescriptor = mContext.getContentResolver().
openFileDescriptor(Uri.parse(mVideoProfile.path), "rw");
mMediaRecorder.setOutputFile(parcelFileDescriptor.getFileDescriptor());
mVideoProfile.path = "content://media/external/video/media/751";
I am writing a camera and gallery app, following the official Google documentation. The problem is that it mostly focuses on how to take a picture and how to save it in memory. I am saving them in the application external memory through getExternalFilesDir().
What I am now trying to do is simpy query that directory in which taken photos are saved, through MediaStore, in order to display all the pictures in there in a recycler view. But I can't seem to find anywhere an explanation on how to do the retrieval. There is something wrong with the Uri that I probably didn't understand well, and I don't know how to solve. Even in here https://developer.android.com/training/data-storage/files#PrivateFiles the article only talks about saving files in the various storage options, but not about retrieving them.
Here is the code of how I save the files:
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = image.getAbsolutePath();
return image;
}
This is the function that actually sends the intent (and then onActivityResult handles the returned data):
private void dispatchTakePictureIntent() {
final String TAG = "dispatchTakePic: ";
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
Log.e(TAG, "Error while creating a file");
ex.printStackTrace();
}
// Continue only if the File was successfully created
// Authority has to be exactly like in manifest
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(
this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
This is the code where I'm trying to get the information about the photos taken:
private void populatePhotoArray() {
final String TAG = "popPhotoArray: ";
ContentResolver contentResolver = getContentResolver();
String photo_id, photo_title, photo_path = "";
final String[] PHOTOGRAPHS_PROJECTION = {
MediaStore.Images.Media._ID,
MediaStore.Images.Media.TITLE,
MediaStore.Images.Media.DATA};
File photographsDirectory = getExternalFilesDir(Environment.DIRECTORY_MOVIES);
Uri photographsUri = Uri.fromFile(photographsDirectory);
//Uri photographsUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
//Uri photographsUri = MediaStore.Images.Media.INTERNAL_CONTENT_URI;
String sortOrder = MediaStore.Images.Media.DATE_ADDED + " DESC";
final Cursor cursor = contentResolver.query(
photographsUri,
PHOTOGRAPHS_PROJECTION,
null,
null,
sortOrder);
Log.d(TAG, "created the projection");
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
photo_id = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media._ID));
photo_title = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.TITLE));
photo_path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
// save to photo list
applicationPhotosList.add(new Photographs(photo_id, photo_title, photo_path));
Log.d(TAG, "new photo added");
}
cursor.close();
Log.d(TAG, "Photo array filled up");
}
else if (cursor == null){
Log.d(TAG, "No photos present, cursor is null");
Toast.makeText(this, "No photos present", Toast.LENGTH_SHORT).show();
}
Looks like trying to transform the path of getExternalFileDir() into an Uri doesn't work. The cursor is empty. But MediaStore only has MediaStore.Images.Media.EXTERNAL_CONTENT_URI and that's not suitable as that queries the whole device memory, while I only need that particular directory in which my app is saving the pictures taken. What am I missing? It cannot be that hard, right?
There is another way to retrieve the images from a specific folder w/o using the cursor and I think its more faster.
private fun getAllShownImagesPath(): ArrayList<String> {
var filePath: ArrayList<String> = ArrayList<String>()
val path = File(getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).path, "BacFo Camera")
if (path.exists()) {
for (i in path.list().iterator()) {
filePath?.add("" + path.toString() + "/" + i)
}
}
return filePath!!
}
`
In "fileNames" you have the path of all images or videos whatever you have saved in the specific folder
My app selects an image taken by the system's camera and obtain its Uri from onActivityResult method, from here i would like to convert the Uri to android standard file path so that i will be able to check its orientation by passing the file path to Exifinterface's constructor and execute getAttributeInt to receive a value and then decide on how many degrees to rotate the image.
I found a sample code here on stackoverflow that has the capability to convert the image uri to file path. but the problem is, it uses DocumentContract class which is added in api level 19 onwards but my app needs to support lower version than API level 19. How can I do this? Or atleast have an alternative solution for getting the orientation of the image.
Use the following method to get the file path from the Uri. Here you need to pass the context and the uri and it maintains the compatibility for pre-Kitkat.
public String getRealPathFromURI(Context context, Uri contentUri) {
String res = "";
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
res = cursor.getString(column_index);
}
cursor.close();
} else {
Log.d(TAG, "Cursor is null");
return contentUri.getPath();
}
return res;
}
Updated for Camera : The above solution is working for Uri returned for the Gallery Intent. For the camera intent use the below code.
public File getOutputMediaFile() {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir;
// If the externam directory is writable then then return the External
// pictures directory.
if (isExternalStorageWritable()) {
mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
.getAbsolutePath() + File.separator + IConstants.CUSTOM_PROFILE_PIC_PATH);
} else {
mediaStorageDir = Environment.getDownloadCacheDirectory();
}
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
Create a global variable selectedImage for storing the image path.
private Uri getOutputMediaFileUri() {
File mediaFile = Utilities.getInstance().getOutputMediaFile();
selectedImage = mediaFile.getAbsolutePath();
return Uri.fromFile(mediaFile);
}
Now call the Camera intent using the following method.
public void dispatchCameraIntent(View view) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// If there any applications that can handle this intent then call the intent.
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
Uri fileUri = getOutputMediaFileUri();
Log.d(TAG, "camera Uri : " + fileUri);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(takePictureIntent, CAMERA_PICKER);
}
}
In OnActivityResult use the selectedImage as the file path.
I save an image to the sdcard and it doesn't appear in the Gallery application until I pull off the sdcard and return it back.
Do you have any idea why is it so?
Seems like the Gallery application has some cache that isn't updated on file save...
Actually, I also want to open the just-saved image in Gallery application and have no success with that this is my question about this issue.
A simpler solution is to use the static convenience method scanFile():
File imageFile = ...
MediaScannerConnection.scanFile(this, new String[] { imageFile.getPath() }, new String[] { "image/jpeg" }, null);
where this is your activity (or whatever context), the mime-type is only necessary if you are using non-standard file extensions and the null is for the optional callback (which we don't need for such a simple case).
My answer to the original question and to anyone else that may have this problem:
I was having this same problem, images in my app that people saved to the SD card were not showing up in their Gallery immediately. After some searching I found this one line of code inserted after my 'save to sdcard' code that fixed the problem:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
The system scans the SD card when it is mounted to find any new image (and other) files. If you are programmatically adding a file, then you can use this class:
http://developer.android.com/reference/android/media/MediaScannerConnection.html
You can also add an Image to the Media Gallery by intent, have a look at the example code to see how it is done:
ContentValues image = new ContentValues();
image.put(Images.Media.TITLE, imageTitle);
image.put(Images.Media.DISPLAY_NAME, imageDisplayName);
image.put(Images.Media.DESCRIPTION, imageDescription);
image.put(Images.Media.DATE_ADDED, dateTaken);
image.put(Images.Media.DATE_TAKEN, dateTaken);
image.put(Images.Media.DATE_MODIFIED, dateTaken);
image.put(Images.Media.MIME_TYPE, "image/png");
image.put(Images.Media.ORIENTATION, 0);
File parent = imageFile.getParentFile();
String path = parent.toString().toLowerCase();
String name = parent.getName().toLowerCase();
image.put(Images.ImageColumns.BUCKET_ID, path.hashCode());
image.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, name);
image.put(Images.Media.SIZE, imageFile.length());
image.put(Images.Media.DATA, imageFile.getAbsolutePath());
Uri result = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, image);
Gallery refresh including Android KITKAT
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File("file://"+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
else
{
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}
Here is the code for the MediaScannerConnection:
MyMediaConnectorClient client = new MyMediaConnectorClient(newfile);
MediaScannerConnection scanner = new MediaScannerConnection(context, client);
client.setScanner(scanner);
scanner.connect();
newfile is the File object of your new/saved file.
there is an app in the emulator that says - ' Dev Tools'
click on that and select ' Media Scanning'.. all the images ll get scanned
Let your activity implement 'MediaScannerConnectionClient'
and add this to your activity:
private void startScan()
{
if(conn!=null) conn.disconnect();
conn = new MediaScannerConnection(YourActivity.this,YourActivity.this);
conn.connect();
}
#Override
public void onMediaScannerConnected() {
try{
conn.scanFile(yourImagePath, "image/*");
} catch (java.lang.IllegalStateException e){
}
}
#Override
public void onScanCompleted(String path, Uri uri) {
conn.disconnect();
}
this work with me
File file = ..... // Save file
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
File folderGIF = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/newgif2"); //path where gif will be stored
success = folderGIF.mkdir(); //make directory
String finalPath = folderGIF + "/test1.gif"; //path of file
.....
/* changes in gallery app if any changes in done*/
MediaScannerConnection.scanFile(this,
new String[]{finalPath}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
Here I am sharing code that can load image in form of bitmap from and save that image on sdcard gallery in app name folder.
You should follow these steps
Download Image Bitmap first
private Bitmap loadBitmap(String url) {
try {
InputStream in = new java.net.URL(url).openStream();
return BitmapFactory.decodeStream(in);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Please also provide following permission in your AndroidManifest.xml file.
uses-permission android:name="android.permission.INTERNET"
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
Here is whole code that is written in Activty in which we want to perform this task.
void saveMyImage(String appName, String imageUrl, String imageName) {
Bitmap bmImg = loadBitmap(imageUrl);
File filename;
try {
String path1 = android.os.Environment.getExternalStorageDirectory()
.toString();
File file = new File(path1 + "/" + appName);
if (!file.exists())
file.mkdirs();
filename = new File(file.getAbsolutePath() + "/" + imageName
+ ".jpg");
FileOutputStream out = new FileOutputStream(filename);
bmImg.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
ContentValues image = new ContentValues();
image.put(Images.Media.TITLE, appName);
image.put(Images.Media.DISPLAY_NAME, imageName);
image.put(Images.Media.DESCRIPTION, "App Image");
image.put(Images.Media.DATE_ADDED, System.currentTimeMillis());
image.put(Images.Media.MIME_TYPE, "image/jpg");
image.put(Images.Media.ORIENTATION, 0);
File parent = filename.getParentFile();
image.put(Images.ImageColumns.BUCKET_ID, parent.toString()
.toLowerCase().hashCode());
image.put(Images.ImageColumns.BUCKET_DISPLAY_NAME, parent.getName()
.toLowerCase());
image.put(Images.Media.SIZE, filename.length());
image.put(Images.Media.DATA, filename.getAbsolutePath());
Uri result = getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, image);
Toast.makeText(getApplicationContext(),
"File is Saved in " + filename, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
Hope that it can solve your whole problem.
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
Does not seem to work on KITKAT. It throws permission denial exception and crashes the app.
So for this, I have done the following,
String path = mediaStorageDir.getPath() + File.separator
+ "IMG_Some_name.jpg";
CameraActivity.this.sendBroadcast(new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri
.parse("file://" + path)));
Hope it helps.
Use this after saving the image
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
My code for MyMediaConnectorClient:
public class MyMediaConnectorClient implements MediaScannerConnectionClient {
String _fisier;
MediaScannerConnection MEDIA_SCANNER_CONNECTION;
public MyMediaConnectorClient(String nume) {
_fisier = nume;
}
public void setScanner(MediaScannerConnection msc){
MEDIA_SCANNER_CONNECTION = msc;
}
#Override
public void onMediaScannerConnected() {
MEDIA_SCANNER_CONNECTION.scanFile(_fisier, null);
}
#Override
public void onScanCompleted(String path, Uri uri) {
if(path.equals(_fisier))
MEDIA_SCANNER_CONNECTION.disconnect();
}
}
You need to give permissions to the Gallery app.
Just long press the gallery app icon in the home screen and tap on 'APP INFO' that pops up at the top of the screen. Doing it will show the gallery app settings. Now go in Permissions tab and enable the storage, camera permissions by toggling it.
Now go to your native gallery app and you will get the your saved images.
This will aslo solve your problem if your image in gallery are not showing instead they might showing a 404 type bitmap in midle.
please add a the tags that are in my code with your image because there must some meta data in order to show image in gallery.
String resultPath = getExternalFilesDir(Environment.DIRECTORY_PICTURES)+
getString(R.string.directory) + System.currentTimeMillis() + ".jpg";
new File(resultPath).getParentFile().mkdir();
try {
OutputStream fileOutputStream = new FileOutputStream(resultPath);
savedBitmap.compress(CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (IOException e2) {
e2.printStackTrace();
}
savedBitmap.recycle();
File file = new File(resultPath);
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "Photo");
values.put(MediaStore.Images.Media.DESCRIPTION, "Edited");
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis ());
values.put(MediaStore.Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(MediaStore.Images.ImageColumns.BUCKET_ID, file.toString().toLowerCase(Locale.US).hashCode());
values.put(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME, file.getName().toLowerCase(Locale.US));
values.put("_data", resultPath);
ContentResolver cr = getContentResolver();
cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
return resultPath;
Try this one, it will broadcast about a new image created, so your image visible. inside a gallery.
photoFile replace with actual file path of the newly created image
private void galleryAddPicBroadCast() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(photoFile);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}