Below you will find a Android example of how to access and display images that are stored on your SD card.
I wrote part 2 for this article, where images are loaded in the background using an asynchronous task. It is an improvement over this article, but I strongly suggest trying this one first to fully appreciate the differences between the two approaches.
The main idea is to make use of the MediaStore class, which is a Media provider that contains data for all available media on both internal and external storage devices (such as an SD card). An adapter is used as a bridge between the data and the view.
I wrote part 2 for this article, where images are loaded in the background using an asynchronous task. It is an improvement over this article, but I strongly suggest trying this one first to fully appreciate the differences between the two approaches.
The main idea is to make use of the MediaStore class, which is a Media provider that contains data for all available media on both internal and external storage devices (such as an SD card). An adapter is used as a bridge between the data and the view.
The activity is shown below:
package blog.android.sdcard;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.AdapterView.OnItemClickListener;
/**
* Displays images from an SD card.
*/
public class SDCardImagesActivity extends Activity {
/**
* Cursor used to access the results from querying for images on the SD card.
*/
private Cursor cursor;
/*
* Column index for the Thumbnails Image IDs.
*/
private int columnIndex;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sdcard);
// Set up an array of the Thumbnail Image ID column we want
String[] projection = {MediaStore.Images.Thumbnails._ID};
// Create the cursor pointing to the SDCard
cursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
projection, // Which columns to return
null, // Return all rows
null,
MediaStore.Images.Thumbnails.IMAGE_ID);
// Get the column index of the Thumbnails Image ID
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID);
GridView sdcardImages = (GridView) findViewById(R.id.sdcard);
sdcardImages.setAdapter(new ImageAdapter(this));
// Set up a click listener
sdcardImages.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position, long id) {
// Get the data location of the image
String[] projection = {MediaStore.Images.Media.DATA};
cursor = managedQuery( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection, // Which columns to return
null, // Return all rows
null,
null);
columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToPosition(position);
// Get image filename
String imagePath = cursor.getString(columnIndex);
// Use this path to do further processing, i.e. full screen display
}
});
}
/**
* Adapter for our image files.
*/
private class ImageAdapter extends BaseAdapter {
private Context context;
public ImageAdapter(Context localContext) {
context = localContext;
}
public int getCount() {
return cursor.getCount();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView picturesView;
if (convertView == null) {
picturesView = new ImageView(context);
// Move cursor to current position
cursor.moveToPosition(position);
// Get the current value for the requested column
int imageID = cursor.getInt(columnIndex);
// Set the content of the image based on the provided URI
picturesView.setImageURI(Uri.withAppendedPath(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, "" + imageID));
picturesView.setScaleType(ImageView.ScaleType.FIT_CENTER);
picturesView.setPadding(8, 8, 8, 8);
picturesView.setLayoutParams(new GridView.LayoutParams(100, 100));
}
else {
picturesView = (ImageView)convertView;
}
return picturesView;
}
}
}
The layout of the main activity is shown below:<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/sdcard"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:numColumns="auto_fit"
android:columnWidth="90dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
In order for this to work, you need to emulate an SD card.
Enjoy!
UPDATE (October 19, 2009): In order to be bale to view thumbnails images from the SD Card, Android needs to create them first, hence you should start the Gallery application that comes preinstalled, and open the sdcard folder which will automatically create thumbnails for the images stored on your sdcard. This is a current shortcoming of the SDK that will be fixed in future releases (http://groups.google.com/group/android-developers/browse_thread/thread/3f01b284e2537312/fa9487d19db4907e).
UPDATE (October 07, 2009): For some reason, if you use
MediaStore.Images.Thumbnails.IMAGE_ID
like in the previous version of the above code, the images are not always displayed on the screen. Changing to
MediaStore.Images.Thumbnails._ID
seems to solve the problem. I will look more into why and get back to you.
Furthermore, some images have the wrong path attached to them. I changed the creation of the cursor object from
cursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, projection, // Which columns to return null, // Return all rows null, null);to
cursor = managedQuery( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, projection, // Which columns to return null, // Return all rows null, MediaStore.Images.Thumbnails.IMAGE_ID);

55 comments:
hi,
I ve done all the necessary corrections on my code but still its not displaying the images... the code is unning and the emulator gets launched but shows only a blank page... please help me out in this code
Have you emulated the sdcard first, started the emulator with that sd card, and pushed the images on the sd card using adb push command properly? If you did all that, when starting the emulator, open the Gallery application that comes with it, and see if it displays the images on the sd card. If it does, try my application again. Post the results back here.
hi,
I ve done all wat u ve asked... i ve pushed the images properly but there is some confusion in the null loop or external URI i guess but the pog shows no error only
i meant the prog shows no error but i m not getting the desired output
Do you see the images on the sd card when using the Gallery application that comes with the emulator?
no i cant c images in the emulator.
its displayed under sdcard in the file explorer
Thanks
in that default gallerywith emulator it shows no media found. wat shall i do
OK, so you do not see any images when using the Gallery application, which implies that maybe the sd card was not emulated properly, or loaded properly. If you followed the steps described in the link I provided, you should have created the sd card image and loaded the images properly. When you create a run configuration for your Android project, you have to specify an AVD for deployment (under the Target tab in run configurations). You have to create one and link to the sd card image you previously created. More info on how to achieve this can be found at http://developer.android.com/guide/developing/eclipse-adt.html#CreatingAnAvd. After you're doen with this, make sure you will use that AVD when starting the emulator and/or launching your application. Always use the Galley application first to make sure that everything works out, then try my application.
I just re-tested the code I posted and it works fine for me (sdk 1.0 and 1.6), so make sure you follow all the necessary steps.
Hello, very nice demo. I got it working on my device first try with no hitches except for one. For some reason it only accesses the first 20 or so images from the sdcard and then builds the gridview with those 20 images repeated over and over for what looks like the total # of images I have on the sdcard. I'm lost as to why that would happen, but I'm pretty new tho this so maybe its an error on my part.
Hi Hyperjetta. Try loading all images from the SD Card with the Gallery application first (which will create a thumbnail for those images), and then use the sample code. Let me know if it solves the problem. I plan to post an update (improvement) for this post in the near future.
Hmm, didn't seem to help. I'm testing the app on my phone which has 400 pictures on it. All the thumbnails load normally in the gallery.
All images have to be loaded in the Gallery application (you actually have to wait until all are loaded, which means you see the thumbnails being displayed on the screen). If you are still having problems after that, I will write a follow up for this post that I am hoping does not have the same issues as this one. By the way, what phone are you using?
I wrote part 2 for this article.
Hi,
I wanted to display all the images of res/drawable folder in gridview.How can I achieve dis without specifying all the Thumb Ids in an Integer array?.
Hi vasu,
I am not aware of any other way to achieve what you want. My suggestion is to post this question in the android developers forum.
Hi Mihai Fonoage,
Thanks for response.Can we access the images of Drawable or Assests folder by setting URI as like u did for Displaying images from SD card?.Give me a good idea to set the URIs for different locations with examples(for internal and external folders).
I was wondering if there was any way to pass an array of the image files to the gallery view since I am looping through the sdcard to find ALL image files. That way all the image files get loaded on the view.
The gallery view (grid view) works together with an adapter. If you have an array of image files, you would need to use an image view together with those image files, something similar to what you have in Grid2.java.
Now, having said that, I still believe that the best way to display all images from the SD Card is through the use of an AsynchTask, coupled with an Adapter, as I showed in http://mihaifonoage.blogspot.com/2009/11/displaying-images-from-sd-card-in.html, since it will display one image at a time, loading them in the background.
is this working in actual device???
i have tested this in MY HTC TATTOO but only a blank screen displayed???
Try part 2 of the article, and make sure you have thumbnails created because the code uses MediaStore.Images.Thumbnails (open the Gallery app on your phone and see if it detects any images on your SD Card, and by doing so it will automatically create thumbnails of those images).
Hi there, that's a great code!
But I got a question: how would I get it working with videos?? I am really new to Android and I am a bit stuck there...
Thanks
Look into http://developer.android.com/reference/android/provider/MediaStore.Video.html.
Hi,
Thanks very much for this guide. It works wonderfully on my phone, running Android API level 7.
However, it displays an image multiple times. It displays the set of all images once, then it repeats that set few more times. How do I get it to display them only once?
I'm glad you find it useful. For the problem you have, look into part 2 of this article. You have a link at the beginning of the post.
Excellent..I have been looking for this for some time. It helped me. Thanks.
And, by the way, please mention that you named the xml file as "sdcard.xml" . I had to change the name from default "main.xml" to "sdcard.xml" only after I was thrown an error. Thanks again.
what is the code to insert images into the sdcard?
after inserting, just follow this example to display it right?
sorry im very new to android, this is totally advance.
hi, i am new on android, i want to display gallery images in my application also when i click an image it should open for editing. your SDcard code only displays the images but can't open them, plz help me.
Thank You!
thank you for you article it was very helpful, however I do have an addition. Androids Adapter works like this; when you scroll he reuses old elements by passing them to getview, but you return the old element, this creates duplicates..
so the correct way to do this is:
public View getView(int position, View convertView, ViewGroup parent) {
cursor.moveToPosition(position);
int imageID = cursor.getInt(columnIndex);
ImageView picturesView = convertView==null?new ImageView(context):(ImageView) convertView;
picturesView.setImageURI(Uri.withAppendedPath(
MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, "" + imageID));
if(picturesView==null){
picturesView.setScaleType(ImageView.ScaleType.FIT_CENTER);
picturesView.setPadding(8, 8, 8, 8);
picturesView.setLayoutParams(new GridView.LayoutParams(100, 100));
}
return picturesView;
}
little mistake in my last comment
if(picturesView==null){
should be
if(convertView==null){
@OwenRay
I fixed that in part 2 of my article. There is a link to that at the beginning of the blog, or you can go directly from here: http://mihaifonoage.blogspot.com/2009/11/displaying-images-from-sd-card-in.html
That helped me solve the "java.lang.OutOfMemoryError: bitmap size exceeds VM budget" problem - I used this code to get the thumb for each URI and put the thumb into my gallery widget. I maintain the URIs in the adapter so I can get the full size images one at a time. Perfect - thanks!
hi,
plz help me to create a slideshow of images which are present in sdcard
Hi, I have tried your code but it crashes. Please help troubleshoot.
Hi, I have tried using this code, but I have been having a lot of problems. My AVD has a sd card and I was able to push files onto it. However, I got some serious errors with the Image Adapter when trying to run this code. I had to create a new object from the main activity class so that I would be able to user the cursor in Main activity. Then, when my code finally seemed error-free, I tried to run it and all I see being displayed is a textview at the top. Please me solve this problem that I have been struggling with for a while.
Hi Dani,
Have you tried the improved version of this code: http://mihaifonoage.blogspot.com/2009/11/displaying-images-from-sd-card-in.html
Let me know if that works for you!
Hi Mihai,
I tried your improved version but still getting a black screen. I really don't know what could be the problem. Any suggestions?
hi every boy ,
i am using ListActivity for my VIEW and extends ArrayAdapter to inflate rows,
for each row i need thumbnail, i using some part of MIHAI code but i got the wrong thumbnail
i using below code :
public View getView(int position, View convertView, ViewGroup parent)
{
.
.
.
.
.
Long Imageid = getItemId(position);
Uri imageUri = Uri.withAppendedPath(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, "" + imageId);
try
{
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
if(bitmap != null)
{
Bitmap newBitmap = Bitmap.createScaledBitmap(bitmap, width, width, true);
bitmap.recycle();
icon = newBitmap;
}
else
icon = null;
}
catch(IOException e)
{
}
}
any help ?
In the progaram it shows the error "The local variable imagePath is never read".Why it is so?
@Mihai ,In the above program which you wrote to display images from sd card, I am getting a warning in the code "Multiple markers at this line
- Line breakpoint:Grid2 [line: 53] - onItemClick(AdapterView, View,
int, long)
- The local variable imagePath is never read"
Please help me to resolve this.
can anybody please send me a download link for working code of this example I am newbeas in android development i am very frasted so please help me
Thanks in advance
I am trying to view the images on Motorola Xoom. I would like to access the photos in the pictures folder. I am unable to find any documentation on how to do that? Any pointers would be greatly appreciated.
Hi mihai,
Im developing one grid view program and displayed some images its working fine.. when i click one images that time to display that image in fullscreen when i scroll left or right i need to load back or previews image... i need to show all the images one by one...
Hie I am new to android.. Ur tutorial was awesome. It worked for me. Now i am working on a video app. Getting all the Videos from the sd-card. I am able to get the thumb images. But the main problem is after clicking on the thumbnail, the respective video must be played. Actual video is not playing. after clicking on end of the GalleryView. IndexoutofBounfException error is occuring Can u please help me out..
This is one of the fantastic post.I like your blog status.Thanks for presenting this kind pf Information.This is one of the challenging post.Android app developers
Hi..
This is a good example..
But what if i want to fetch images from the specific folder other than default folder where images stored...
suppose i have a folder "/sdcard/myimage/*.jpg"
what should i do to display only those images...??
Pls reply as soon as possible
Hi..
This is a good example..
But what if i want to fetch images from the specific folder other than default folder where images stored...
suppose i have a folder "/sdcard/myimage/*.jpg"
what should i do to display only those images...??
Pls reply as soon as possible
Hi
When i click on the image im not getting the enlarged image.
i have used
imageview.setImageResource(projection[position])
projection is the string array
This is one of the brilliant post.Your blog is presenting very satisfactory information.This is one of the supportive post.
This is one of the satisfactory post.I like your blog features.This is one of the good application.
Hi Mihai,
In my case I cannot get the path to the original image (the one who's thumb i get in the cursor).
This part of the code:
String path = cursor.getString(columnIndexPath);
Uri imgThmbPath = Uri.withAppendedPath( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, ""
+ imageID);
returns me something like this (in imgThmbPath ): content://media/external/images/thumbnails/1
This can't be the full image, the original one. How do I get the path to the original image?
How do i get my android to download to my micro sd card?
My phone likes to save stuff on my phone's memory and i want the stuff saved on my sd card. I have android 2.2.
thanks;
App Development Company
i am really new to android
I am trying to get images from sd card in gridview in android and to display them when clicked
I have tried this program but there is a problem with the output
there is no error showing in the program but am not getting the required output
please give me relevant answer
i want to select multiple images from sdcard and store in sqlite database ...and retrieve back from sqlite view in gridview....i tried to do this from 15 days but can't make... can anyone help me...??
Post a Comment