Android: how to get all folders with photos?
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>
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;
Paltroth
Updated on July 15, 2022Comments
-
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 about 10 yearsbut i don't need from 1 directory. I need from all (INTERNAL, EXTERNAL).
-
user184994 about 10 yearsNo 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 about 10 yearsHey. But can you show me how to add your code to gridview for to show folders??
-
Paltroth about 10 yearsi can't, cuz i'm secon day here, and have low reputation. :( But i will do when my reputation will be higher.
-
Paltroth about 10 years3rd trying to make gallery and still can't make with showing folders :(
-
kablu about 10 yearsplz wait.. i give i tutorial links
-
Paltroth about 10 yearsHi. 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 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 about 10 yearsHey i've got an error at launching my apk file. i posted my xml files. can you look plz?
-
Paltroth about 10 yearsand look here plz stackoverflow.com/questions/23710136/… may be you know how to finish that code?? it;s show folders too
-
user184994 about 10 yearsHi, Could you post the logcat output as well please?
-
Paltroth about 10 yearsi don;t use emulator -.-'
-
user184994 about 10 yearsOkay, 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 about 10 yearsstill 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 about 10 years@Paltroth I've added the XML files.
-
Paltroth about 10 yearsdamn... 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 about 10 yearscuz i don't know why he closing always program
-
user184994 about 10 yearsI'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 about 10 yearsi made storade= sdcard. there max 500 pictures, and max size i think 1mb+
-
user184994 about 10 yearsI'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 about 10 yearssame 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 about 10 yearsDo you have a github account?
-
user184994 about 10 yearsI've uploaded the project to github.com/jpilfold/gallery
-
user184994 about 10 yearsI'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 about 10 yearsClick the link I just posted and we can sort it out on IRC. It's easier than using these comment boxes. Thanks
-
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 over 8 yearshow can we add all the folders from sdcard , i tried
String root_sd = Environment.getExternalStorageDirectory().toString() ; setGridAdapter(root_sd);
but the app crashed -
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 over 3 yearsI have posted a new answer based on your answer with some modifications and i need some more help if you can,Thank you