Android Studio - 从画廊导入图像

Android Studio - importing images from gallery

我正在创建 activity 以查看图库中的图像(将图像拍摄到个人资料照片),但我遇到三个问题:

1) 部分照片重复
2) 如果我要显示来自 SD 卡的图像,它加载大约 30 秒
3) 有微缩视频

也许有人知道如何修复它?我想像 Facebook、Instagram 或 Behance 应用程序那样做

import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;

import com.stagap.stagap.R;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import static android.os.Environment.getExternalStoragePublicDirectory;

public class GalleryActivity extends AppCompatActivity {

    private Toolbar galleryToolbar;
    private RecyclerView recyclerGallery;
    private ArrayList<File> imageFiles;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gallery);
        galleryToolbar = findViewById(R.id.galleryToolbar);
        setSupportActionBar(galleryToolbar);
        recyclerGallery = findViewById(R.id.recyclerGallery);

        GridLayoutManager gridLayoutManager = new GridLayoutManager(getBaseContext(), 3);
        recyclerGallery.setLayoutManager(gridLayoutManager);
        imageFiles = new ArrayList<>();

        readImages(getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), imageFiles);
//        if(isExternalStorageAvailable() && !isExternalStorageReadOnly())
//            readImages(Environment.getExternalStorageDirectory(), imageFiles);
        Collections.sort(imageFiles, new SortFolder());

        GalleryRecyclerAdapter adapter = new GalleryRecyclerAdapter(getBaseContext(), imageFiles);
        recyclerGallery.setAdapter(adapter);
        recyclerGallery.setHasFixedSize(true);


    }

    private void readImages(File root ,ArrayList<File> imageList) {

        File[] files = root.listFiles();
        for(File file: files){

            if(file.isDirectory()){
                readImages(file, imageList);
            }else{
                if(file.getName().endsWith(".png") ||
                        file.getName().endsWith(".jpeg") ||
                        file.getName().endsWith(".jpg")){
                        imageList.add(file);
                }
            }
        }
    }

    class SortFolder implements Comparator<File> {
        @Override
        public int compare(File f1, File f2) {
            if (f1.lastModified() > (f2.lastModified())) {
                return -1;
            } else if (f1.lastModified() < (f2.lastModified())) {
                return +1;
            } else {
                return 0;
            }
        }
    }

    private static boolean isExternalStorageAvailable() {
        String extStorageState = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED.equals(extStorageState)) {
            return true;
        }
        return false;
    }

    private static boolean isExternalStorageReadOnly() {
        String extStorageState = Environment.getExternalStorageState();
        if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) {
            return true;
        }
        return false;
    }
}

你的 readImages 方法有点矫枉过正,AFAIK 从 phone 内存加载照片的最佳实践是这样的:

    private int imagesQuantity = 40;
    private Context ctx;
    private Cursor cursor;
    private ArrayList<Bitmap> photos = new ArrayList<>(imagesQuantity);
    private ArrayList<Uri> uris = new ArrayList<>(imagesQuantity);
    private ArrayList<Bitmap> photos = new ArrayList<>(imagesQuantity);

如上所述用位图声明arrayList,读取方法应该如下所示,有一些参数你可以改变读取照片的顺序(DESC =降序在你的情况下最好我猜

  String[] projection = new String[]{
            MediaStore.Images.ImageColumns._ID,
            MediaStore.Images.ImageColumns.DATA,
            MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
            MediaStore.Images.ImageColumns.DATE_TAKEN,
            MediaStore.Images.ImageColumns.MIME_TYPE,
    };
    cursor = ctx.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null,
            null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");
    cursor.moveToFirst();
    for (int i = 1; i <= imagesQuantity; i++) {
        Bitmap bmp = BitmapFactory.decodeFile(cursor.getString(1));
        Uri imageUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, cursor.getInt(cursor.getColumnIndex(MediaStore.Images.ImageColumns._ID)));
        photos.add(bmp);
        uris.add(imageUri);
        cursor.moveToNext();
    }
}