Obtaining thumbnails for images in android using ContentResolver and Cursor - android

The following is my code for obtaining a thumbnail of a given image.
As of now, the exception that I'm getting is 'Cursor out of bounds'
I think that may be because I am not appending the image URL anywhere. I'm a little confused as to where to do that.
So 2 questions:
1. Where do I use the image URL of which I want to obtain a thumbnail
2. The for loop which is supposed to print column names prints nothing except the first statement 'COLUMN NAMES'
//get the corresponding thumbnail
String lastImageTakenPath = MyActivity.this.savedInstanceStateVariable.getString("lastImageTaken");
System.out.println("previous image is "+ lastImageTakenPath);
ContentResolver cr = getContentResolver();
if(cr != null){
String[] projection = { MediaStore.Images.Media._ID };
Cursor cursor = managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,projection,null,null,null);
//Cursor cursor = cr.query(lastImageTakenURI, null, null, null, null);
//Activity.startManagingCursor(cursor);
if(cursor != null){
String[] columnNames = cursor.getColumnNames();
System.out.println("COLUMN NAMES");
for(int i=0;i<columnNames.length; i++){
System.out.println(columnNames[i]);
}
/* 1. get the id of the image
* 2. use this id in the call, getThumbnails on MediaStore.Images.Thumbnails to obtain the
thumbnail
3.set the imageview's src to this thumbnail */
int imageID = cursor.getInt( cursor.getColumnIndex(MediaStore.Images.Media._ID) );
Uri uri = Uri.withAppendedPath( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, Integer.toString(imageID) );
// Get original image ID
String url = uri.toString();
int originalImageId = Integer.parseInt(url.substring(url.lastIndexOf("/") + 1, url.length()));
// Get (or create upon demand) the micro thumbnail for the original image.
thumbnailLastImage = MediaStore.Images.Thumbnails.getThumbnail(cr, originalImageId, MediaStore.Images.Thumbnails.MICRO_KIND,null);
thumbnailImage.setImageBitmap(thumbnailLastImage);
}
else{
System.out.println("Cursor is NULL");
}
}
else{
Log.d(TAG,"ContentResolver is NULL");
}

I believe your test of if(cursor != null) is incorrect or at least insufficient. If the result of the query returns no thumbnails then you will still get a cursor where cursor.getCount() == 0 you may want to use that as your test.

Related

can i get a photo directlly from calllog.calls provider

i want to get a contact photo (if he has one) from the callLog.
now i know i can get the number and then query the contacts provider for a contact id.
however i want to know if there is a better way one that directly get the photo uri from the callLog.calls table.
what makes me believe it might be possible is the fact that inside the documentation i ran across 2 interesting fields:
1)CACHED_LOOKUP_URI -The cached URI to look up the contact associated with the phone number, if it exists.
2)CACHED_PHOTO_ID - The cached photo id of the picture associated with the phone number, if it exists.
now if it can be done how, and if it cant be done than i would like to know what those fields are used for,
thx
You can get its ID. Then you have to retrieve the actual image from ContactsContract.
imageDataRow = c.getInt(c.getColumnIndex(CallLog.Calls.CACHED_PHOTO_ID));
Cursor c = mContext.getContentResolver().query(ContactsContract.Data.CONTENT_URI, new String[]{
ContactsContract.CommonDataKinds.Photo.PHOTO
}, ContactsContract.Data._ID + "=?", new String[]{
Integer.toString(imageDataRow)
}, null);
byte[] imageBytes = null;
if (c != null) {
if (c.moveToFirst()) {
imageBytes = c.getBlob(0);
}
c.close();
}
Bitmap photo = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
Mostly, I have used Glide to set an image on view.
SDK>=23
c.getString(c.getColumnIndex(CallLog.Calls.CACHED_PHOTO_URI));
SDK<23
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(num));
Cursor cursor = getContext().getContentResolver().query(uri, null, null, null, null);
if (cursor != null && cursor.moveToNext()) {
image_uri = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.PHOTO_URI));
//Log.d(TAG, "image_uri "+image_uri);
}
if(cursor !=null)
cursor.close();

Media Gallery ContentProvider

My app will display the complete list of images in my custom gallery .For this, I'm using ContentProvider of Image Thumbnails. Upon selecting the thumbnail's I need to display the actual image.According to my understanding Gallery's image do have same unique ID in Thumb and Media Table.
Here is the code. Firstly I queried Thumbnail's ContentProvider and saved URL and ID.
String pictureThumbTemp[] = { MediaStore.Images.Thumbnails._ID, MediaStore.Images.Thumbnails.DATA };
Cursor imagecursor = context.getContentResolver().query (MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
pictureThumbTemp,null, null, null);
Later I am displaying thumbs in Grid.
Upon selection of thumbnail, I have to display original image. I'm trying to retrieve the original image like
String pictureImageTemp[] = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA };
Cursor imagecursor = context.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
pictureImageTemp, MediaStore.Images.Media._ID + " = " + mediaID + "", null,
MediaStore.Images.Media._ID);
Overall, I'm showing thumbnail through it's url and upon click I'm querying the thumbnail's media ID in Original image table.
But it is returning a cursor with 0 results.
Please help me out.
Thanks,
sha.
I cracked out a way which worked out.
Retrieved the cursor for Original Images.
From that I pulled the ID for every image and Queried the Thumbnails for the ID which returns a cursor containing paths.
Find the code snippet below.
String pictureCols[] = { MediaStore.Images.Media._ID, MediaStore.Images.Media.DATA };
Cursor imagecursor = mContext.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, pictureCols,
null, null, null);
imagecursor.moveToFirst();
mImageUrls = new ArrayList<String>();
try {
// Iterate the cursor for Image urls
for (int index = 0; index < imagecursor.getCount(); index++) {
imagecursor.moveToPosition(index);
preparePicture(imagecursor);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
imagecursor.close();
}
}
Here is the code for preparePicture method
private void preparePicture(Cursor imageCursor) {
// get the ID for the original image
int idColumnIndex = imageCursor.getColumnIndex(mSelectedImage.mediaID);
Long id = imageCursor.getLong(idColumnIndex);
// Thumbnail image Cursor for this specific image.
String thumbCols[] = { MediaStore.Images.Thumbnails._ID, MediaStore.Images.Thumbnails.DATA };
Cursor thumbCursor = MediaStore.Images.Thumbnails.queryMiniThumbnail(mContext.getContentResolver(), id,
Thumbnails.MINI_KIND, thumbCols);
thumbCursor.moveToFirst();
// Save thumbnail URL in MediaInfo
dataColumnIndex = thumbCursor.getColumnIndex(mSelectedThumb.data);
String thumbURL = thumbCursor.getString(dataColumnIndex);
thumbCursor.close();
mImageUrls.add(url);
}
Finally, I will have all my Thumbnail urls in the ArrayList.
The same logic is not working for video thumbnails. Of course that is a different question :)
Regards,
Sha.
try this one
final String[] pictureImageTemp= { MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID };
Cursor imagecursor = managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, pictureImageTemp, null,
null, MediaStore.Images.Media._ID);

How to get imagepath from thumbnail path of a image?

I am trying to get imagepath based on thumbail path , i have already tried solution from
android-getting-path-to-image-from-thumbnail, but it is based on gridview position, i am only retrieving specific images. Also i found one sample code from SO, the code is
private String getImagePathFromThumbPath(String thumbPath)
{
String imgPath=null;
// String[] projection = new String[] {MediaStore.Images.Thumbnails._ID, MediaStore.Images.Thumbnails.IMAGE_ID};
String[] imagesDataPath={ MediaStore.Images.Media.DATA ,MediaStore.Images.Media._ID};
//mResolver.query() requires android API 16
Cursor thumbnails = mResolver.query(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, imagesDataPath,MediaStore.Images.Thumbnails.DATA+"=?",new String[]{thumbPath}, null, null);
String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor imageCursor = mResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, filePathColumn, MediaStore.Images.Media._ID + "=?", new String[] {thumbId}, null);
if (imageCursor != null && imageCursor.moveToFirst()) {
// Your file-path will be here
imgPath= imageCursor.getString(imageCursor.getColumnIndex(filePathColumn[0]));
}
return imgPath;
}
The above method is bit modified to suit my needs and it returns nothing on Toasting, please tell how to retrieve imagepath using thumbnail path?
After a long time and relentless try, the solution is here
1. You need to find the image id which is image unique id from images table in thumbnail table, query to thumbnail provider (MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI) if you do not understand it, refer here , specifically IMAGE_ID,
Step 1 is to get retrievedImageId.
retrievedImageId = Long.parseLong(cursor.getString(imageIdInImages));
2. Now using the retrievedImageId get the image path, by again querying the content provider, only this time query the Images media provider (MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
String getImagePathFromThumbPath(String thumbPath)
{
String imagePath = null;
if(thumbPath != null )
{
String[] columns_to_return = {MediaStore.Images.Thumbnails.IMAGE_ID};
String where = MediaStore.Images.Thumbnails.DATA+" LIKE ?";
long retrievedImageId = -1;
String valuesAre[] = {"%"+thumbPath};
Cursor cursor = getContentResolver().query(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, columns_to_return, where, valuesAre, null);
if(cursor != null)
{
int imageIdInImages = cursor.getColumnIndex(MediaStore.Images.Thumbnails.IMAGE_ID);
for (cursor.moveToFirst();!cursor.isAfterLast(); cursor.moveToNext())
{
//STEP 1 to retrieve image ID
retrievedImageId = Long.parseLong(cursor.getString(imageIdInImages));
}
if(retrievedImageId != -1)
{
// STEP 2 Now
Log.i(TAG, "imageId-" + retrievedImageId);
String[] columnsReturn = {MediaStore.Images.Media.DATA};
String whereimageId = MediaStore.Images.Media._ID+" LIKE ?";
String valuesIs[] = {"%" + retrievedImageId};
Cursor mCursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columnsReturn, whereimageId, valuesIs, null);
int rawDataPath= mCursor.getColumnIndex(MediaStore.Images.Media.DATA);
for (mCursor.moveToFirst();!mCursor.isAfterLast(); mCursor.moveToNext())
{
imagePath = mCursor.getString(rawDataPath);
}
}
}
}
return imagePath;
}
If you still have doubt or error/exception, leave comment!

Android - MediaStore.Video.query() is returning null

I'm trying to retrieve the metadata from a video file (title, language, artist) using the method MediaStore.Video.query(). However, the method is always returning null. The code is bellow:
String[] columns = {
MediaStore.Video.VideoColumns._ID,
MediaStore.Video.VideoColumns.TITLE,
MediaStore.Video.VideoColumns.ARTIST
};
Cursor cursor = MediaStore.Video.query(getApplicationContext().getContentResolver(), videoUri,columns);
if (cursor != null) {
cursor.moveToNext();
}
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.TITLE));
Any suggestion about how to return video metadata using android?
==Update
As I searched in many places, I tried one solution using CursorLoader. However, the method loadInBackground() from CursorLoader is also returning null. The code is showed bellow:
String[] columns = {
MediaStore.Video.VideoColumns.TITLE
};
Uri videoUri = Uri.parse("content://mnt/sdcard/Movies/landscapes.mp4");
CursorLoader loader = new CursorLoader(getBaseContext(), videoUri, columns, null, null, null);
Cursor cursor = loader.loadInBackground();
cursor.moveToFirst();
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Video.VideoColumns.TITLE));
Uri.parse("content://mnt/sdcard/Movies/landscapes.mp4") is not an Uri for MediaStore. It would try to find a ContentProvider for authority mnt which does not exist.
MediaStore can handle only content://media/... Uris which you should get exclusively via MediaStore, not by using Uri.parse().
In your case use the following for example
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] columns = {
MediaStore.Video.VideoColumns._ID,
MediaStore.Video.VideoColumns.TITLE,
MediaStore.Video.VideoColumns.ARTIST
};
String selection = MediaStore.Video.VideoColumns.DATA + "=?";
String selectionArgs[] = { "/mnt/sdcard/Movies/landscapes.mp4" };
Cursor cursor = context.getContentResolver().query(uri, columns, selection, selectionArgs, null);
The MediaStore.Video.VideoColumns.DATA field holds the path to the videos and you search for a certain video this way. At least for now, future versions of Android may change that.
Your second example is using CursorLoader the wrong way. If you call loader.loadInBackground() yourself, you load the data in foreground. See e.g. http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/
The next thing you do is
Cursor cursor = getCursor();
cursor.moveToFirst();
String title = cursor.getString(/* some index */);
This will lead to a CursorIndexOutOfBoundsException if your cursor has 0 rows and cursor.moveToFirst() failed because there is no first row. The cursor stays before the first row (at -1) and that index does not exist. That would mean in your case that the file was not found in the database.
To prevent that use the return value of moveToFirst - it will only be true if there is a first row.
Cursor cursor = getCursor(); // from somewhere
if (cursor.moveToFirst()) {
String title = cursor.getString(/* some index */);
}
A more complete example including checks for null and closing the cursor in all cases
Cursor cursor = getCursor(); // from somewhere
String title = "not found";
if (cursor != null) {
if (cursor.moveToFirst()) {
title = cursor.getString(/* some index */);
}
cursor.close();
}
I guess the file you try to find is either not indexed in the database (rebooting forces the indexer to run again) or the path is wrong.
Or the path you use is actually a symlink in which case MediaStore might use a different path.
Use this to get rid of symlinks
String path = "/mnt/sdcard/Movies/landscapes.mp4";
try {
path = new File(path).getCanonicalPath();
} catch (IOException e) {
e.printStackTrace();
}
Yes, I tested now and it is throwing IndexOutOfBoundsException. When I'm using cursor.getColumnCount() it returns 1
cursor.getColumnCount() is the column count, not the row count. It should always be the same as the number of columns you requested in columns. You need to check cursor.getCount() if you want to check the row count.
Try dumping all the videos known to MediaStore into logcat in case it does not show as expected.
public static void dumpVideos(Context context) {
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaStore.Video.VideoColumns.DATA };
Cursor c = context.getContentResolver().query(uri, projection, null, null, null);
int vidsCount = 0;
if (c != null) {
vidsCount = c.getCount();
while (c.moveToNext()) {
Log.d("VIDEO", c.getString(0));
}
c.close();
}
Log.d("VIDEO", "Total count of videos: " + vidsCount);
}
I updated your code, it works, just check it
public static void dumpVideos(Context context) {
Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
String[] projection = { MediaStore.Video.VideoColumns.DATA };
Cursor c = context.getContentResolver().query(uri, projection, null, null, null);
int vidsCount = 0;
if (c != null) {
c.moveToFirst();
vidsCount = c.getCount();
do {
Log.d("VIDEO", c.getString(0));
}while (c.moveToNext());
c.close();
}
Log.d("VIDEO", "Total count of videos: " + vidsCount);
}

Getting contact photo

I am having a problem getting a contact photo, the kind you see in the messaging app and new gmail notification. I have looked at a few example codes but nothing has worked for me, this is what I currently have
this should get the photo uri and turn it into a bitmap image to use or at least it seems
public static Bitmap getContactImage(long id,Context context){
InputStream input = getPhoto(id,context);
if(input == null){
return null;
}
return BitmapFactory.decodeStream(input);
}
public static InputStream getPhoto(long contactId,Context context){
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, contactId);
Uri photoUri = Uri.withAppendedPath(contactUri, Contacts.Photo.CONTENT_DIRECTORY);
InputStream in = null;
try{
in = context.getContentResolver().openInputStream(photoUri);
}catch(FileNotFoundException e){
Log.d(TAG, e.toString());
}
return in;
}
and this is how I call
long contactID = 0;
Bitmap image = BitmapFactory.decodeResource(context.getResources(),R.drawable.ic_contact_picture);
Cursor contact = context.getContentResolver().query(Data.CONTENT_URI,new String[] {Data.CONTACT_ID},Email.ADDRESS + "='" + from + "'",null,null);
if(contact.moveToFirst() && contact != null){
contactID = contact.getLong(0);
image = getContactImage(contactID,context);
}
I get the contact id fine (checked by searching the number for the person querying against) but then it does not find the contact photo. I know there is a photo because I am testing it against myself to make sure and I have a contact photo so I dont know what else I should do.
I always find navigating the contact provider very troublesome because there is so much to it.
I got it, I did a query against the RAW_CONTACT_ID with the MIMETYPE and that gave me the photo I was looking for
Cursor p = context.getContentResolver().query(Data.CONTENT_URI,new String[] {Photo.PHOTO},
Data.RAW_CONTACT_ID + "=" + contactId + " AND " + Data.MIMETYPE + "='" + Photo.CONTENT_ITEM_TYPE+"'"
,null,null);
You're doing it wrong.
First, get an ID of the photo from the PHOTO_ID column of ContactsContract.Contacts table. Next, retrieve a byte array from PHOTO column (which is actually alias to DATA15) from ContactsContract.Data by ID you got in previous step. And, finally, decode that byte array using BitmapFactory to get a bitmap.
Here are docs about this.
This works for me.
//Querying for all contacts(Apply selection parameter in query to get a specific contact)
Uri contacts = ContactsContract.Contacts.CONTENT_URI;
cur = null;
cur = Main.context.getContentResolver().query(contacts, null, null,
null, null);
int contactIdIndex = cur.getColumnIndex(ContactsContract.PhoneLookup._ID);
int contactId = cur.getInt(contactIdIndex);
// Photo
Uri contactUri = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI, contactId);
Uri photoUri = Uri.withAppendedPath(contactUri,
ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
Cursor cursor = cr
.query(
photoUri,
new String[] { ContactsContract.CommonDataKinds.Photo.PHOTO },
null, null, null);
if (cursor != null && cursor.moveToFirst()) {
byte[] data = cursor.getBlob(0);
_conEntry.setPhoto(data);
//Data is the photo bytes for you
}
if (cursor != null)
cursor.close();

Categories

Resources