获取 Android 上的照片库列表

发布于 2024-10-03 06:39:42 字数 248 浏览 0 评论 0原文

我在找: 现有照片库名称的列表(希望也是它们的顶部缩略图) 图库的内容(然后我可以根据需要加载缩略图和全尺寸)

我将如何获取“图库”列表(不知道这是否是 android 中用于显示图像分组的正确术语)图库应用程序...)及其内容?我需要访问其结构中的画廊,而不使用现有的画廊显示(我正在创建一个全新的画廊,而不是照片请求者的覆盖层等)。

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

I'm looking for:
A list of the existing photo gallery names (hopefully their top thumbnail as well)
The contents of the gallery (I can then load thumbnails and full size as needed)

How would I go about getting a list of the "Galleries" (don't know if that's the proper term in android for the groupings of images visible in the Gallery app...) and their contents? I need access to the gallery in it's structure without using the existing gallery display (I'm creating a totally new one, not an over layer to the photo requestor etc.)

I assume MediaStore.Images is where I need to be but I don't see anything that will give me the groupings...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

梦里人 2024-10-10 06:39:42

分组由 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());

}

Groupings are defined by MediaStore.Images.Media.BUCKET_DISPLAY_NAME. Here is the sample code to list the images and log their bucket name and 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());

}
傲娇萝莉攻 2024-10-10 06:39:42
/**
 * 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;
}
/**
 * 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;
}
饮湿 2024-10-10 06:39:42

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

接下来的几个步骤将指导您如何创建一个 Vector 来保存在给定设备上找到的相册。每个相册都将包含一个预览图像以及一个用于保存相册所有图像的内部Vector

  1. 创建一个对象,用于保存从存储中提取的图像。我们将其命名为 PhoneAlbum。它将如下所示:

    公共类 PhoneAlbum {
    
        私有 int id;
        私有字符串名称;
        私有字符串 coverUri;
        私人矢量相册照片;
    
        公共 int getId() {
            返回ID;
        }
    
        公共无效setId(int id){
            这个.id = id;
        }
    
        公共字符串 getName() {
            返回名称;
        }
    
        公共无效setName(字符串名称){
            this.name = 名称;
        }
    
        公共字符串 getCoverUri() {
            返回封面Uri;
        }
    
        公共无效setCoverUri(字符串专辑CoverUri){
            this.coverUri = albumCoverUri;
        }
    
        公共矢量<手机照片>>获取相册照片() {
            if ( albumPhotos == null ) {
                albumPhotos = new Vector<>();
            }
            返回相册照片;
        }
    
        public void setAlbumPhotos( Vector albumPhotos ) {
            this.albumPhotos = albumPhotos;
        }
    }
    
  2. 创建一个对象,用于保存相册中的图像,名为:PhonePhoto

    公共类PhonePhoto {
    
        私有 int id;
        私有字符串专辑名称;
        私有字符串 photoUri;
    
        公共 int getId() {
            返回ID;
        }
    
        公共无效setId(int id){
            这个.id = id;
        }
    
        公共字符串 getAlbumName() {
            返回专辑名称;
        }
    
        公共无效setAlbumName(字符串名称){
            this.albumName = 名称;
        }
    
        公共字符串 getPhotoUri() {
            返回照片Uri;
        }
    
        公共无效setPhotoUri(字符串photoUri){
            this.photoUri = photoUri;
        }
    }
    
  3. 创建一个接口来处理完成后提取的图像。我们将其命名为 OnPhoneImagesObtained。这是:

    公共接口OnPhoneImagesObtained {
    
        void onComplete( Vector albums );
        无效 onError();
    
    }
    
  4. 创建一个新类:DeviceImageManager

    公共类DeviceImageManager {
    
    }
    
  5. 创建 DeviceImageManager 后,添加以下方法:

    public static void getPhoneAlbums( Context context , OnPhoneImagesObtained 侦听器 ){
        // 创建向量来保存最终的专辑对象和专辑名称
        向量<手机相册> phoneAlbums = new Vector<>();
        向量<字符串> albumsNames = new Vector<>();
    
        // 我们正在查询哪些图像属性
        字符串[]投影=新字符串[]{
                MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
                MediaStore.Images.Media.DATA,
                MediaStore.Images.Media._ID
        };
    
        // 内容:“主”外部存储卷的样式 URI
        Uri 图像 = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    
        // 进行查询。
        光标 cur = context.getContentResolver().query(images,
                projection, // 返回哪些列
                null, // 返回哪些行(所有行)
                null, // 选择参数(无)
                null // 排序
        );
    
        if ( cur != null && cur.getCount() > 0 ) {
            Log.i("DeviceImageManager","查询计数=" + cur.getCount());
    
            if (cur.moveToFirst()) {
                字符串存储桶名称;
                字符串数据;
                字符串图像ID;
                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 );
    
                做 {
                    // 获取字段值
                    BucketName = cur.getString(bucketNameColumn);
                    数据 = cur.getString( imageUriColumn );
                    imageId = cur.getString( imageIdColumn );
    
                    // 将新的 PhonePhoto 对象添加到phonePhotos向量中
                    PhonePhotophonePhoto = new PhonePhoto();
                    phonePhoto.setAlbumName(bucketName);
                    phonePhoto.setPhotoUri( 数据 );
                    phonePhoto.setId( Integer.valueOf( imageId ) );
    
                    if ( albumsNames.contains(bucketName ) ) {
                        for ( 电话相册相册 : 电话相册 ) {
                            if ( album.getName().equals(bucketName ) ) {
                                album.getAlbumPhotos().add(phonePhoto);
                                Log.i( "DeviceImageManager", "照片已添加至相册 => " + bucketName );
                                休息;
                            }
                        }
                    } 别的 {
                        PhoneAlbum 相册 = new PhoneAlbum();
                        Log.i( "DeviceImageManager", "新相册已创建 => " + bucketName );
                        album.setId(phonePhoto.getId());
                        album.setName(bucketName);
                        album.setCoverUri(phonePhoto.getPhotoUri());
                        album.getAlbumPhotos().add(phonePhoto);
                        Log.i( "DeviceImageManager", "照片已添加至相册 => " + bucketName );
    
                        phoneAlbums.add( 专辑 );
                        albumsNames.add(bucketName);
                    }
    
                while (cur.moveToNext());
            }
    
            cur.close();
            监听器.onComplete(phoneAlbums);
        } 别的 {
            监听器.onError();
        }
    }
    
  6. 现在剩下的就是将图像渲染到屏幕上。就我而言,我喜欢使用 Picasso。我是这样做的:

     Picasso.with( getActivity() )
                    .load( "文件:" + mPhoneAlbums.get( i ).getCoverUri() )
                    .centerCrop()
                    。合身()
                    .placeholder( R.drawable.temp_image )
                    .into(mAlbumPreview);
    
  7. 不要忘记在清单中添加读取外部存储的权限:

    ;
    

就是这样。你可以走了!
祝你好运!

Here is the full solution in few simple steps:

The next few steps will guid you how to create a Vector that will hold the albums found on a given device. Every Album will hold a preview image as well an inner Vector that will hold all the images of the Album.

  1. Create an object that will hold the images once extracted from storage. We are going to call it PhoneAlbum. This is how it's going to look:

    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;
        }
    }
    
  2. Create an object that will hold the images within the album called: 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;
        }
    }
    
  3. Create an interface to handle the extracted images upon completion. We are going to call it OnPhoneImagesObtained. Here it is:

    public interface OnPhoneImagesObtained {
    
        void onComplete( Vector<PhoneAlbum> albums );
        void onError();
    
    }
    
  4. Create a new class: DeviceImageManager

    public class DeviceImageManager {
    
    }
    
  5. Once you created DeviceImageManager, add the following method:

    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();
        }
    }
    
  6. Now all you have left is to render the images to screen. In my case I like to use Picasso. Here is how I do it:

        Picasso.with( getActivity() )
                    .load( "file:" + mPhoneAlbums.get( i ).getCoverUri() )
                    .centerCrop()
                    .fit()
                    .placeholder( R.drawable.temp_image )
                    .into( mAlbumPreview );
    
  7. Don't forget to add a permission to read external storage in your manifest:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    

That's it. You are good to go!
Good luck!

森罗 2024-10-10 06:39:42

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

 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");

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

示例:

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();
        }

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

contentResolver 在编译 sqlLite 的结果查询时添加括号,因此如果我们做出像

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

这样的选择,它将被编译为“WHERE(GROUP BYbucket_display_name)”并在运行时导致SQLiteException。否则,如果我们进行像

“1) GROUP BY (” + MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME

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

I've found a way to get albums without iterating over every photo.

 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");

cursor will contain as much elements, as distinct bucket name exists, and also you can get count inside every cursor position to get count of images inside album

here example:

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();
        }

Some explanation about selection param:

contentResolver adds parentheses when compiling resulting query for sqlLite, so if we make selection like

"GROUP BY " + MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME

it will be compiled as "WHERE (GROUP BY bucket_display_name)" and will cause SQLiteException at runtime. Otherwise if we make selection like

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

it will be compiled as "WHERE (1) GROUP BY (bucket_display_name)", which is correct

旧人 2024-10-10 06:39:42

从这里下载源代码(以编程方式从 Android 中的图库中获取所有图像

activity_main.xml

<RelativeLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    xmlns:android="http://schemas.android.com/apk/res/android">


    <GridView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/gv_folder"
        android:numColumns="2"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"></GridView>


</RelativeLayout>

MainActivity.java

package galleryimages.galleryimages;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    public static ArrayList<Model_images> al_images = new ArrayList<>();
    boolean boolean_folder;
    Adapter_PhotosFolder obj_adapter;
    GridView gv_folder;
    private static final int REQUEST_PERMISSIONS = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gv_folder = (GridView)findViewById(R.id.gv_folder);

        gv_folder.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Intent intent = new Intent(getApplicationContext(), PhotosActivity.class);
                intent.putExtra("value",i);
                startActivity(intent);
            }
        });


        if ((ContextCompat.checkSelfPermission(getApplicationContext(),
                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(getApplicationContext(),
                Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
            if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)) && (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                    Manifest.permission.READ_EXTERNAL_STORAGE))) {

            } else {
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
                        REQUEST_PERMISSIONS);
            }
        }else {
            Log.e("Else","Else");
            fn_imagespath();
        }



    }

    public ArrayList<Model_images> fn_imagespath() {
        al_images.clear();

        int int_position = 0;
        Uri uri;
        Cursor cursor;
        int column_index_data, column_index_folder_name;

        String absolutePathOfImage = null;
        uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

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

        final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
        cursor = getApplicationContext().getContentResolver().query(uri, projection, null, null, orderBy + " DESC");

        column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
        column_index_folder_name = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
        while (cursor.moveToNext()) {
            absolutePathOfImage = cursor.getString(column_index_data);
            Log.e("Column", absolutePathOfImage);
            Log.e("Folder", cursor.getString(column_index_folder_name));

            for (int i = 0; i < al_images.size(); i++) {
                if (al_images.get(i).getStr_folder().equals(cursor.getString(column_index_folder_name))) {
                    boolean_folder = true;
                    int_position = i;
                    break;
                } else {
                    boolean_folder = false;
                }
            }


            if (boolean_folder) {

                ArrayList<String> al_path = new ArrayList<>();
                al_path.addAll(al_images.get(int_position).getAl_imagepath());
                al_path.add(absolutePathOfImage);
                al_images.get(int_position).setAl_imagepath(al_path);

            } else {
                ArrayList<String> al_path = new ArrayList<>();
                al_path.add(absolutePathOfImage);
                Model_images obj_model = new Model_images();
                obj_model.setStr_folder(cursor.getString(column_index_folder_name));
                obj_model.setAl_imagepath(al_path);

                al_images.add(obj_model);


            }


        }


        for (int i = 0; i < al_images.size(); i++) {
            Log.e("FOLDER", al_images.get(i).getStr_folder());
            for (int j = 0; j < al_images.get(i).getAl_imagepath().size(); j++) {
                Log.e("FILE", al_images.get(i).getAl_imagepath().get(j));
            }
        }
        obj_adapter = new Adapter_PhotosFolder(getApplicationContext(),al_images);
        gv_folder.setAdapter(obj_adapter);
        return al_images;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case REQUEST_PERMISSIONS: {
                for (int i = 0; i < grantResults.length; i++) {
                    if (grantResults.length > 0 && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                        fn_imagespath();
                    } else {
                        Toast.makeText(MainActivity.this, "The app was not allowed to read or write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
                    }
                }
            }
        }
    }

}

Download the source code from here (Get all images from gallery in android programmatically)

activity_main.xml

<RelativeLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    xmlns:android="http://schemas.android.com/apk/res/android">


    <GridView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/gv_folder"
        android:numColumns="2"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"></GridView>


</RelativeLayout>

MainActivity.java

package galleryimages.galleryimages;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    public static ArrayList<Model_images> al_images = new ArrayList<>();
    boolean boolean_folder;
    Adapter_PhotosFolder obj_adapter;
    GridView gv_folder;
    private static final int REQUEST_PERMISSIONS = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        gv_folder = (GridView)findViewById(R.id.gv_folder);

        gv_folder.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Intent intent = new Intent(getApplicationContext(), PhotosActivity.class);
                intent.putExtra("value",i);
                startActivity(intent);
            }
        });


        if ((ContextCompat.checkSelfPermission(getApplicationContext(),
                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(getApplicationContext(),
                Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
            if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)) && (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                    Manifest.permission.READ_EXTERNAL_STORAGE))) {

            } else {
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
                        REQUEST_PERMISSIONS);
            }
        }else {
            Log.e("Else","Else");
            fn_imagespath();
        }



    }

    public ArrayList<Model_images> fn_imagespath() {
        al_images.clear();

        int int_position = 0;
        Uri uri;
        Cursor cursor;
        int column_index_data, column_index_folder_name;

        String absolutePathOfImage = null;
        uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;

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

        final String orderBy = MediaStore.Images.Media.DATE_TAKEN;
        cursor = getApplicationContext().getContentResolver().query(uri, projection, null, null, orderBy + " DESC");

        column_index_data = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
        column_index_folder_name = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME);
        while (cursor.moveToNext()) {
            absolutePathOfImage = cursor.getString(column_index_data);
            Log.e("Column", absolutePathOfImage);
            Log.e("Folder", cursor.getString(column_index_folder_name));

            for (int i = 0; i < al_images.size(); i++) {
                if (al_images.get(i).getStr_folder().equals(cursor.getString(column_index_folder_name))) {
                    boolean_folder = true;
                    int_position = i;
                    break;
                } else {
                    boolean_folder = false;
                }
            }


            if (boolean_folder) {

                ArrayList<String> al_path = new ArrayList<>();
                al_path.addAll(al_images.get(int_position).getAl_imagepath());
                al_path.add(absolutePathOfImage);
                al_images.get(int_position).setAl_imagepath(al_path);

            } else {
                ArrayList<String> al_path = new ArrayList<>();
                al_path.add(absolutePathOfImage);
                Model_images obj_model = new Model_images();
                obj_model.setStr_folder(cursor.getString(column_index_folder_name));
                obj_model.setAl_imagepath(al_path);

                al_images.add(obj_model);


            }


        }


        for (int i = 0; i < al_images.size(); i++) {
            Log.e("FOLDER", al_images.get(i).getStr_folder());
            for (int j = 0; j < al_images.get(i).getAl_imagepath().size(); j++) {
                Log.e("FILE", al_images.get(i).getAl_imagepath().get(j));
            }
        }
        obj_adapter = new Adapter_PhotosFolder(getApplicationContext(),al_images);
        gv_folder.setAdapter(obj_adapter);
        return al_images;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case REQUEST_PERMISSIONS: {
                for (int i = 0; i < grantResults.length; i++) {
                    if (grantResults.length > 0 && grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                        fn_imagespath();
                    } else {
                        Toast.makeText(MainActivity.this, "The app was not allowed to read or write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
                    }
                }
            }
        }
    }

}
笨笨の傻瓜 2024-10-10 06:39:42

对于使用 Compose 的 Android,这也很有效!

@Composable
internal fun rememberMediaPhotos(
    context: Context
): List<MediaPhoto> {
    val photos = remember { mutableStateListOf<MediaPhoto>() }
    val coroutineScope = rememberCoroutineScope()

    LaunchedEffect(coroutineScope) {
        withContext(Dispatchers.IO) {
            val projection = arrayOf(
                MediaStore.Images.Media._ID,
                MediaStore.Images.Media.DISPLAY_NAME,
                MediaStore.Images.Media.HEIGHT,
                MediaStore.Images.Media.WIDTH
            )

            val sortOrder = "${MediaStore.Images.Media.DATE_ADDED} DESC"

            val query = context.contentResolver.query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection,
                null,
                null,
                sortOrder
            )

            query?.use { cursor ->
                val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
                val nameColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME)
                val heightColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.HEIGHT)
                val widthColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.WIDTH)

                while (cursor.moveToNext()) {
                    val id = cursor.getLong(idColumn)
                    val name = cursor.getString(nameColumn)
                    val height = cursor.getFloat(heightColumn)
                    val width = cursor.getFloat(widthColumn)
                    val contentUri = ContentUris.withAppendedId(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        id
                    )

                    photos.add(
                        MediaPhoto(
                            name = name,
                            uri = contentUri,
                            size = Size(width = width, height = height)
                        )
                    )
                }
            }
        }
    }
    return photos
}

我创建了一个库来使这更容易:
https://github.com/nabla-run/Compose-gallery-picker

For Android with Compose, this works well too!

@Composable
internal fun rememberMediaPhotos(
    context: Context
): List<MediaPhoto> {
    val photos = remember { mutableStateListOf<MediaPhoto>() }
    val coroutineScope = rememberCoroutineScope()

    LaunchedEffect(coroutineScope) {
        withContext(Dispatchers.IO) {
            val projection = arrayOf(
                MediaStore.Images.Media._ID,
                MediaStore.Images.Media.DISPLAY_NAME,
                MediaStore.Images.Media.HEIGHT,
                MediaStore.Images.Media.WIDTH
            )

            val sortOrder = "${MediaStore.Images.Media.DATE_ADDED} DESC"

            val query = context.contentResolver.query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection,
                null,
                null,
                sortOrder
            )

            query?.use { cursor ->
                val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID)
                val nameColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME)
                val heightColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.HEIGHT)
                val widthColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.WIDTH)

                while (cursor.moveToNext()) {
                    val id = cursor.getLong(idColumn)
                    val name = cursor.getString(nameColumn)
                    val height = cursor.getFloat(heightColumn)
                    val width = cursor.getFloat(widthColumn)
                    val contentUri = ContentUris.withAppendedId(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        id
                    )

                    photos.add(
                        MediaPhoto(
                            name = name,
                            uri = contentUri,
                            size = Size(width = width, height = height)
                        )
                    )
                }
            }
        }
    }
    return photos
}

I have created a library to make this easier:
https://github.com/nabla-run/Compose-gallery-picker

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文