This article is an extension to the article “Asynchronously loading Image thumbnails in a GridView from an external (SD Card) storage using Media Content Providers in Android“.
In this article, the thumbnails of images from the external ( SD Card ) storage is loaded in grid view using Cursor Loader. And on clicking a thumbnail, corresponding original image will be opened in alert dialog window.
A screenshot of this application is shown towards the end of this article.
This application is developed in Eclipse ( 4.2.0 ) with ADT plugin ( 20.0.3 ) and Android SDK ( R20.0.3 )
1. Create a new Android application project namely “GridViewOpenImage”
2. Design application launcher icon
3. Create a blank activity
4. Enter MainActivity details
5. Update the file res/values/strings.xml
<resources> <string name="app_name">GridViewLoadImages</string> <string name="hello_world">Hello world!</string> <string name="menu_settings">Settings</string> <string name="title_activity_main">GridView with Images</string> <string name="img_description">Image Description</string> <string name="img_original_description">Original Image Description</string> </resources>
6. Update the layout for the MainActivity screen in the file res/layout/activity_main.xml
<GridView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/gridview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:numColumns="auto_fit" android:verticalSpacing="10dp" />
7. Create a new layout file res/layout/gridview.xml and update the content with the given below code
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" > <ImageView android:id="@+id/img" android:layout_width="fill_parent" android:layout_height="wrap_content" android:contentDescription="@string/img_description" android:padding="10dp" android:adjustViewBounds="true" /> </LinearLayout>
8. Create a new layout file res/layout/image_dialog_layout.xml and update the content with the given below code
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ImageView android:id="@+id/imgOriginal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:contentDescription="@string/img_original_description" /> </LinearLayout>
9. Create a class namely ImageDialog in the file src/in/wptrafficanalyzer/gridviewopenimage/ImageDialog.java
package in.wptrafficanalyzer.gridviewopenimage; import java.io.File; import android.app.AlertDialog; import android.app.Dialog; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.support.v4.app.DialogFragment; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; public class ImageDialog extends DialogFragment implements LoaderCallbacks<Cursor>{ LayoutInflater mLayoutInflater; ImageView mImgOriginal; String mId=""; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** Initializing the Loader */ getLoaderManager().initLoader(0, null, this); } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { /** Instantiating Builder object to create an alert dialog window */ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); /** Getting layout inflater */ mLayoutInflater = getActivity().getLayoutInflater(); /** Getting the screen view corresponding to the layout image_dialog_layout */ View v = mLayoutInflater.inflate(R.layout.image_dialog_layout, null); /** Getting a reference to the image widget imgOriginal of the layoutfile image_dialog_layout.xml */ mImgOriginal = (ImageView) v.findViewById(R.id.imgOriginal); /** Setting a view on the builder */ builder.setView(v); /** Settng a title for the alert dialog window */ builder.setTitle("Image"); /** Creating a alert window */ return builder.create(); } /** A callback method, invoked on initializing the loader */ @Override public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { /** Getting Bundle object passed from MainActivity */ Bundle b = getArguments(); /** Getting image_id from the bundle object */ mId = b.getString("image_id"); /** Setting uri to the original image files stored in external storage device */ Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; /** Creating a cursor loader from the uri corresponds to mID **/ CursorLoader cLoader= new CursorLoader(getActivity(), uri, null, "_id=" + mId , null, null); return cLoader; } /** A callback method, invoked on initializing the loader */ @Override public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) { if(arg1.getCount()==0) return; String path = ""; /** Move to the first row of the cursor, if it exists */ if(arg1.moveToFirst()){ path = arg1.getString(arg1.getColumnIndex("_data")); File imgFile = new File(path); if(imgFile.exists()){ Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath()); mImgOriginal.setImageBitmap(myBitmap); mImgOriginal.setAdjustViewBounds(true); } } } @Override public void onLoaderReset(Loader<Cursor> arg0) { } }
10. Update the class MainActivity in the file src/in/wptrafficanalyzer/gridviewopenimage/MainActivity.java
package in.wptrafficanalyzer.gridviewopenimage; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.widget.SimpleCursorAdapter; import android.view.Menu; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.GridView; public class MainActivity extends FragmentActivity implements LoaderCallbacks<Cursor>{ /** SimpleCursorAdapter, holds images and layout for the gridview */ SimpleCursorAdapter mAdapter; @Override protected void onStart() { super.onStart(); /** Initializes the Loader */ getSupportLoaderManager().initLoader(0, null, this); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /** Getting a reference to gridview of the MainActivity layout */ GridView gridView = (GridView) findViewById(R.id.gridview); /** Create an adapter for the gridview */ /** This adapter defines the data and the layout for the grid view */ mAdapter = new SimpleCursorAdapter( getBaseContext(), R.layout.gridview, null, new String[] { "_data","_id"} , new int[] { R.id.img}, 0 ); /** Setting adapter for the gridview */ gridView.setAdapter(mAdapter); /** Loader to get images from the SD Card */ getSupportLoaderManager().initLoader(0, null, this); /** Defining item click listener for the grid view */ OnItemClickListener itemClickListener = new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { /** Getting the cursor object corresponds to the clicked item */ Cursor c1 = (Cursor ) arg0.getItemAtPosition(position); /** Getting the image_id from the cursor */ /** image_id of the thumbnail is same as the original image id */ String id = c1.getString(c1.getColumnIndex("image_id")); /** Creating a bundle object to pass the image_id to the ImageDialog */ Bundle b = new Bundle(); /** Storing image_id in the bundle object */ b.putString("image_id", id); /** Instantiating ImageDialog, which displays the clicked image */ ImageDialog img = new ImageDialog(); /** Setting the bundle object to the ImageDialog */ img.setArguments(b); /** Opening ImageDialog */ img.show(getSupportFragmentManager(), "IMAGEDIALOG"); return ; } }; /** Setting itemclicklistener for the grid view */ gridView.setOnItemClickListener(itemClickListener); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } /** A callback method invoked by the loader when initLoader() is called */ @Override public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { /** Getting uri to the Thumbnail images stored in the external storage */ Uri uri = MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI; /** Invoking the uri */ return new CursorLoader(this, uri, null, null, null, null); } /** A callback method, invoked after the requested content provider returned all the data */ @Override public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) { mAdapter.swapCursor(arg1); } @Override public void onLoaderReset(Loader<Cursor> arg0) { // TODO Auto-generated method stub } }
11. Screenshot of the application in execution
12. Download

13. Reference
http://developer.android.com/guide/index.html

I am George Mathew, working as software architect and Android app developer at wptrafficanalyzer.in
You can hire me on hourly basis or on project basis for Android applications development.
For hiring me, please mail your requirements to info@wptrafficanalyzer.in.
My other blogs
store4js.blogspot.com
nice post dear thank you so much
Hi man, do you know how can I get images from a specific folder in sdcard using your code? thx in advance
My folder is located in sdcard/dcim/foldername
Hi, Thanks for the tutorial it’s really interesting. I have a doubt is it possible to display images using UIL(Universal Image Loader) by fetching image by your code.
If it possible could u send me the sample code.
Thanks in Advance.
source is missing permission