I want to retrieve only the name of the bucket (Albums). E.g. Camera, Download etc but not a list of Camera, Download etc from all the the photos so how do I retrieve one ro
You can query MediaStore.Images.Media.BUCKET_DISPLAY_NAME for it. Peter Knego sent a good example. It's a good example and you can update it using query() from a ContentResolver object rather than managedQuery() that is deprecated.
// which image properties are we querying
String[] projection = new String[]{
MediaStore.Images.Media._ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.DATE_TAKEN
};
// Get the base URI for the People table in the Contacts content provider.
Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
// Make the query.
ContentResolver cr = getContentResolver();
Cursor cur = cr.query(images,
projection, // Which columns to return
"", // Which rows to return (all rows)
null, // Selection arguments (none)
"" // Ordering
);
Log.i("ListingImages"," query count="+cur.getCount());
if (cur.moveToFirst()) {
String bucket;
String date;
int bucketColumn = cur.getColumnIndex(
MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
int dateColumn = cur.getColumnIndex(
MediaStore.Images.Media.DATE_TAKEN);
do {
// Get the field values
bucket = cur.getString(bucketColumn);
date = cur.getString(dateColumn);
// Do something with the values.
Log.i("ListingImages", " bucket=" + bucket
+ " date_taken=" + date);
} while (cur.moveToNext());
}
I have the same problem and here is my solution (after tracing gallery source code) to get album name and the first image in it (can use as thumbnail for this album):
(Note that bucket repeat is removed by groupby & order technique)
// which image properties are we querying
String[] PROJECTION_BUCKET = {
ImageColumns.BUCKET_ID,
ImageColumns.BUCKET_DISPLAY_NAME,
ImageColumns.DATE_TAKEN,
ImageColumns.DATA};
// We want to order the albums by reverse chronological order. We abuse the
// "WHERE" parameter to insert a "GROUP BY" clause into the SQL statement.
// The template for "WHERE" parameter is like:
// SELECT ... FROM ... WHERE (%s)
// and we make it look like:
// SELECT ... FROM ... WHERE (1) GROUP BY 1,(2)
// The "(1)" means true. The "1,(2)" means the first two columns specified
// after SELECT. Note that because there is a ")" in the template, we use
// "(2" to match it.
String BUCKET_GROUP_BY =
"1) GROUP BY 1,(2";
String BUCKET_ORDER_BY = "MAX(datetaken) DESC";
// Get the base URI for the People table in the Contacts content provider.
Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Cursor cur = getContentResolver().query(
images, PROJECTION_BUCKET, BUCKET_GROUP_BY, null, BUCKET_ORDER_BY);
Log.i("ListingImages"," query count=" + cur.getCount());
if (cur.moveToFirst()) {
String bucket;
String date;
String data;
int bucketColumn = cur.getColumnIndex(
MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
int dateColumn = cur.getColumnIndex(
MediaStore.Images.Media.DATE_TAKEN);
int dataColumn = cur.getColumnIndex(
MediaStore.Images.Media.DATA);
do {
// Get the field values
bucket = cur.getString(bucketColumn);
date = cur.getString(dateColumn);
data = cur.getString(dataColumn);
// Do something with the values.
Log.i("ListingImages", " bucket=" + bucket
+ " date_taken=" + date
+ " _data=" + data);
} while (cur.moveToNext());
}
Here it is. it works for me:
Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
String[] projection = new String[]{
MediaStore.Images.Media.BUCKET_ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.DATE_TAKEN,
MediaStore.Images.Media.DATA
};
String BUCKET_ORDER_BY = MediaStore.Images.Media.DATE_MODIFIED + " DESC";
String BUCKET_GROUP_BY = "1) GROUP BY 1,(2";
Cursor imagecursor = managedQuery(images,
projection, // Which columns to return
BUCKET_GROUP_BY, // Which rows to return (all rows)
null, // Selection arguments (none)
BUCKET_ORDER_BY // Ordering
);
this.imageUrls = new ArrayList<String>();
this.imageBuckets = new ArrayList<String>();
for (int i = 0; i < imagecursor.getCount(); i++)
{
imagecursor.moveToPosition(i);
int bucketColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
String bucketDisplayName = imagecursor.getString(bucketColumnIndex);
imageBuckets.add(bucketDisplayName);
int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.DATA);
imageUrls.add(imagecursor.getString(dataColumnIndex));
}
imageBuckets Arraylist is containing album names
imageUrls Arraylist is containing path of last modifided image of album you can use it as thumbnail
Do projection in query as below:
String bucketProjection[] = {"Distinct "+ MediaStore.Images.Media.BUCKET_DISPLAY_NAME};
Use following function to get albums of Video or Images :
/*
*
* Author : @nieldeokar
* mediaType could be one of
*
* public static final int MEDIA_TYPE_IMAGE = 1;
*
* public static final int MEDIA_TYPE_VIDEO = 3;
*
* from android.provider.MediaStore class
*
*/
fun getAlbumList(mediaType: Int, contentResolver: ContentResolver) {
val countColumnName = "count"
var contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
if (mediaType == MEDIA_TYPE_VIDEO) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
}
val projection = arrayOf(ImageColumns.BUCKET_ID, ImageColumns.BUCKET_DISPLAY_NAME, ImageColumns.DATE_TAKEN, ImageColumns.DATA)
val bucketGroupBy = "1) GROUP BY ${ImageColumns.BUCKET_ID}, (${ImageColumns.BUCKET_DISPLAY_NAME}"
val bucketOrderBy = MediaStore.Images.Media.DATE_MODIFIED + " DESC"
val cursor = contentResolver.query(contentUri, projection, bucketGroupBy, null, bucketOrderBy)
if (cursor != null) {
while (cursor.moveToNext()) {
val bucketId = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.BUCKET_ID))
val name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME))
val path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA)) // Thumb image path
val selection = MediaStore.Images.Media.BUCKET_ID + "='" + bucketId + "'"
val countCursor = contentResolver.query(contentUri, arrayOf( "count(" + MediaStore.Images.ImageColumns._ID + ")"), selection, null, null)
var count = 0
if (countCursor != null) {
countCursor.moveToFirst()
count = countCursor.getInt(0)
countCursor.close()
}
Log.d("AlbumScanner", "bucketId : $bucketId | name : $name | count : $count | path : $path")
}
cursor.close()
}
}
This forms a SQL Statement as :
SELECT bucket_id, bucket_display_name, datetaken, _data FROM images WHERE (1) GROUP BY bucket_id,(bucket_display_name) ORDER BY date_modified DESC
UPDATE : As @PerracoLabs pointed out, This code needs to be improved for targeting Android Q.