So in my application I at one point save a bunch of images to a temporary folder, and I want them to show up immediately in the Gallery. Off of a reboot, they do, but otherwise they don't.
I've tried using the sendBroadcast method:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
But I get a permission error:
E/AndroidRuntime( 2628): java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.MEDIA_MOUNTED from pid=2628, uid=10068
Could I be missing a permission in my AndroidManifest, or is this just no longer supported? Thanks
Code provided by Petrus in another answer works for me on Kitkat (4.4):
MediaScannerConnection.scanFile(this, new String[] { Environment.getExternalStorageDirectory().toString() }, null, new MediaScannerConnection.OnScanCompletedListener() {
/*
* (non-Javadoc)
* #see android.media.MediaScannerConnection.OnScanCompletedListener#onScanCompleted(java.lang.String, android.net.Uri)
*/
public void onScanCompleted(String path, Uri uri)
{
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
I tried Environment.getExternalStorageDirectory().toString(), but it didn't find my custom folder.
I just wanted to share my experience to solving this issue.
At the end, I had MediaScannerConnection configured to scan one file at a time and now missing folder that was holding those images showed up. Every time I download each image, I called MediaScannerConnection and file path as Uri instead of folder itself.
Also, many people asked why sendBroadcast stop working on kitkat and the answer is that sendBroadcast was abused and called too many times and causing system to drain battery or slowdown, so they removed the direct call to prevent abuse which makes sense. I was hoping to use above solution to the folder that hold all images, but it didn't work on the folder. I was hoping that finding folder would expose rest of the files within the custom folder, but it didn't in my case. I am hoping to find better answer in the future...
Here's snippet of my code.
MediaScannerConnection.scanFile(ApplicationContext.context, new String[] { imageFile.getPath() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
Log.i(TAG, "Scanned " + path);
}
});
Try this one:
after saving your file to folder,write below code
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File("your image path"))));
Below code work all device for refreshing the gallery after saving image.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f1 = new File("file://" + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));
Uri contentUri = Uri.fromFile(f1);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
} else {
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
}
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File("your image path"))));
Implement MediaScannerConnectionClient and add the below code.Works perfectly in 4.4 :)
MediaScannerConnection conn;
public void startScan(String url) {
imagepath = url;
if (conn != null)
conn.disconnect();
conn = new MediaScannerConnection(activity.this, activity.this);
conn.connect();
}
#Override
public void onMediaScannerConnected() {
try {
conn.scanFile(imagepath, getMimeType(imagepath));
} catch (java.lang.IllegalStateException e) {
//Do something
}
}
#Override
public void onScanCompleted(String path, Uri uri) {
conn.disconnect();
}
I know its late but try this can working in all versions:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(out); //out is your file you saved/deleted/moved/copied
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
} else {
sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
}
Use MediaScannerConnection instead of SendBroadcast..
MediaScannerConnection.MediaScannerConnectionClient(
{
#Override
public void onScanCompleted(String path, Uri uri) {
if (path.equals(**your filename**.getAbsolutePath()))
{
Log.i("Scan Status", "Completed");
Log.i("uri: ",uri.toString());
conn.disconnect();
}
}
#Override
public void onMediaScannerConnected()
{
// TODO Auto-generated method stub
conn.scanFile(**your file name**.getAbsolutePath(),null);
}
});
conn.connect();
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
//Gallery Refresh Code
MediaScannerConnection.scanFile(getActivity(), new String[] { Environment.getExternalStorageDirectory().toString() }, null, new MediaScannerConnection.OnScanCompletedListener() {
/*
* (non-Javadoc)
* #see android.media.MediaScannerConnection.OnScanCompletedListener#onScanCompleted(java.lang.String, android.net.Uri)
*/
public void onScanCompleted(String path, Uri uri)
{
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
out.close();
Related
Hi I am trying to save image in my gallery but the issue is that, not able to see in my gallery, following is my code can any one help?
public void OnClickSave(View view)
{
Bitmap bitmap =getBitmapFromView(idForSaveView);
try {
ContextWrapper wrapper = new ContextWrapper(context);
File file = wrapper.getDir("MilMilaImages",MODE_PRIVATE);
// Create a file to save the image
file = new File(file, "MilMila"+".jpg");
try{
OutputStream stream = null;
stream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG,100,stream);
stream.flush();
stream.close();
}catch (IOException e) // Catch the exception
{
e.printStackTrace();
}
// Parse the gallery image url to uri
final Uri savedImageURI = Uri.parse(file.getAbsolutePath());
// Display the saved image to ImageView
System.out.println("HLL"+savedImageURI);
iv.setImageURI(savedImageURI);
MediaScannerConnection.scanFile(context, new String[] { file.getAbsolutePath()},
null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
context.sendBroadcast(mediaScanIntent);
} else {
context.sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"
+ Environment.getRootDirectory())));
}
// Display saved image uri to TextView
// Toast.makeText(context,"Saved Successfully",Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
I have used this code and it works for me :
// show the image in the device gallery
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
val mediaScanIntent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
val contentUri = Uri.fromFile(compressFile) //out is your output file
mediaScanIntent.data = contentUri
this.sendBroadcast(mediaScanIntent)
} else {
sendBroadcast(Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())))
}// // show the image in the device gallery
I am creating an android app where I take a picture using camera intent, then store the picture in the picture directory. Then my app required to upload it. But, As I take the first picture from the app I can't see it in the gallery. But, from the second picture I take I can see them in the gallery. What to do?
here is my code: Here I display my pic on an image button:
mImageSelect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
Intent galleryIntent=new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent,GALLERY_REQUEST);
}catch (Exception e){
Toast.makeText(getApplicationContext(),"There was an ERROR: "+e,Toast.LENGTH_LONG).show();
Intent intent=new Intent(PostActivity.this,AllPosts.class);
}
}
});
// I am saving it with mediastore.
MediaScannerConnection.scanFile(HomeActivity.this,
new String[] {imageFile.getAbsolutePath()},
new String[] {"image/jpeg"},null);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(imageFile)));
Use below method for API level below 19 to scan media file.
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
For API level 19 or above scan media file like below.
private void scanFile(String path) {
MediaScannerConnection.scanFile(MainActivity.this,
new String[] { path }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("TAG", "Finished scanning " + path);
}
});
}
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())));
}
Given a bitmap that I want to save to a special folder in the public Gallery on the phone, I tried this:
public static void saveToGallery(Context context, Bitmap bitmap) {
File path = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), File.separator + "FolderForMyApp");
path.mkdirs();
File imageFile = new File(path, "image_name.png");
FileOutputStream out = null;
try {
out = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
}
catch (IOException e) {
Log.w(TAG, "Could not resolve file stream: " + e);
}
}
However it does not actually show up in the Gallery. What am I doing wrong?
It does not appear on the gallery because you have to refresh the gallery, so it knows about the new file
// 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);
}
});
Sry about the formatting. I'm on my phone.
I have an app where the user creates an image and then I want to save it so it's visible form the default gallery application.
Now I don't want the pictures to be saved in the same folder as the pictures taken from the camera, I want them to be saved in a folder dedicated to the app, just like images from apps like whatsapp or facebook.
I've tried saving them in this two locations:
File imagePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)+ File.separator + appDirectoryName + File.separator);
and here
File imagePath = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)+ File.separator + appDirectoryName + File.separator);
If I browse through the phone I see that I successfully save the images but they don't show in the gallery app. It is obvious that I'm missing something but I don't know what it is. Maybe adding some kind of metadata to the files or folders so the gallery recognizes them?
Well I found the answer in the end.
It turned out to be what I suspected. The saved image needs to have some metadata added in order to be seen in the gallery (at least in my device).
This is what I did:
OutputStream fOut = null;
File file = new File(imagePath,"GE_"+ System.currentTimeMillis() +".jpg");
try {
fOut = new FileOutputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
try {
fOut.flush();
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, this.getString(R.string.picture_title));
values.put(Images.Media.DESCRIPTION, this.getString(R.string.picture_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);
I have had the same problem.
The second way is the correct way, but you don't see the images in the Gallery because the gallery needs to be refreshed.
So, you can wait a while until it refreshes itself, or you can use the MediaScanner -
look here
Hope this helped!
I did the following to get it to work:
public void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_MOUNTED);
String mCurrentPhotoPath = "file:" + image.getAbsolutePath(); // image is the created file image
File file = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
}
Try this
private void createDirectoryAndSaveFile(Bitmap imageToSave, String fileName) {
File direct = new File(Environment.getExternalStorageDirectory() + "/DirName");
if (!direct.exists()) {
File wallpaperDirectory = new File("/sdcard/DirName/");
wallpaperDirectory.mkdirs();
}
File file = new File(new File("/sdcard/DirName/"), fileName);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
I tried this it works perfectly.
private Uri imageUri;
String getimgname, getimgpath;
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File photo = new File(Environment.getExternalStorageDirectory(), "IMG"+System.currentTimeMillis()+".jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photo));
imageUri = Uri.fromFile(photo);
getimgname = photo.getName();
getimgpath = photo.getAbsolutePath();
Try this
MediaScannerConnection.scanFile(context,
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);
}
});
How to refresh gallery the in android kitkat ?
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
I tried with the above, but its not refreshing in android 4.4. How to refresh the gallery when add/delete the images programatically ?
This works for me :)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File("folderPATH", "fileName");
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
appContext.sendBroadcast(mediaScanIntent);
} else {
appContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory() + "/" + "FOLDER_TO_REFRESH")));
}
Hope it helps :)
You can use following technique to update all files present in a single folder:
for (File child : fileFolder.listFiles()) {
if (child.isFile()) {
fName = child.getName();
Log.d("MyTag", "Scanning >> " + child.getName());
MediaScannerConnection
.scanFile( MyActivity.this,
new String[] { "path/of/our/folder" + fName },
null, new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(
String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
}
}
Source: here
Use this code to add/ refresh gallery images.
String version = Build.VERSION.RELEASE;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_MOUNTED);
String mCurrentPhotoPath = "file://"
+ Environment.getExternalStorageDirectory() + "/AppDirectory"; // image
// is
// the
// created
// file
// image
File file = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(file);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent);
} else {
MediaScannerConnection.scanFile(this, new String[] { Environment
.getExternalStorageDirectory().toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
/*
* (non-Javadoc)
*
* #see android.media.MediaScannerConnection.
* OnScanCompletedListener
* #onScanCompleted(java.lang.String, android.net.Uri)
*/
public void onScanCompleted(String path, Uri uri) {
Log.i(TAG, "Scanned ................" + path);
}
});
}