Displaying images from a specific folder on the SDCard using a gridview
Asked Answered
H

6

10

I'm attempting to create a gridview that is loaded with images from a specific folder that resides on an SDCard. The path to the folder is known, ("/sdcard/pictures") , but in the examples I've seen online I am unsure how or where to specify the path to the pictures folder I want to load images from. I have read through dozens of tutorials, even the HelloGridView tutorial at developer.android.com but those tutorials do not teach me what i am seeking.

Every tutorial I have read so far has either:

A) called the images as a Drawable from the /res folder and put them into an array to be loaded, not using the SDCard at all.

B) Accessed all pictures on the SDCard using the MediaStore but not specifying how to set the path to the folder I want to display images form

or

C) Suggested using BitmapFactory, which I haven't the slightest clue how to use.

If I'm going about this in the wrong way, please let me know and direct me toward the proper method to do what I'm trying to do.

Hakim answered 18/2, 2011 at 9:50 Comment(0)
C
15

OK, after many iterations of trying, I finally have an example that works and I thought I'd share it. My example queries the images MediaStore, then obtains the thumbnail for each image to display in a view. I am loading my images into a Gallery object, but that is not a requirement for this code to work:

Make sure you have a Cursor and int for the column index defined at the class level so that the Gallery's ImageAdapter has access to them:

private Cursor cursor;
private int columnIndex;

First, obtain a cursor of image IDs located in the folder:

Gallery g = (Gallery) findViewById(R.id.gallery);
// request only the image ID to be returned
String[] projection = {MediaStore.Images.Media._ID};
// Create the cursor pointing to the SDCard
cursor = managedQuery( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        projection, 
        MediaStore.Images.Media.DATA + " like ? ",
        new String[] {"%myimagesfolder%"},  
        null);
// Get the column index of the image ID
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
g.setAdapter(new ImageAdapter(this));

Then, in the ImageAdapter for the Gallery, obtain the thumbnail to display:

public View getView(int position, View convertView, ViewGroup parent) {
    ImageView i = new ImageView(context);
    // Move cursor to current position
    cursor.moveToPosition(position);
    // Get the current value for the requested column
    int imageID = cursor.getInt(columnIndex);
    // obtain the image URI
    Uri uri = Uri.withAppendedPath( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, Integer.toString(imageID) );
    String url = uri.toString();
    // Set the content of the image based on the image URI
    int originalImageId = Integer.parseInt(url.substring(url.lastIndexOf("/") + 1, url.length()));
    Bitmap b = MediaStore.Images.Thumbnails.getThumbnail(getContentResolver(),
                    originalImageId, MediaStore.Images.Thumbnails.MINI_KIND, null);
    i.setImageBitmap(b);
    i.setLayoutParams(new Gallery.LayoutParams(150, 100));
    i.setScaleType(ImageView.ScaleType.FIT_XY);
    i.setBackgroundResource(mGalleryItemBackground);
    return i;
}

I guess the most important section of this code is the managedQuery that demonstrates how to use MediaStore queries to filter a list of image files in a specific folder.

Combustion answered 23/8, 2011 at 14:55 Comment(3)
@achilldress : Hello, I followed your code exactly. But I log columnIndex is 0, cursor not null. It looks like wrong, you know why? Please tell me. Thank you.Infatuated
And the imageID I get from index 0 is null. android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0Infatuated
the managedQuery now is deprecated, and for an unknown reason, the cursor is always null here.Gillen
S
4

You need to do a few more steps than the GridView tutorial on developer.android.com. Using the following tutorial http://developer.android.com/resources/tutorials/views/hello-gridview.html

You'll want to add a method to create ImageView's of the files from your sd card:

Create/add a Vector to your class variables (to hold a list of ImageViews):

private Vector<ImageView> mySDCardImages;

Initialize the vector:

mySDCardImages = new Vector<ImageView>();

Create a method to load images:

List<Integer> drawablesId = new ArrayList<Integer>();
int picIndex=12345;
File sdDir = new File("/sdcard/pictures");
File[] sdDirFiles = sdDir.listFiles();
for(File singleFile : sdDirFiles)
{
   ImageView myImageView = new ImageView(context);
   myImageView.setImageDrawable(Drawable.createFromPath(singleFile.getAbsolutePath());
   myImageView.setId(picIndex);
   picIndex++;
   drawablesId.add(myImageView.getId());
   mySDCardImages.add(myImageView);
}
mThumbIds = (Integer[])drawablesId.toArray(new Integer[0]);

Then down in your ImageAdapter method, change

imageView.setImageResource(mThumbIds[position]);

to

imageView.setImageDrawable(mySDCardImages.get(position).getDrawable());

Remove from the ImageAdapter the initialization of mThumbIds. (it should be up with the definition of mySDCardImages. Accessible to both class methods.)

(Quick and dirty version) Make sure to test your path, etc and catch any Exceptions.

Shaving answered 22/7, 2011 at 21:35 Comment(2)
Hi, i used developer.android.com/guide/topics/ui/layout/… this one and i want to change it to get files from SDCard. Can you tell me where and what part of your code to write? thanksPerrault
If you want to post that as a question, I'll answer it. I don't know that I can answer that question very well in a comment here.Shaving
D
3

In your case BitmaFactory might be a good way to go. Example:

File dir = new File( "/sdcard/pictures" );    
String[] fileNames = dir.list(new FilenameFilter() { 
  boolean accept (File dir, String name) {
      if (new File(dir,name).isDirectory())
         return false;
      return name.toLowerCase().endsWith(".png");
  }
});
for(string bitmapFileName : fileNames) {
  Bitmap bmp = BitmapFactory.decodeFile(dir.getPath() + "/" + bitmapFileName);
  // do something with bitmap
}

Not time to test this but should work ;-)

Degradable answered 18/2, 2011 at 10:10 Comment(1)
Thanks for replying evilcroco, I'm testing out your code right now!Hakim
R
0

read this link: http://androidsamples.blogspot.com/2009/06/how-to-display-thumbnails-of-images.html
it shows how to use both mediastore and bitmapfactory.

the way you should chose depends on what exactly you need. if you have a static set of images, it's much better idea to put them to drawables, i think, cause this way it's faster and you don't rely on sd card, which can be removed, corrupt or files could be renamed/deleted

if images are dynamic, then use mediastore or bitmap factory. but keep in mind that putting images into array or something it's quite memory consuming, so you can end up having outofmemory exception

Ranged answered 18/2, 2011 at 10:10 Comment(1)
Thanks for replying! I've followed the tutorial and gotten it to compile correctly but I'm having trouble changing the folder path from which to load the images from. I did read in the comments however, that you can change the folder path query. My question is this: Would I change the query at "imagecursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, img, null, null, MediaStore.Images.Thumbnails.IMAGE_ID + "");" and does it accept a string as a parameter?Hakim
I
0

Looks like you want custom gallerry, it will take much time for you,

I suggest you get Custom Camera Gallery for your working.

You will get Photos/Videos in Grid View as you want.

Infatuated answered 3/12, 2015 at 9:13 Comment(0)
B
0

for Kotlin code see the answer of this question

the idea is alslo applicable for java (but you need to modify the code)

Briefcase answered 7/7, 2018 at 12:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.