Loading ListView with SDCard Thumbnail Images and displaying its Title, Size, Width and Height by merging cursors using MatrixCursor

September 5, 2012
By

In this article we will create an Android application to display the thumbnails of SDCard images in a listview. The details of the images such as title, size, width and height are also be displayed in the listview.

The thumbnails of the images can be retrieved using the content provider android.provider.MediaStore.Images.Thumbnails.

The details of the images can be retrieved using the content provider android.provider.MediaStore.Images.Media.

We are using a loader identified by  the unique id THUMBNAIL_LOADER_ID to load thumbnail images to the cursor variable mThumbCursor.

We are using a loader identified by  the unique id IMAGE_LOADER_ID to load thumbnail images to the cursor mImageCursor.

The cursors mThumbCursor and mImageCursor will be merged to a MatrixCursor variable mMatrixCursor. This MatrixCursor will be set to listview as its adapter to display the images and its details in the listview.

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 “ListViewWithSDCardImages”

Create a new Android Application Project

Figure1 : Create a new Android Application Project


2. Design an application launcher icon

Design application launcher icon

Figure 2 : Design application launcher icon


3. Create a blank activity to define the MainActivity class

Create a blank activity

Figure 3 : Create a blank activity


4. Enter MainActivity class details

Enter MainActivity Details

Figure 4 : Enter MainActivity Details


5. Add Android’s Support Library to this project

Loaders are introduced in Android API level 11 ( Honeycomb ) but can be used in pre Honeycomb versions using Android’s support library. Since this application will run in API level 4 and above, we need to add Android Support library to this project to use Loaders in our application.

By default, Android support library (android-support-v4.jar ) is added to this project by Eclipse IDE to the directory libs. If it is not added, we can do it manually by doing the following steps :

  • Open Project Explorer by Clicking “Window -> Show View -> Project Explorer”
  • Right click this project
  • Then from popup window, Click “Android Tools -> Add Support Library “

6. Update the file res/values/strings.xml


<resources>
    <string name="app_name">ListViewWithSDCardImages</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
    <string name="title_activity_main">ListView with Images</string>
</resources>


7. Update the layout of the MainActivity in the file res/layout/activity_main.xml


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView
        android:id="@+id/lv_thumbnail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:context=".MainActivity" />
</RelativeLayout>

8. Create a new layout for the listview items in the file res/layout/lv_layout.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="75dp" >
    <ImageView
        android:id="@+id/img_thumbnail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"integrate
        android:layout_alignParentLeft="true"
        android:adjustViewBounds="true"
        android:padding="5dp"
    />
    <TextView
        android:id="@+id/tv_details"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/img_thumbnail"
        android:padding="5dp"
    />
</RelativeLayout>


9. Update the class MainActivity in the file src/in/wptrafficanalyzer/listviewwithsdcardimages/MainActivity.java


package in.wptrafficanalyzer.listviewwithsdcardimages;

import android.database.Cursor;
import android.database.MatrixCursor;
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.widget.ListView;

public class MainActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {

    SimpleCursorAdapter mAdapter;

    private final int THUMBNAIL_LOADER_ID  = 0;
    private final int IMAGE_LOADER_ID  = 1;

    MatrixCursor mMatrixCursor;
    Cursor mThumbCursor;
    Cursor mImageCursor;

    String mThumbImageId="";
    String mThumbImageData="";
    String mImageSize="";
    String mImageTitle="";
    String mImageWidth="";
    String mImageHeight="";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /** Initializing MatrixCursor */
        mMatrixCursor = new MatrixCursor(new String[]{"_id","_data","_details"});

        /** Getting a reference to listview of the MainActivity layout */
        ListView lVThumbnail = (ListView) findViewById(R.id.lv_thumbnail);

        /** Creating an adapter object to set image and text in the listview */
        mAdapter = new SimpleCursorAdapter(
                                            getBaseContext(),
                                            R.layout.lv_layout,
                                            null,
                                            new String[] { "_data","_details"} ,
                                            new int[] { R.id.img_thumbnail,R.id.tv_details},
                                            0
                                           );

        /** Setting adapter for the listview */
        lVThumbnail.setAdapter(mAdapter);

        /** Loader to get thumbnail images from the SD Card */
        getSupportLoaderManager().initLoader(THUMBNAIL_LOADER_ID, null, this);
    }

    @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 loader_id, Bundle arg1) {
        CursorLoader cLoader;
        Uri uri;

        if(loader_id==THUMBNAIL_LOADER_ID){    /** Querying Thumbnail content provider */
            uri = MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI;
            cLoader = new CursorLoader(this, uri, null, null, null, null);
        }else { /** Querying Image Content provider with thumbnail image id */
            String image_id = arg1.getString("image_id");
            uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            cLoader = new CursorLoader(this, uri, null, MediaStore.Images.Media._ID +"=" +image_id, null, null);
        }
        return cLoader;
    }

    /** A callback method, invoked after the requested content provider returned all the data */
    @Override
    public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {

        if(arg0.getId()==THUMBNAIL_LOADER_ID){  /** Thumbnail cursor is loaded completely */
            mThumbCursor = arg1;

            if(mThumbCursor.moveToFirst()){ /** Taking the first thumbnail */

                mThumbImageId = mThumbCursor.getString(mThumbCursor.getColumnIndex(MediaStore.Images.Thumbnails._ID));
                mThumbImageData = mThumbCursor.getString(mThumbCursor.getColumnIndex(MediaStore.Images.Thumbnails.DATA));

                /** Getting the image id from the mThumbCursor and putting in to the bundle*/
                String image_id = mThumbCursor.getString(mThumbCursor.getColumnIndex(MediaStore.Images.Thumbnails.IMAGE_ID));
                Bundle data = new Bundle();
                data.putString("image_id", image_id);

                /** Intiates the Image Loader onCreateLoader() */
                getSupportLoaderManager().initLoader(IMAGE_LOADER_ID, data, this);

            }

        }else if(arg0.getId() == IMAGE_LOADER_ID){
            mImageCursor = arg1;

            if(mImageCursor.moveToFirst()){
                mImageTitle = mImageCursor.getString(mImageCursor.getColumnIndex(MediaStore.Images.Media.TITLE));
                mImageSize = mImageCursor.getString(mImageCursor.getColumnIndex(MediaStore.Images.Media.SIZE));
                mImageWidth = mThumbCursor.getString(mThumbCursor.getColumnIndex(MediaStore.Images.Thumbnails.WIDTH));
                mImageHeight = mThumbCursor.getString(mThumbCursor.getColumnIndex(MediaStore.Images.Thumbnails.HEIGHT));

                String details =    "Title:"+mImageTitle + "\n" +
                                    "Size:" + mImageSize + " Bytes " + "\n" +
                                    "Resolution:" + mImageWidth + " x " + mImageHeight ;

                /** Adding new row to the matrixcursor object */
                mMatrixCursor.addRow(new Object[]{ mThumbImageId,mThumbImageData, details });

                /** Taking the next thumbnail */
                if(mThumbCursor.moveToNext()){

                    mThumbImageId = mThumbCursor.getString(mThumbCursor.getColumnIndex(MediaStore.Images.Thumbnails._ID));
                    mThumbImageData = mThumbCursor.getString(mThumbCursor.getColumnIndex(MediaStore.Images.Thumbnails.DATA));

                    String image_id = mThumbCursor.getString(mThumbCursor.getColumnIndex(MediaStore.Images.Thumbnails.IMAGE_ID));
                    Bundle data = new Bundle();
                    data.putString("image_id", image_id);

                    /** Restarting the image loader to get the next image details */
                    getSupportLoaderManager().restartLoader(IMAGE_LOADER_ID, data, this);

                }else{ /** No more thumbnails exists */
                    if(mThumbCursor.isAfterLast())
                        mAdapter.swapCursor(mMatrixCursor); /** Set the thumbnails and its details in the listview */
                }
            }
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> arg0) {
        // TODO Auto-generated method stub
    }
}


10. Screenshot of the application in execution

ListView with SDCard Images and Text

Figure 5 : ListView with SDCard Images and Text


11. Download


12. 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: , , , , , , , , , ,

8 Responses to Loading ListView with SDCard Thumbnail Images and displaying its Title, Size, Width and Height by merging cursors using MatrixCursor

  1. kopler on September 23, 2013 at 7:07 pm

    Thank you George Mathew, for posting the code here. But, when I run this application, I am getting blank activity. Why?

  2. Sachindra on November 14, 2014 at 6:11 pm

    once i write permission in AndroidManifest.xml….its perfectly working

    Thanks a Ton .
    Thank you George Mathew

  3. Sachindra on November 14, 2014 at 6:29 pm

    Can you please tell me how can we get a particular folder images instead of all the images from SD card..Thans in Advance

  4. vibhuti bhatt on February 5, 2015 at 3:17 pm

    how to show main folders of SD card and Internal memory in list view
    and set click event on it?

  5. Ana on April 8, 2015 at 3:32 pm

    Thank you for this tutorial. What is getSupportLoaderManager() ?

  6. jatin on June 4, 2015 at 10:45 pm

    Hi,
    what is the maximum size of image we can show in listview through this code?
    thanks

  7. harsh on July 7, 2015 at 2:32 am

    I tried the code but it never goes in this else block

    else{ /** No more thumbnails exists */
    if(mThumbCursor.isAfterLast())
    mAdapter.swapCursor(mMatrixCursor); /** Set the thumbnails and its details in the listview */
    }

  8. safari on April 23, 2016 at 4:15 pm

    am doing an application where the user loads the image from the memory card and itemclick by a different user ,the user is given the options comment,like and buy.How can I get to achieve this

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