CursorWindowAllocationException from MediaStore.Images.Thumbnails.getThumbnail - android

I am getting an occasional (quite rare) exception from MediaStore.Images.Thumbnails.getThumbnail (see below). Similar questions were advised to always close the cursor, but I am not performing an explicit query.
I call it like this:
a private function reading the thumbnails.. (
private Bitmap getThumbnail(long imageId) { return MediaStore.Images.Thumbnails.getThumbnail(context.getContentResolver(), imageId,
MediaStore.Images.Thumbnails.MINI_KIND, null); }
It is called from here:
Cursor cursor = null;
int numProcessed = 0, numFaceDetected = 0;
try {
dirtyFile.createNewFile();
String[] projection = {
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DATA,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.ORIENTATION
};
cursor = getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection,
null,
null,
MediaStore.Images.Media.DATE_ADDED + " desc");
if (cursor == null) {
return;
}
cursor.moveToFirst();
final int columnIndexId = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
final int columnIndexData = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
final int columnIndexOrientation = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.ORIENTATION);
final int columnIndexBucketName = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
while (!cursor.isAfterLast()) {
final long imageId = cursor.getLong(columnIndexId);
final String imagePath = cursor.getString(columnIndexData);
final int imageOrientation = cursor.getInt(columnIndexOrientation);
Bitmap bitmap = getThumbnail(imageId);
faceDetect(bitmap);
cursor.moveToNext();
numProcessed++;
}
Here is the exception:
android.database.CursorWindowAllocationException: Cursor window could not be created from binder.
at android.database.CursorWindow.(CursorWindow.java:137)
at android.database.CursorWindow.(CursorWindow.java:42)
at android.database.CursorWindow$1.createFromParcel(CursorWindow.java:685)
at android.database.CursorWindow$1.createFromParcel(CursorWindow.java:683)
at android.database.BulkCursorDescriptor.readFromParcel(BulkCursorDescriptor.java:75)
at android.database.BulkCursorDescriptor$1.createFromParcel(BulkCursorDescriptor.java:34)
at android.database.BulkCursorDescriptor$1.createFromParcel(BulkCursorDescriptor.java:30)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:423)
at android.content.ContentResolver.query(ContentResolver.java:478)
at android.content.ContentResolver.query(ContentResolver.java:422)
at android.provider.MediaStore$InternalThumbnails.getThumbnail(MediaStore.java:680)
at android.provider.MediaStore$Images$Thumbnails.getThumbnail(MediaStore.java:1060)

Could you try replacing your thumb nail code with this
Cursor cursor = MediaStore.Images.Thumbnails.queryMiniThumbnail(
getContentResolver(), selectedImageUri,
MediaStore.Images.Thumbnails.MINI_KIND,
null );
if( cursor != null && cursor.getCount() > 0 ) {
cursor.moveToFirst();//**EDIT**
String uri = cursor.getString( cursor.getColumnIndex( MediaStore.Images.Thumbnails.DATA ) );
}
Reference of this answer is taken from [here][1]
[1]: http://stackoverflow.com/questions/5548645/get-thumbnail-uri-path-of-the-image-stored-in-sd-card-android

Related

In 4.4 Camera activity returns null

When i run this application on android 4.2, bitmap returns image, but in 4.4 it returns null........ In Gallery things works perfectly.
if (items[which].equals("Camera")) {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1);
In onActivityResult
else if (requestCode == 1) {
final Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
if (imageNumber == 1)
slip_image1.setImageBitmap(thumbnail);
else if (imageNumber == 2)
slip_image2.setImageBitmap(thumbnail);
else if (imageNumber == 3)
slip_image3.setImageBitmap(thumbnail);
#SuppressLint("NewApi")
public static String getRealPathFromURI_API19(Context context, Uri uri){
String filePath = "";
try { // FIXME NPE error when select image from QuickPic, Dropbox etc
String wholeID = DocumentsContract.getDocumentId(uri);
// Split at colon, use second item in the array
String id = wholeID.split(":")[1];
String[] column = {MediaStore.Images.Media.DATA};
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
column, sel, new String[]{id}, null);
int columnIndex = cursor.getColumnIndex(column[0]);
if (cursor.moveToFirst()) {
filePath = cursor.getString(columnIndex);
}
cursor.close();
return filePath;
} catch (Exception e) { // this is the fix lol
String result;
Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
if (cursor == null) { // Source is Dropbox or other similar local file path
result = uri.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
}
#SuppressLint("NewApi")
public static String getRealPathFromURI_API11to18(Context context, Uri contentUri) {
String[] proj = { MediaStore.Images.Media.DATA };
String result = null;
CursorLoader cursorLoader = new CursorLoader(
context,
contentUri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
if(cursor != null){
int column_index =
cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
result = cursor.getString(column_index);
}
return result;
}
public static String getRealPathFromURI_BelowAPI11(Context context, Uri contentUri){
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
int column_index
= cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}

capturing image cursor returns null in android

In application I am using cursorloader to get captures image file path, it always returns null:
Uri file path = file:///storage/emulated/0/Pictures/BBI_Images/BBI_ORIG_20150313_112912.jpg
public static int getRotation(Context context, Uri selectedImage, String filePath) {
try{
String[] projection = { MediaStore.Images.Media.DATE };
CursorLoader loader = new CursorLoader(context, selectedImage, projection, null, null, null);
Cursor cursor = loader.loadInBackground();//here i can get only null
cursor.moveToFirst();
int column_index_data = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
int rotation = 0;
String realPath = cursor.getString(column_index_data);
if (realPath != null) {
rotation = getRotationForImage(realPath);
}
return rotation;
}catch(Exception e){
e.printStackTrace();
}
return 0;
}

Android, media scan doesn't generate thumbnails?

I have image files which don't have thumbnails. (imported from my external carmera using NFC)
I want to create thumbnails for my image picker view. (has to be fast)
At this moment, I'm not even sure "MEDIA SCAN" means "generating thumbnail" or what.
I tried to scan file using mMediaScannerConnection.scanFile(mPath, null);
onScanCompleted gets called and I try to get thumbnail using the following two version of functions.
I get null thumbnailPath for both functions, I don't get why..
private String getThumbnailPath(long imageId) {
ContentResolver cr = this.mContext.getContentResolver();
Cursor c = MediaStore.Images.Thumbnails.queryMiniThumbnail(cr, imageId, MediaStore.Images.Thumbnails.MINI_KIND, null);
try {
if (c.moveToNext()) {
int dataId = c.getColumnIndex( Images.Thumbnails.DATA);
String strThumPath = c.getString(dataId);
Log.i("ScanTest", "strThumPath = " + strThumPath );
return strThumPath;
}
} finally {
if (c != null) c.close();
}
return null;
}
private String getThumbnailPath2( long imageId ){
// http://wikicloud.blogspot.kr/2010/10/scanfile.html
ContentResolver cr = this.mContext.getContentResolver();
Cursor c = cr.query(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Thumbnails.IMAGE_ID + "= ?" , new String[]{String.valueOf(imageId)}, null);
try {
if (c.moveToNext()) {
int dataId = c.getColumnIndex( Images.Thumbnails.DATA);
String strThumPath = c.getString(dataId);
Log.i("ScanTest", "strThumPath = " + strThumPath );
return strThumPath;
}
} finally {
if (c != null) c.close();
}
return null;
}
-- edit --
Here's how I try to get thumbnails.
first create a mapping from image-id to thumbnail-path.
protected Map getThumbnailPathFromDB() {
Map result = new HashMap();
Cursor thumbCursor = null;
thumbCursor = getContentResolver().query(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
null,
null,
null, null);
if (thumbCursor.moveToFirst()) {
do {
String path = thumbCursor.getString(thumbCursor
.getColumnIndex(MediaStore.MediaColumns.DATA));
long imageId = thumbCursor.getLong(thumbCursor
.getColumnIndex(MediaStore.Images.Thumbnails.IMAGE_ID));
result.put(new Long(imageId), path);
} while(thumbCursor.moveToNext());
}
thumbCursor.close();
return result;
next I iterate all images and try to find thumbnails from the mapping I created above
ContentResolver cr = getContentResolver();
Cursor cursor = cr.query(
Images.Media.EXTERNAL_CONTENT_URI, null,
null, null, Images.ImageColumns.DATE_MODIFIED + " DESC");
//thumbnailPathList is the mapping I created above, imageId is the id of image obtained from the cursor
String thumbnailPath = thumbnailPathList.get(new Long(imageId));
// thumbnailPath are occasionally null here!,
I tested my code on about 10 devices.
They all have images which I can't find thumbnails for.

Android - Get gallery images Samsung S4/S5

I'm working on a custom image gallery for my application but I got a serious issue under Samsung Galaxy S4 and S5. The following code works great on HTC and Xperia devices but not at all on Samsung ones.
Basically, the pathes are always null on these devices.
Here is the code I made.
In big lines, it returns a list of categories containing a name and a list of images. The aim is to provide a folder based gallery like the native one.
Should you have any idea why it fails on Samsung galaxy ?
Thanks for your help.
public List<Category> getCategories()
{
Map<String, Category> map = new HashMap<String, Category>();
String[] projection = new String[] {
MediaStore.Images.Media._ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
};
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, MediaStore.Images.Media.DATE_TAKEN + " DESC");
if (cursor == null) return;
if (cur.moveToFirst())
{
Category category = null;
long id = 0L;
String bucket = null;;
int idColumn = cur.getColumnIndex(MediaStore.Images.Media._ID);
int bucketColumn = cur.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
do
{
id = cur.getLong(idColumn);
bucket = cur.getString(bucketColumn);
if (map.get(bucket) == null)
{
category = new Category(bucket);
map.put(bucket, category);
}
category = map.get(bucket);
category.addImage( idToImage(id) );
}
while (cur.moveToNext());
}
return map.values().toArray();
}
private Image idToImage(long id)
{
Image image = new Image();
image.setThumbnail( getThumbnail(id) );
image.setImage( getImage(id) );
return image;
}
private String getThumbnail(long id)
{
String path = null;
Cursor cursor = MediaStore.Images.Thumbnails.queryMiniThumbnail(getContentResolver(), id, MediaStore.Images.Thumbnails.MINI_KIND, null);
if( cursor != null && cursor.getCount() > 0 )
{
cursor.moveToFirst();
path = cursor.getString( cursor.getColumnIndex( MediaStore.Images.Thumbnails.DATA ) );
cursor.close();
}
return path;
}
private String getImage(long id)
{
String path = null;
String[] projection = {MediaStore.Images.Media.DATA};
String where = MediaStore.Images.Media._ID + " = " + id;
Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, where, null, null);
int dataColumn = cursor.getColumnIndex(MediaStore.Images.Media.DATA);
if( cursor != null && cursor.getCount() > 0 )
{
cursor.moveToFirst();
path = cursor.getString(dataColumn);
}
return path;
}
It will work
/**
* Get actual file path from gallery
*/
public String getPath(Uri uri, Context ctx) {
String[] projection = {MediaStore.Images.Media.DATA};
String result;
Cursor cursor = ctx.getContentResolver().query(uri, projection, null, null, null);
if (cursor == null) {
return null;
}
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
result = cursor.getString(column_index);
cursor.close();
return result;
}

Get thumbnail Uri/path of the image stored in sd card + android

SDK version - 1.6
I am using following intent to open android's default gallery:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, "Select Picture"), 101);
Now in onActivityResult, i am able to get the original Uri and path of the selected image, but i am not able to get the Uri and path of the thumbnail of selected image.
Code for getting the original image Uri and path:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
if (requestCode == 101 && data != null) {
Uri selectedImageUri = data.getData();
String selectedImagePath = getPath(selectedImageUri);
} else {
Toast toast = Toast.makeText(this, "No Image is selected.",
Toast.LENGTH_LONG);
toast.show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
PS: 1) i am not looking to resize image like this question. I am specifically looking for the thumbnails which are generated by android OS itself.
2) Using SDK version 1.6 so not interested in ThumbnailUtils class.
You can use this to get the thumbnail:
Bitmap bitmap = MediaStore.Images.Thumbnails.getThumbnail(
getContentResolver(), selectedImageUri,
MediaStore.Images.Thumbnails.MINI_KIND,
(BitmapFactory.Options) null );
There are two types of thumbnails available:
MINI_KIND: 512 x 384 thumbnailMICRO_KIND: 96 x 96 thumbnail
OR use [queryMiniThumbnails][1] with almost same parameters to get the path of the thumbnail.
EDIT
Cursor cursor = MediaStore.Images.Thumbnails.queryMiniThumbnails(
getContentResolver(), selectedImageUri,
MediaStore.Images.Thumbnails.MINI_KIND,
null );
if( cursor != null && cursor.getCount() > 0 ) {
cursor.moveToFirst();//**EDIT**
String uri = cursor.getString( cursor.getColumnIndex( MediaStore.Images.Thumbnails.DATA ) );
}
HTH !
[1]: https://developer.android.com/reference/android/provider/MediaStore.Images.Thumbnails.html#queryMiniThumbnails(android.content.ContentResolver, android.net.Uri, int, java.lang.String[])
This solution is work on me!
final int THUMBSIZE = 128;
Bitmap thumbImage = ThumbnailUtils.extractThumbnail(
BitmapFactory.decodeFile(file.getAbsolutePath()),
THUMBSIZE,
THUMBSIZE);
It could be a alternative ways as other had already mentioned in their answer but Easy way i found to get thumbnail is using ExifInterface
ExifInterface exif = new ExifInterface(pictureFile.getPath());
byte[] imageData=exif.getThumbnail();
Bitmap thumbnail= BitmapFactory.decodeByteArray(imageData,0,imageData.length);
Two variants without depricated methods.
public String getThumbnailPath(Uri uri) {
String[] proj = { MediaStore.Images.Media.DATA };
// This method was deprecated in API level 11
// Cursor cursor = managedQuery(contentUri, proj, null, null, null);
CursorLoader cursorLoader = new CursorLoader(activity, uri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
cursor.moveToFirst();
long imageId = cursor.getLong(column_index);
//cursor.close();
String result="";
cursor = MediaStore.Images.Thumbnails.queryMiniThumbnail(activity.getContentResolver(), imageId,
MediaStore.Images.Thumbnails.MINI_KIND, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
result = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));
cursor.close();
}
return result;
}
public Bitmap getThumbnailBitmap(Uri uri){
String[] proj = { MediaStore.Images.Media.DATA };
// This method was deprecated in API level 11
// Cursor cursor = managedQuery(contentUri, proj, null, null, null);
CursorLoader cursorLoader = new CursorLoader(activity, uri, proj, null, null, null);
Cursor cursor = cursorLoader.loadInBackground();
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
cursor.moveToFirst();
long imageId = cursor.getLong(column_index);
//cursor.close();
Bitmap bitmap = MediaStore.Images.Thumbnails.getThumbnail(
getContentResolver(), imageId,
MediaStore.Images.Thumbnails.MINI_KIND,
(BitmapFactory.Options) null );
return bitmap;
}
Based on #Karan's answer and following comments, just for the people that arrive here (like I did) and need a ready-to-work code:
public String getThumbnailPath(Uri uri) {
String[] projection = { MediaStore.Images.Media._ID };
String result = null;
Cursor cursor = managedQuery(uri, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
cursor.moveToFirst();
long imageId = cursor.getLong(column_index);
cursor.close();
cursor = MediaStore.Images.Thumbnails.queryMiniThumbnail(
getContentResolver(), imageId,
MediaStore.Images.Thumbnails.MINI_KIND,
null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
result = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));
cursor.close();
}
return result;
}
public static String getThumbnailPath(Context context, String path)
{
long imageId = -1;
String[] projection = new String[] { MediaStore.MediaColumns._ID };
String selection = MediaStore.MediaColumns.DATA + "=?";
String[] selectionArgs = new String[] { path };
Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst())
{
imageId = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
cursor.close();
}
String result = null;
cursor = MediaStore.Images.Thumbnails.queryMiniThumbnail(context.getContentResolver(), imageId, MediaStore.Images.Thumbnails.MINI_KIND, null);
if (cursor != null && cursor.getCount() > 0)
{
cursor.moveToFirst();
result = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));
cursor.close();
}
return result;
}
Take a look at the following class
http://developer.android.com/reference/android/provider/MediaStore.Images.Thumbnails.html
The accepted answer is not working for me. I use following method to make it:
try{
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getActivity().getContentResolver(), uri);
Bitmap thumbBitmap = ThumbnailUtils.extractThumbnail(bitmap,120,120);
// imageView.setImageBitmap(thumbBitmap);
}
catch (IOException ex){
//......
}
The best Answer for getting Thumbnail and All Android Versions is this:
val thumbnail: Bitmap = if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)) {
mContentResolver.loadThumbnail(contentUri, Size.parseSize(""), null)
} else {
MediaStore.Images.Thumbnails.getThumbnail(mContentResolver, id, MediaStore.Images.Thumbnails.MINI_KIND, null)
}

Categories

Resources