Loading thumbnail Images in a GridView and Opening original images in AlertDialog using Media Content Providers

August 21, 2012
By

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”

New Android application project

Figure 1 : New Android application project


2. Design application launcher icon

Design Application launcher icon

Figure 2 : Design Application launcher icon


3. Create a blank activity

Create a blank activity

Figure 3 : Create a blank activity


4. Enter MainActivity details

Enter MainActivity details

Figure 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

An image in AlertDialog window

Figure 5 : An image in AlertDialog window


12. Download


13. Reference

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


How to hire me?

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


Android Knowledge Quiz

Ready to test your knowledge in Android? Take this quiz :



Tags: , , , , , , , ,

4 Responses to Loading thumbnail Images in a GridView and Opening original images in AlertDialog using Media Content Providers

  1. vinay singh on October 17, 2012 at 5:50 pm

    nice post dear thank you so much

  2. Paul on September 6, 2013 at 2:56 am

    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

  3. siva sundar on February 17, 2015 at 5:23 pm

    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.

  4. vihaan on May 21, 2015 at 12:22 pm

    source is missing permission

Leave a Reply

Your email address will not be published. Required fields are marked *

Be friend at g+

Subscribe for Lastest Updates

FBFPowered by ®Google Feedburner