Hi I am trying to save an image to the .thumbnails folder as shown below:
bitmap = ThumbnailUtils.extractThumbnail
(BitmapFactory.decodeFile(actualImagePath,options), 120, 120);
bitmapGenerated = true;
File file = new File(Environment.getExternalStorageDirectory()
.toString()+"/"+"DCIM/.thumbnails/"+id+".jpg");
boolean bcc =file.createNewFile();
boolean success = bitmap.compress(Bitmap.CompressFormat.PNG,60,new
FileOutputStream
(file));
The 'id' is actually the id of the particular image that I am trying to save and is obtained from a cursor as shown:
image_column_index = mCursor.getColumnIndex(MediaStore.Images.Media._ID);
id = mCursor.getLong(image_column_index);
The image gets saved in the '.thumbnails' , however, as I try to access the image thumbnail that I just created, it is not read.
I think it was because of the name I gave to the thumbnail image.
So my question is it okay to save to '.thumbnails' folder and if so in what name should we save the file?
Help is really appreciated,
Thank You.
I found out that to generate a thumbnail we don't need to explicitly create a thumbnail image file and put it in the .thumbnials folder.
There is a method called getThumbnail in MediaStore.Images.Media that we can use for our purpose. Code is as shown:
Cursor mCursor;
mCursor = mContext.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null,
null, null, null);
int image_column_index = mCursor.getColumnIndex(MediaStore.Images.Media._ID);
long id = mCursor.getLong(image_column_index);
MediaStore.Images.Thumbnails.getThumbnail(mContext
.getContentResolver(), id, MediaStore.Images.Thumbnails.MINI_KIND, null);
The above code will generate a thumbnail for the associated imageid , first we have to make sure that the thumbnail doesn't exist and create a new one only if one doesn't exist.
Related
I'm using org.apache.commons.io.FileUtils to move files from one directory to another, like so:
File source = new File("/my/image/directory/image.jpg";
File destination = new File("/new/image/directory/image.jpg");
FileUtils.moveFile(source, destination);
Note that the source directory is an external directory and destination is an internal directory.
After above code is executed, I query to get the files of my internal directory like so:
File vaultDir = ctx.getDir("dir_name", Context.MODE_PRIVATE);
String[] fileList = vaultDir.list();
//Iterate and print file names
This is working as intended. But when i query the MediaStore like so:
ArrayList<GridViewObject> objects = new ArrayList<>();
String[] mProjection = {MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.DATA};
ContentResolver cr = ctx.getContentResolver();
Cursor mCursor = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
mProjection,
null,
null,
MediaStore.Images.Media.DEFAULT_SORT_ORDER);
mCursor.moveToFirst();
while (!mCursor.isAfterLast()) {
GridViewObject tmpGridViewObject = new GridViewObject();
tmpGridViewObject.setTitle(mCursor.getString(0));
tmpGridViewObject.setUrl(mCursor.getString(1));
objects.add(tmpGridViewObject);
mCursor.moveToNext();
}
The image is still returned to me by the query. Also, when I open my camera gallery app, the image is still there, as if it was never deleted.
I noticed that if I restart the phone, the image disappears from my device camera gallery app as intended (and above query return correct result). So I think it might be an indexing problem.
What do I need to do to "update" the MediaStore to show the intended result?
I solved this by instead of deleting the file using FileUtils.delete(srcFile, destFile); i copied the the file using FileUtils.copy(srcFile, destFile); and then to refresh MediaStore i used the following code to delete the source entry:
String selection = MediaStore.Images.Media.DATA + "='" + source.getAbsolutePath() + "'";
ctx.getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, null);
Credit goes to Pascal's answer to this question.
I am populating a gridview with MICRO_KIND thumbnails using the following:
/* Find images of interest */
imagecursor = getActivity().getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CON TENT_URI,
columns,
MediaStore.Images.Media.DATA + " like ? ",
new String[]{"%/houseTab" + currentHouseNumber + "/%"},
null);
/* Retrieve MICRO_KIND Thumbnails */
int id = imagecursor.getInt(image_column_index);
thumbnails[i] = MediaStore.Images.Thumbnails.getThumbnail(
getActivity().getApplicationContext().getContentResolver(), id,
MediaStore.Images.Thumbnails.MICRO_KIND, null);
The retrieve process works perfectly; the issue happen when I delete the actual image files I can not delete the MICRO_KIND Thumbnails. This is what I am using right now and the files images gets deleted but the MICRO_KIND does not get deleted and still visible in the gridview even after a refresh. To get rid of the thumbnail I have to turn off the device or do a unmount/mount of the sdcard.
int count = imagecursor.getCount();
int image_column_index = imagecursor.getColumnIndex(MediaStore.Images.Media._ID);
ContentResolver cr = getActivity().getApplicationContext().getContentResolver();
for (int i = 0; i < count; i++) {
new File(arrPath[i]).delete(); // Delete the actual image file
imagecursor.moveToPosition(i);
long id = imagecursor.getInt(image_column_index);
/* Delete the thumbnails ???? Not working */
cr.delete(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, MediaStore.Images.Thumbnails.IMAGE_ID +
"= ?",new String[]{"" + id});
By the way arrPath is retrieve from the mediastore using the following:
int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.DATA);
arrPath[i] = imagecursor.getString(dataColumnIndex);
I also try to following to delete the thumbnails but also without any success.
MediaScannerConnection.scanFile(
getActivity().getApplicationContext(),
new String[]{arrPath[i]},
null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
refreshImages();
}
});
So how do I remove this entry from the database so the when the imagecursor is refreshed after the file deletion the imagecursor is empty and no MICRO_KIND or any data for that matter is returned???
Any help would be appreciated.
Hopefully this will help others. I manage to delete the entry from the mediastore hence the MICRO_KIND thumbnails using the following:
Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
id);
cr.delete(uri,null,null);
I'm having this same problem, I couldn't find any way to delete the MICRO_KIND thumbnails no matter what I did, so I peeked through the MediaStore source code and saw that there were references to the /sdcard/DCIM/.thumbnails/.thumbdata3--##### file, and it looks like thats where the MICRO_KIND thumbnails are stored.
The MediaStore database holds records that point to the thumbnail files in the /sdcard/DCIM/.thumbnails folder, so when you delete a thumbnail from MediaStore, it also deletes the file under that folder (which appear to be the MINI_KIND thumbnails since they are considerably larger than MICRO_KIND).
When I deleted the /sdcard/DCIM/.thumbnails/.thumbdata--BLAHBLAH file through ADB, it fixed my problem, the correct thumbnails loaded and I noticed the file instantly was recreated.
I also noticed when I deleted the file throught he ContentResolver like you did, and then queried the MINI_KIND thumbnails, they always loaded correctly.
So my answer (which seems more like a workaround than an answer) was to query the MINI_KIND thumbnails from the MediaStore, and extract a thumbnail from that:
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 3;
Bitmap out = MediaStore.Images.Thumbnails.getThumbnail(contentResolver, imageId, MediaStore.Images.Thumbnails.MINI_KIND, opts);
out = ThumbnailUtils.extractThumbnail(out, 96, 96);
And delete the thumbnail using user2553585's answer
Hope this helps
For my application, I need to refresh thumbnail image of gallery.
Because whenever I update my image content that thing don't reflected on thumbnail. The thumbnail image show first time image creation data not the present one.
But actual image contain new data so I need to reflect it into thumbnail also.
After wandering this forum I found following code snipper to delete current thumbnail but I can't able to call this function because I don't able to get photoId.
private static void removeThumbnails(ContentResolver contentResolver, long photoId) {
Cursor thumbnails = contentResolver.query(Thumbnails.EXTERNAL_CONTENT_URI, null, Thumbnails.IMAGE_ID + "=?", new String[]{String.valueOf(photoId)}, null);
for (thumbnails.moveToFirst(); !thumbnails.isAfterLast(); thumbnails.moveToNext()) {
long thumbnailId = thumbnails.getLong(thumbnails.getColumnIndex(Thumbnails._ID));
String path = thumbnails.getString(thumbnails.getColumnIndex(Thumbnails.DATA));
File file = new File(path);
if (file.delete()) {
contentResolver.delete(Thumbnails.EXTERNAL_CONTENT_URI, Thumbnails._ID + "=?", new String[]{String.valueOf(thumbnailId)});
}
}
At present I was calling this function as
removeThumbnails(pexelMimics.getContentResolver(),
ContentUris.parseId(uri));
I think this trick will work for me. But this is my guess. If you guys have better solution for this problem then please help me.
At the time of image saving, I have to provide following code to delete image content.
activity.getContentResolver().delete(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
MediaColumns.DATA
+ "='"
+ GameManager.getInstance().getSavedImageFilePath()
.replaceAll("'", "''") + "'", null);
After this I got new content in thumbnail icon.
You don't mention what class and inheritance you have; if you are in a class the inherits BaseAdapter, then you can do
notifyDataSetChanged();
after you change the thumbs.
I am trying to rename an image in Gallery taken from Camera to give a new name. When I renamed the file the original image disappears showing 2 black squares . Can any one help me in sorting this issue by telling me procedure to rename Gallery Image.
Path is as follows : /mnt/sdcard/DCIM/Camera
I tried to update the Image title through content provider as below:
ContentValues val = new ContentValues();
val.put(Images.Media.TITLE, "ImageTitle23");
getContentResolver().update(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, val, null, null);
The image title is changed in Gallery.
But when I try to query the updated image as below I am getting the name same as previous one :
final String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA };
final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
Cursor imageCursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns, MediaStore.Images.Media._ID+"="+id, null, imageOrderBy);
if(imageCursor.moveToFirst()){
int idd = imageCursor.getInt(imageCursor.getColumnIndex(MediaStore.Images.Media._ID));
String fullPath = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
Can anyone help me in sorting out this issue?
The MediaStore looks for changes in your pictures BUT it will not react to all changes in real time. Each time you do such a modification, you should ask the MediaScanner to scan this file:
MediaScannerConnection.scanFile(
getApplicationContext(),
new String[]{file.getAbsolutePath()},
null,
new OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
Log.v("grokkingandroid",
"file " + path + " was scanned seccessfully: " + uri);
}
});
Also, you should check this blog post that gives a lot of useful informations on this usecase.
The Gallery is interacting with the MediaStore content provider. If you change the name of the image file you probably need to update the field in the content provider.
You can read up on it in the MediaStore reference : http://developer.android.com/reference/android/provider/MediaStore.Images.Media.html
Potentially you can just trigger a refresh of the MediaStore. Look at this thread : How can I refresh MediaStore on Android?
Can i get an image from SD card and store it in the application database??
Is this idea effective in my application??
Thanks in advance!!
Regards
Yes you can get the image from your sd card and store it in sqlite database, we have done it but it will be too expensive for your device....... So be careful about that,
call image picker intent by calling this
Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
startActivityForResult(i, 12);
It will open default gallery picker view , when you select an image you will be returned in your current activity, So override onActivityResult() and look for result code 12.
in that code you can get cursor by these lines
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
From that cursor object you can get the file path of image by these lines
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
Here is the bitmap object
Bitmap bMap = BitmapFactory.decodeFile(filePath);
Get byte arrays
ByteArrayOutputStream out = new ByteArrayOutputStream();
bMap.compress(Bitmap.CompressFormat.PNG, 100,out);
byte[] imageArray = out.toByteArray();
Now you have to store imageArray as blob in your database. And you are done.... Don't forget to refer this post from where i got the solution...