Android: how to get all folders with photos?

27,470

Solution 1

EDIT : I've thrown together a working example for you. It works like this:

It will start within a directory (in the example below, /storage/sdcard/DCIM/). If the directory contains any images, they will be displayed. If it contains any sub-directories, it will check to see if they contain either images, or their own sub-directories. If they do, a folder icon will be displayed. Clicking on the folder icon will open up the folder, and show the images/ sub-directories that it contains.

Please note that this is just intended to give you a rough idea of how to implement it-- you will still need to work on this code a bit to improve the efficiency, especially in terms of memory usage, but I've run this on my emulator and the code is working.

Within your activity

public class MainActivity extends Activity implements OnItemClickListener {

    List<GridViewItem> gridItems;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setGridAdapter("/storage/sdcard/DCIM/");
    }


    /**
     * This will create our GridViewItems and set the adapter
     * 
     * @param path
     *            The directory in which to search for images
     */
    private void setGridAdapter(String path) {
        // Create a new grid adapter
        gridItems = createGridItems(path);
        MyGridAdapter adapter = new MyGridAdapter(this, gridItems);

        // Set the grid adapter
        GridView gridView = (GridView) findViewById(R.id.gridView);
        gridView.setAdapter(adapter);

        // Set the onClickListener
        gridView.setOnItemClickListener(this);
    }


    /**
     * Go through the specified directory, and create items to display in our
     * GridView
     */
    private List<GridViewItem> createGridItems(String directoryPath) {
        List<GridViewItem> items = new ArrayList<GridViewItem>();

        // List all the items within the folder.
        File[] files = new File(directoryPath).listFiles(new ImageFileFilter());
        for (File file : files) {

            // Add the directories containing images or sub-directories
            if (file.isDirectory()
                && file.listFiles(new ImageFileFilter()).length > 0) {

                items.add(new GridViewItem(file.getAbsolutePath(), true, null));
            }
            // Add the images
            else {
                Bitmap image = BitmapHelper.decodeBitmapFromFile(file.getAbsolutePath(),
                                                                 50,
                                                                 50);
                items.add(new GridViewItem(file.getAbsolutePath(), false, image));
            }
        }

        return items;
    }


    /**
     * Checks the file to see if it has a compatible extension.
     */
    private boolean isImageFile(String filePath) {
        if (filePath.endsWith(".jpg") || filePath.endsWith(".png"))
        // Add other formats as desired
        {
            return true;
        }
        return false;
    }


    @Override
    public void
            onItemClick(AdapterView<?> parent, View view, int position, long id) {

        if (gridItems.get(position).isDirectory()) {
            setGridAdapter(gridItems.get(position).getPath());
        }
        else {
            // Display the image
        }

    }

    /**
     * This can be used to filter files.
     */
    private class ImageFileFilter implements FileFilter {

        @Override
        public boolean accept(File file) {
            if (file.isDirectory()) {
                return true;
            }
            else if (isImageFile(file.getAbsolutePath())) {
                return true;
            }
            return false;
        }
    }

}

Then you need to create the adapter, which should extend BaseAdapter, and look like this.

public class MyGridAdapter extends BaseAdapter {

    LayoutInflater inflater;
    List<GridViewItem> items;


    public MyGridAdapter(Context context, List<GridViewItem> items) {
        this.items = items;
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }


    @Override
    public int getCount() {
        return items.size();
    }


    @Override
    public Object getItem(int position) {
        return items.get(position);
    }


    @Override
    public long getItemId(int position) {
        return position;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (convertView == null) {
            convertView = inflater.inflate(R.layout.grid_item, null);
        }

        TextView text = (TextView) convertView.findViewById(R.id.textView);
        text.setText(items.get(position).getPath());

        ImageView imageView = (ImageView) convertView.findViewById(R.id.imageView);
        Bitmap image = items.get(position).getImage();

        if (image != null){
            imageView.setImageBitmap(image);
        }
        else {
            // If no image is provided, display a folder icon.
            imageView.setImageResource(R.drawable.your_folder_icon);
        }

        return convertView;
    }

}

And you need to create a class that represents each grid item

public class GridViewItem {

    private String path;
    private boolean isDirectory;
    private Bitmap image;


    public GridViewItem(String path, boolean isDirectory, Bitmap image) {
        this.path = path;
        this.isDirectory = isDirectory;
        this.image = image;
    }


    public String getPath() {
        return path;
    }


    public boolean isDirectory() {
        return isDirectory;
    }


    public Bitmap getImage() {
        return image;
    }
}

A class for working with images

public abstract class BitmapHelper {

    public static Bitmap decodeBitmapFromFile(String imagePath,
                                              int reqWidth,
                                              int reqHeight) {

        // First decode with inJustDecodeBounds=true to check dimensions
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imagePath, options);

        // Calculate inSampleSize
        options.inSampleSize = calculateSampleSize(options, reqWidth, reqHeight);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(imagePath, options);
    }


    private static int calculateSampleSize(BitmapFactory.Options options,
                                           int reqHeight,
                                           int reqWidth) {

        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and
            // keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                   && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;

    }

}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/gridView"
    android:numColumns="auto_fit"
    android:gravity="center"
    android:columnWidth="150dp"
    android:stretchMode="columnWidth"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
</GridView>

grid_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="150dp"
    android:layout_height="150dp"
    android:padding="5dp" >

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:scaleType="centerCrop"
        android:src="@drawable/andrew_salgado" >
    </ImageView>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="20dp"
        android:layout_alignParentBottom="true"
        android:alpha="0.8"
        android:background="#000000" >

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="start"
            android:singleLine="true"
            android:textColor="#FFFFFF" />

    </RelativeLayout>

</RelativeLayout>

enter image description here

Solution 2

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

}

adapter_photosfolder.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <LinearLayout
        android:layout_width="match_parent"
        android:orientation="vertical"
        android:layout_marginTop="10dp"
        android:layout_marginLeft="10dp"
        android:background="@drawable/drawable_photofolder"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="10dp"
        android:layout_height="match_parent">
    <ImageView
        android:layout_width="150dp"
        android:layout_gravity="center"
        android:layout_height="150dp"
        android:id="@+id/iv_image"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/tv_folder"
        android:textStyle="bold"
        android:textColor="#000000"
        android:layout_marginLeft="10dp"
        android:textSize="15dp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/tv_folder2"
            android:textColor="#dfdfdf"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="10dp"
            android:textSize="15dp"/>
    </LinearLayout>

    <RelativeLayout
        android:layout_width="match_parent"
        android:id="@+id/rl_select"
        android:alpha="0.5"
        android:layout_height="match_parent">

    </RelativeLayout>

</RelativeLayout>

Adapter_PhotosFolder.java

package galleryimages.galleryimages;


import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;

import java.util.ArrayList;


public class Adapter_PhotosFolder extends ArrayAdapter<Model_images> {

    Context context;
    ViewHolder viewHolder;
    ArrayList<Model_images> al_menu = new ArrayList<>();


    public Adapter_PhotosFolder(Context context, ArrayList<Model_images> al_menu) {
        super(context, R.layout.adapter_photosfolder, al_menu);
        this.al_menu = al_menu;
        this.context = context;


    }

    @Override
    public int getCount() {

        Log.e("ADAPTER LIST SIZE", al_menu.size() + "");
        return al_menu.size();
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @Override
    public int getViewTypeCount() {
        if (al_menu.size() > 0) {
            return al_menu.size();
        } else {
            return 1;
        }
    }

    @Override
    public long getItemId(int position) {
        return position;
    }


    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {

        if (convertView == null) {

            viewHolder = new ViewHolder();
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.adapter_photosfolder, parent, false);
            viewHolder.tv_foldern = (TextView) convertView.findViewById(R.id.tv_folder);
            viewHolder.tv_foldersize = (TextView) convertView.findViewById(R.id.tv_folder2);
            viewHolder.iv_image = (ImageView) convertView.findViewById(R.id.iv_image);


            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.tv_foldern.setText(al_menu.get(position).getStr_folder());
            viewHolder.tv_foldersize.setText(al_menu.get(position).getAl_imagepath().size()+"");



        Glide.with(context).load("file://" + al_menu.get(position).getAl_imagepath().get(0))
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .skipMemoryCache(true)
                .into(viewHolder.iv_image);


        return convertView;

    }

    private static class ViewHolder {
        TextView tv_foldern, tv_foldersize;
        ImageView iv_image;


    }


}

Solution 3

Uri lUri;
    Cursor lCursor;
    Log.w("ImageUtils: ", "GetAllImagesFoldersCursor");

    lUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    String[] lProjection = {"DISTINCT " + MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
            MediaStore.Images.Media.DATA, MediaStore.Images.Media.DATE_TAKEN};
    String lSelectionString = MediaStore.Images.Media.BUCKET_DISPLAY_NAME +
            " IS NOT NULL) GROUP BY (" + MediaStore.Images.Media.BUCKET_DISPLAY_NAME;
    lCursor = aContext.getContentResolver().query(lUri, lProjection, lSelectionString,
            null, null);

    if (lCursor != null) {
        Log.w("ImageUtils: ", "Returning total Folders: " + lCursor.getCount());
    }
    return lCursor;
Share:
27,470
Paltroth
Author by

Paltroth

Updated on July 15, 2022

Comments

  • Paltroth
    Paltroth almost 2 years

    I trying to make a gallery. I know how to get all photos and to show them in grid view. But can someone explain how to get and show folders(with photos)?

    i've got error after launching my apk file. look plz at my xml files, may be something wrong here??? gridview.xml:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
        <GridView
            android:id="@+id/gridView"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:layout_marginBottom="-10dp"
            android:layout_marginLeft="-10dp"
            android:layout_marginRight="-10dp"
            android:layout_marginTop="-10dp"
            android:horizontalSpacing="-15dp"
            android:numColumns="3"
            android:padding="0dp"
            android:verticalSpacing="-15dp" >
        </GridView>
        </LinearLayout>
    

    and grid_item:

    <ImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:layout_marginRight="2dp"
            android:layout_marginTop="2dp"
    
            android:gravity="center"
            android:scaleType="center"
             />
    
  • Paltroth
    Paltroth about 10 years
    but i don't need from 1 directory. I need from all (INTERNAL, EXTERNAL).
  • user184994
    user184994 about 10 years
    No probs. If this has helped you, would you mind accepting this as the answer? You just need to click the tick underneath the up/down vote buttons. Thanks :)
  • Paltroth
    Paltroth about 10 years
    Hey. But can you show me how to add your code to gridview for to show folders??
  • Paltroth
    Paltroth about 10 years
    i can't, cuz i'm secon day here, and have low reputation. :( But i will do when my reputation will be higher.
  • Paltroth
    Paltroth about 10 years
    3rd trying to make gallery and still can't make with showing folders :(
  • kablu
    kablu about 10 years
    plz wait.. i give i tutorial links
  • Paltroth
    Paltroth about 10 years
    Hi. Can you please explain how to use your code? I mean, may be you have any example?? Cuz i don't understand how to add that code to my gridview
  • user184994
    user184994 about 10 years
    @Paltroth please see my updated answer. I've tested this on my emulator and it is working. You will still need to work on it a little bit, but this should give you a good headstart. Let me know if you need any clarification of any of it.
  • Paltroth
    Paltroth about 10 years
    Hey i've got an error at launching my apk file. i posted my xml files. can you look plz?
  • Paltroth
    Paltroth about 10 years
    and look here plz stackoverflow.com/questions/23710136/… may be you know how to finish that code?? it;s show folders too
  • user184994
    user184994 about 10 years
    Hi, Could you post the logcat output as well please?
  • Paltroth
    Paltroth about 10 years
    i don;t use emulator -.-'
  • user184994
    user184994 about 10 years
    Okay, I've edited my answer to to make the images takes up less memory. I am guessing the reason it crashes is an out of memory exception, so try using the edit (more specifically, the updated decodeResource method). You should probably calculate the inSampleSize instead of just passing it 10, but as I said in my answer, this should just be a basic template that you can build on.
  • Paltroth
    Paltroth about 10 years
    still error, it doesn;t work at mobile. i gave all permitions(in manifest), and even tryed to change base folder. i think something wrong with my xml files. can you show your files plz?
  • user184994
    user184994 about 10 years
    @Paltroth I've added the XML files.
  • Paltroth
    Paltroth about 10 years
    damn... it's still don't works. i have no more idea what to do. if you have some free time, can you look at project? dropmefiles.com/467AU
  • Paltroth
    Paltroth about 10 years
    cuz i don't know why he closing always program
  • user184994
    user184994 about 10 years
    I'll try and have a look later. Can you just let me know how many images are in the base folder? And how big the images are?
  • Paltroth
    Paltroth about 10 years
    i made storade= sdcard. there max 500 pictures, and max size i think 1mb+
  • user184994
    user184994 about 10 years
    I've made another update. Add the bitmap helper class I made, and make the changes to the MainActivity. This will make sure that the images are loaded into memory as very small images. This may make it a bit more blurry, but it should solve any out of memory exceptions. I'm afraid if this doesn't help you, without having a LogCat output I don't know how else I can help...
  • Paltroth
    Paltroth about 10 years
    same thing...error after launching. Can you give your source code? or any examples with makeing gallery?? I know that i'm not very good programmer but still i must make a gallery which have tags(on photos for searching and showing them in gridview). so if you have any exampes give plz.
  • user184994
    user184994 about 10 years
    Do you have a github account?
  • user184994
    user184994 about 10 years
    I've uploaded the project to github.com/jpilfold/gallery
  • user184994
    user184994 about 10 years
    I've just set up an IRC channel. If you visit dal.net/news/shownews.php?id=124 and then type in #jimmy for the channel and click on Go, and then we can fix it on there.
  • user184994
    user184994 about 10 years
    Click the link I just posted and we can sort it out on IRC. It's easier than using these comment boxes. Thanks
  • Paltroth
    Paltroth about 10 years
    ..mm i found one project which show images in gridview, And a user can add tagg to that images. Can you say plz is it hard to make to show folders(which contain those images)? github.com/Andrew67/PhotoTagger/tree/master/src
  • 1234567
    1234567 over 8 years
    how can we add all the folders from sdcard , i tried String root_sd = Environment.getExternalStorageDirectory().toString() ; setGridAdapter(root_sd); but the app crashed
  • Umair
    Umair about 8 years
    @ user184994 .... I love u man ... Spent whole day to figure out but couldn't do so ... Unfortunately, I could only give u +1 .
  • Vivek Thummar
    Vivek Thummar over 3 years
    I have posted a new answer based on your answer with some modifications and i need some more help if you can,Thank you