Delete picture taken from camera gets corrupted - android

I have a small app that calls the intent of image_capture from android, takes and then deletes it from the gallery.
Well, the picture is not deleted, well, not completely, the best result that I get it's this:
My code is simple, based on what I found around internet:
success = new File(imageUrl).delete();
//deleteFile(imageUrl);
if(success)
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
What can I do to solve this problem?

Related

Image not added to Gallery

I have followed tutorials and Stackoverflow's questions without any success.
What I have to do is: take a picture from Camera, save it and show it in the gallery.
I don't know why with the following code, the image is not added to the gallery. The code doesn't give any error and I have checked with some Log.i that it is fully executed. But the problem remains: the picture is taken but not shown into the gallery.
Because of my code is really long, I report only the key parts in order to make the reading easier. I hope that it is clear enough.
File mFile = new File(Environment.DIRECTORY_PICTURES, "pic.jpg");
mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile)); // it saves the image
Uri contentUri = Uri.fromFile(mFile);
getActivity().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, contentUri));

Android - Generate Thumbnails in Gallery

I am currently creating a camera app and storing it. However, every time I take a picture, the picture is saved in the directory but is not saved in the Gallery. I think it's all about the generation of thumbnail right after the image has been taken. How can you generate a thumbnail in the gallery?
Try this:
Intent mediaScan = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScan.setData(uri);
context.sendBroadcast(mediaScan);
If you are adding files or images programmatically, you have to use MediaScannerClass to scan the media file for your sd card.
of you can also use following piece of code:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));

"Unable to play video, Sorry this video cannot be played" when trying to display video from camera intent

I am having a weird problem. (I am new to android) In my app I have an intent to launch the video camera as well as one to launch the camera. Now what seems to happen is when I click on the image button to display image, it then display the images. But when trying to display video it says "unable to play video". So I thought there was something wrong with my phone so I restarted my phone and it then seemed to play. So when testing again it doesn't.
So I know there is nothing wrong with my code, but can't seem to display the video after it has been taken. (and only plays after a reboot of the device)
Could someone please help me?
Thanks
EDIT
To take the video I use:
Intent imageIntent = new Intent (android.provider.MediaStore.ACTION_VIDEO_CAPTURE);
timeStamp = new SimpleDateFormat("ddMMMyyyy_HH:mm:ss").format(new Date());
File videosFolder = new File(Environment.getExternalStorageDirectory(), "Cool Videos");
videosFolder.mkdirs();
image = new File(imagesFolder.getPath(), "Cvidoes_" + timeStamp + ".mp4");
fUri = Uri.fromFile(image);
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(imageIntent, TAKE_PICTURE);
And then in my "display full screen"
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(temp_file),getMimeType(temp_file.getAbsolutePath()));
startActivity(intent);
But the weird thing is worked before I recently updated to android version 5.0.
EDIT 2
Okay I have solved the issue.
I have pretty much nothing in my "OnActivityResult" section, but added this and all is working again:
MediaScannerConnection.scanFile(
getApplicationContext(),
new String[]{image.getAbsolutePath()},
null,
new OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
Log.v("VideoScan",
"file " + path + " was scanned seccessfully: " + uri);
}
});
So why since the update it stopped working and now have to add this?
So why since the update it stopped working and now have to add this?
Strictly speaking, we can't really answer this definitively.
What you added was code to arrange to have your video be indexed by the MediaStore. A video player receiving a file:/// Uri — as you are using in your ACTION_VIEW Intent — should not really care about MediaStore. Apparently, yours does, or does after your device was upgraded to Android 5.0. IMHO, that's a bug in the video player.
Now, in general, if you want the user to be able to work with the video separately from your app, you need to get it indexed by the MediaStore. That will happen automatically... eventually. Your code addition makes it happen much more quickly, which is generally a good idea.
So, I'd look at it more that you tripped over a bug in the video player, whose fix happened to be some code that you probably needed anyway.
In other words, it's just another day at the office... :-)

Thumbnail isn't refresh immediately

I'm making a file manager in which picture items have a small thumbnail.
I get thumbnail image by using MediaStore. Everything works fine. But when I rename or move a file, the thumbnail does not show up.
I've found a piece of code to refresh MediaStore:
getActivity().sendBroadcast(
new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://" + Environment.getExternalStorageDirectory())));
It worked but I must wait 4 or 5 second and refresh, then the thumbnail updates.
How to get thumbnail of image immediately after rename or moving?
What happen if you use ACTION_MEDIA_SCANNER_SCAN_FILE instead of ACTION_MEDIA_MOUNTED, (i.e. trigger a refresh for a single file instead of for the complete directory hierarchy) ?
You will need to replace the URI of the directory with the URI of the file, obtained for example using Uri.fromFile().
When you move or rename a file you should refresh the old and the new URIs.
The recommended way to update one specific image in Android is using ACTION_MEDIA_SCANNER_SCAN_FILE intent. And for smoother
You can check it at Basic Photo Handling Training in Android Developer Site.
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
If you want to show new thumbnail immediately for some missing files, you can do it by yourself. First, check the MediaStore as before, and if the returned thumbnail is null then generate your own one using ThumbnailUtils or BitmapFactory.
And, For handling a bitmap and displaying it, there is a quiet straightforward sample in Android Training Course.
Have you tried doing the scan directly on the directory you are changing? So instead of
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
something like
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory() + "/path/to/your/folder")));
An alternative would be to manually use ThumbnailUtils.
Actually sending Intent.ACTION_MEDIA_MOUNTED broadcast intent is really ugly. Read this post http://androidyue.github.io/blog/2014/01/19/scan-media-files-in-android As to renaming files. You should remove the older file from the library and then add the new one into the library. I think this could help you.

Scan Android SD card for new files

My app allows a user to save an image to their SD card. But I'm not sure how to make it appear in the gallery until you unmount and remount the SD card. I have googled for a couple of days with this problem but am not sure how to make it appear automatically. I found
this link but I'm not sure how to use the class. This is what i use to save the file. At the bottom of the try catch block is where I want to scan the sd card for new media.
FileOutputStream outStream = null;
File file = new File(dirPath, fileName);
try {
outStream = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
} catch {
...
}
If anyone could point me in the right direction, I would appreciate.
I've tried plenty of different methods to trigger the MediaScanner, and these are my results.
SendBroadcast
The most simple and naive solution. It consists in executing the following instruction from your code:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"+ Environment.getExternalStorageDirectory())));
However, this no longer works in KitKat devices, due to a lack of required permissions.
MediaScannerWrapper
As posted here (per #Brian's answer), it consists in wrapping a MediaScannerConnection instance in order to trigger the scan() method over a specific directory. This method has proven to be working fine for 4.3 and below, but still no luck with KitKat (4.4+).
FileWalker
One of the many Play Store apps that tries to overcome the MediaStore's lack of commitment to update its database is ReScan SD. It sends a lot of different broadcasts:
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file://" + Environment.getExternalStorageDirectory())));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable")));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable/SD")));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable/MicroSD")));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///mnt/Removable/MicroSD")));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///mnt")));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///storage")));
sendBroadcast(new Intent("android.intent.action.MEDIA_MOUNTED", Uri.parse("file:///Removable")));
and tries to support KitKat by manually triggering the scan() method over each file of the base directory. Unfortunately, this is both very CPU-intensive and time-consuming, so it is not very recommended.
"The shell way"
The only thing that seem to work with KitKat in some cases is sending the broadcast via adb shell. So, this snippet allows you to do just that programmatically:
Runtime.getRuntime().exec("am broadcast -a android.intent.action.MEDIA_MOUNTED -d file://" + Environment.getExternalStorageDirectory());
It is more of an hack-ish way of doing it, but at the moment is the best I could come up with.
Bottom line
Each of the above solutions actually works for everything that is not KitKat. That's because, thanks to Justin, a bug has been found and issued to the official Tracker. This means that, until the bug is ironed out, we are left with no true KitKat support.
Which one to use? Among those, I would use the MediaScannerWrapper solution, together with the shell-ish approach (the last one).
Since the last answer I posted apparently wasn't an appropriate method, I found another method here. You basically create a wrapper class, initialize it, and then call the scan() method. Very helpful post. Let me know if this isn't appropriate either.
Use MediaScannerConnection:
http://developer.android.com/reference/android/media/MediaScannerConnection.html
It can be a little bit of a pain because of the multiple levels of asynchronous calls, so as of API 8 (Froyo) there is a helper function:
http://developer.android.com/reference/android/media/MediaScannerConnection.html#scanFile(android.content.Context, java.lang.String[], java.lang.String[], android.media.MediaScannerConnection.OnScanCompletedListener)
You could also call media scanner explicitly by sending broadcast.
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri
.parse("file://"
+ Environment.getExternalStorageDirectory())));
Edit
This was an old post. Updating it to new versions
Android is taking steps to prevent apps from spoofing more system broadcasts like this.
If you want to tell Android to index a file you put on external storage, either use MediaScannerConnection or ACTION_MEDIA_SCANNER_SCAN_FILE
Reference: This post
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
final Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
final Uri contentUri = Uri.fromFile(outputFile);
scanIntent.setData(contentUri);
sendBroadcast(scanIntent);
} else {
final Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()));
sendBroadcast(intent);
}
If the above piece of code is not working you can try the following:
MediaScannerConnection.scanFile(this, new String[] {
file.getAbsolutePath()
}, null, new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
}
});
Here is another way to force scan:
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,"uri to file"));
And then system will fire ACTION_MEDIA_SCANNER_FINISHED broadcast so you can react on it with BroadcastReceiver
In order to be able to receive ACTION_MEDIA_SCANNER_FINISHED broadcast, intent filter should contain data scheme:
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_SCANNER_FINISHED);
intentFilter.addDataScheme("file");
context.registerReceiver(mMediaScannerFinishReceiver, intentFilter);
from the doc:
public static final String ACTION_MEDIA_SCANNER_SCAN_FILE
Added in API level 1 Broadcast Action: Request the media scanner to
scan a file and add it to the media database. The path to the file is
contained in the Intent.mData field.
and
public static final String ACTION_MEDIA_SCANNER_FINISHED
Added in API level 1 Broadcast Action: The media scanner has finished
scanning a directory. The path to the scanned directory is contained
in the Intent.mData field.
You can use MediaStore.Images.Media.insertImage to insert an item into the gallery.

Categories

Resources