获取Android上的照片库列表

ima*_*747 44 android image gallery mediastore

我正在寻找:现有照片库名称的列表(希望它们的顶部缩略图)画廊的内容(我可以根据需要加载缩略图和完整大小)

我如何获得"画廊"列表(不知道这是否是Android中适用于Gallery应用程序中可见图像分组的正确术语...)及其内容?我需要访问其结构中的图库,而不使用现有的图库显示(我正在创建一个全新的,而不是照片请求者的过度层等)

我认为MediaStore.Images是我需要的地方,但我没有看到任何会给我分组的东西......

Pet*_*ego 78

分组由MediaStore.Images.Media.BUCKET_DISPLAY_NAME.定义.以下是列出图像并记录其存储桶名称和date_taken的示例代码:

// 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
};

// content:// style URI for the "primary" external storage volume
Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

// Make the query.
Cursor cur = managedQuery(images,
        projection, // Which columns to return
        null,       // Which rows to return (all rows)
        null,       // Selection arguments (none)
        null        // 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());

}
Run Code Online (Sandbox Code Playgroud)

  • 不推荐使用managedQuery,请使用context.getContentResolver().query,请参阅:http://stackoverflow.com/a/12714830/3324388 (3认同)
  • >= android.os.Build.VERSION_CODES.Q (这是一个悲伤的故事!) (2认同)

小智 36

/**
 * Getting All Images Path
 * 
 * @param activity
 * @return ArrayList with images Path
 */
public static ArrayList<String> getAllShownImagesPath(Activity activity) {
    Uri uri;
    Cursor cursor;
    int column_index_data, column_index_folder_name;
    ArrayList<String> listOfAllImages = new ArrayList<String>();
    String absolutePathOfImage = null;
    uri = android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

    String[] projection = { MediaColumns.DATA,
            MediaStore.Images.Media.BUCKET_DISPLAY_NAME };

    cursor = activity.getContentResolver().query(uri, projection, null,
            null, null);

    column_index_data = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
    column_index_folder_name = cursor
            .getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
    while (cursor.moveToNext()) {
        absolutePathOfImage = cursor.getString(column_index_data);

        listOfAllImages.add(absolutePathOfImage);
    }
    return listOfAllImages;
}
Run Code Online (Sandbox Code Playgroud)

  • 不要忘记在您的清单中添加<uses-permission android:name ="android.permission.READ_EXTERNAL_STORAGE"/>. (13认同)

Bar*_*uda 19

以下是几个简单步骤的完整解决方案:

接下来的几个步骤将指导您如何创建一个Vector将保存在给定设备上找到的相册.每张专辑都会保留一张预览图像以及一张Vector可以容纳相册所有图像的内部图像.

  1. 创建一个对象,该对象将从存储中提取图像.我们打算叫它PhoneAlbum.这就是它的样子:

    public class PhoneAlbum {
    
        private int id;
        private String name;
        private String coverUri;
        private Vector<PhonePhoto> albumPhotos;
    
        public int getId() {
            return id;
        }
    
        public void setId( int id ) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName( String name ) {
            this.name = name;
        }
    
        public String getCoverUri() {
            return coverUri;
        }
    
        public void setCoverUri( String albumCoverUri ) {
            this.coverUri = albumCoverUri;
        }
    
        public Vector< PhonePhoto > getAlbumPhotos() {
            if ( albumPhotos == null ) {
                albumPhotos = new Vector<>();
            }
            return albumPhotos;
        }
    
        public void setAlbumPhotos( Vector< PhonePhoto > albumPhotos ) {
            this.albumPhotos = albumPhotos;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 创建一个对象,用于保存相册中的图像: PhonePhoto

    public class PhonePhoto {
    
        private int id;
        private String albumName;
        private String photoUri;
    
        public int getId() {
            return id;
        }
    
        public void setId( int id ) {
            this.id = id;
        }
    
        public String getAlbumName() {
            return albumName;
        }
    
        public void setAlbumName( String name ) {
            this.albumName = name;
        }
    
        public String getPhotoUri() {
            return photoUri;
        }
    
        public void setPhotoUri( String photoUri ) {
            this.photoUri = photoUri;
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 创建一个接口,以在完成时处理提取的图像.我们打算叫它OnPhoneImagesObtained.这里是:

    public interface OnPhoneImagesObtained {
    
        void onComplete( Vector<PhoneAlbum> albums );
        void onError();
    
    }
    
    Run Code Online (Sandbox Code Playgroud)
  4. 创建一个新类: DeviceImageManager

    public class DeviceImageManager {
    
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 创建后DeviceImageManager,添加以下方法:

    public static void getPhoneAlbums( Context context , OnPhoneImagesObtained listener ){
        // Creating vectors to hold the final albums objects and albums names
        Vector< PhoneAlbum > phoneAlbums = new Vector<>();
        Vector< String > albumsNames = new Vector<>();
    
        // which image properties are we querying
        String[] projection = new String[] {
                MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
                MediaStore.Images.Media.DATA,
                MediaStore.Images.Media._ID
        };
    
        // content: style URI for the "primary" external storage volume
        Uri images = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    
        // Make the query.
        Cursor cur = context.getContentResolver().query(images,
                projection, // Which columns to return
                null,       // Which rows to return (all rows)
                null,       // Selection arguments (none)
                null        // Ordering
        );
    
        if ( cur != null && cur.getCount() > 0 ) {
            Log.i("DeviceImageManager"," query count=" + cur.getCount());
    
            if (cur.moveToFirst()) {
                String bucketName;
                String data;
                String imageId;
                int bucketNameColumn = cur.getColumnIndex(
                    MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
    
                int imageUriColumn = cur.getColumnIndex(
                    MediaStore.Images.Media.DATA);
    
                int imageIdColumn = cur.getColumnIndex(
                    MediaStore.Images.Media._ID );
    
                do {
                    // Get the field values
                    bucketName = cur.getString( bucketNameColumn );
                    data = cur.getString( imageUriColumn );
                    imageId = cur.getString( imageIdColumn );
    
                    // Adding a new PhonePhoto object to phonePhotos vector
                    PhonePhoto phonePhoto = new PhonePhoto();
                    phonePhoto.setAlbumName( bucketName );
                    phonePhoto.setPhotoUri( data );
                    phonePhoto.setId( Integer.valueOf( imageId ) );
    
                    if ( albumsNames.contains( bucketName ) ) {
                        for ( PhoneAlbum album : phoneAlbums ) {
                            if ( album.getName().equals( bucketName ) ) {
                                album.getAlbumPhotos().add( phonePhoto );
                                Log.i( "DeviceImageManager", "A photo was added to album => " + bucketName );
                                break;
                            }
                        }
                    } else {
                        PhoneAlbum album = new PhoneAlbum();
                        Log.i( "DeviceImageManager", "A new album was created => " + bucketName );
                        album.setId( phonePhoto.getId() );
                        album.setName( bucketName );
                        album.setCoverUri( phonePhoto.getPhotoUri() );
                        album.getAlbumPhotos().add( phonePhoto );
                        Log.i( "DeviceImageManager", "A photo was added to album => " + bucketName );
    
                        phoneAlbums.add( album );
                        albumsNames.add( bucketName );
                    }
    
                } while (cur.moveToNext());
            }
    
            cur.close();
            listener.onComplete( phoneAlbums );
        } else {
            listener.onError();
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  6. 现在你剩下的就是将图像渲染到屏幕上.在我的情况下,我喜欢使用Picasso.我是这样做的:

        Picasso.with( getActivity() )
                    .load( "file:" + mPhoneAlbums.get( i ).getCoverUri() )
                    .centerCrop()
                    .fit()
                    .placeholder( R.drawable.temp_image )
                    .into( mAlbumPreview );
    
    Run Code Online (Sandbox Code Playgroud)
  7. 不要忘记在清单中添加读取外部存储的权限:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    
    Run Code Online (Sandbox Code Playgroud)

而已.你已准备好出发!祝好运!


小智 5

我找到了一种无需遍历每张照片即可获取相册的方法。

 String[] projection = new String[]{
                "COUNT(*) as count",
                MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
                MediaStore.Images.ImageColumns.DATA,
                "MAX (" + MediaStore.Images.ImageColumns.DATE_TAKEN + ") as max"};

 Context context = ServiceProvider.getInstance().getApplicationContext();
 Cursor cursor = context.getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection,
                "1) GROUP BY (" + MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
                null,
                "max DESC");
Run Code Online (Sandbox Code Playgroud)

光标将包含尽可能多的元素,因为存在不同的存储桶名称,并且您还可以在每个光标位置内获取计数以获取相册内的图像计数

这里的例子:

if (cursor != null) {
            if (cursor.moveToFirst()) {
                do {
                //gets image path, it will always be a latest image because of sortOrdering by MAX date_taken
                String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
                //gets count via alias ("as count" in projection)
                int count = cursor.getInt(cursor.getColumnIndex("count"));

                //do you logic here
                ...

                } while (cursor.moveToNext());
            }

            cursor.close();
        }
Run Code Online (Sandbox Code Playgroud)

关于选择参数的一些解释:

contentResolver 在为 sqlLite 编译结果查询时添加括号,所以如果我们选择像

“GROUP BY” + MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME

它将被编译为“WHERE (GROUP BY bucket_display_name)”并在运行时导致 SQLiteException。否则,如果我们做出选择

"1) GROUP BY (" + MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME

它将被编译为“WHERE (1) GROUP BY (bucket_display_name)”,这是正确的