Tag Archives: gallery

Android custom image gallery – part 2 – Add capture button and update gallery


This is the squeal of my previous post to create custom image gallery.

In this post, I added a button to capture new image, and update default gallery.

main.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="fill_parent">
	<LinearLayout android:id="@+id/customGalleryFooter"
		android:layout_width="fill_parent" android:layout_height="wrap_content"
		android:orientation="horizontal" android:gravity="center"
		android:layout_alignParentBottom="true">
		<Button android:id="@+id/captureBtn" android:layout_width="wrap_content"
			android:layout_height="wrap_content" android:text="Capture"
			android:minWidth="200px" />
		<Button android:id="@+id/selectBtn" android:layout_width="wrap_content"
			android:layout_height="wrap_content" android:text="Select"
			android:minWidth="200px" />
	</LinearLayout>
	<GridView android:id="@+id/PhoneImageGrid"
		android:layout_width="fill_parent" android:layout_height="fill_parent"
		android:numColumns="auto_fit" android:verticalSpacing="10dp"
		android:horizontalSpacing="10dp" android:columnWidth="90dp"
		android:stretchMode="columnWidth" android:gravity="center"
		android:layout_above="@id/customGalleryFooter" />
</RelativeLayout>

AndroidCustomGalleryActivity.java

package com.isummation.customgallery;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;

public class AndroidCustomGalleryActivity extends Activity {
	public ImageAdapter imageAdapter;
	private final static int TAKE_IMAGE = 1;
	private Uri imageUri;
	private MediaScannerConnection mScanner;
	public GridView imagegrid;
	private long lastId;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		imageAdapter = new ImageAdapter();
		imageAdapter.initialize();
		imagegrid = (GridView) findViewById(R.id.PhoneImageGrid);
		imagegrid.setAdapter(imageAdapter);

		final Button selectBtn = (Button) findViewById(R.id.selectBtn);
		selectBtn.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				final int len = imageAdapter.images.size();
				int cnt = 0;
				String selectImages = "";
				for (int i = 0; i < len; i++) {
					if (imageAdapter.images.get(i).selection) {
						cnt++;
						selectImages = selectImages
								+ imageAdapter.images.get(i).id + ",";
					}
				}
				if (cnt == 0) {
					Toast.makeText(getApplicationContext(),
							"Please select at least one image",
							Toast.LENGTH_LONG).show();
				} else {
					selectImages = selectImages + "-1";
					Intent intent = new Intent(getApplicationContext(),
							UploadQueue.class);
					intent.putExtra("Ids", selectImages);
					startActivityForResult(intent, 2);
				}
				
			}
		});
		final Button captureBtn = (Button) findViewById(R.id.captureBtn);
		captureBtn.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
				String fileName = "IMG_" + sdf.format(new Date()) + ".jpg";
				File myDirectory = new File(Environment
						.getExternalStorageDirectory() + "/REOAllegiance/");
				myDirectory.mkdirs();
				File file = new File(myDirectory, fileName);
				imageUri = Uri.fromFile(file);
				Intent intent = new Intent(
						android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
				intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
				startActivityForResult(intent, TAKE_IMAGE);
			}
		});
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (resultCode) {
		case RESULT_OK:
			try {
				// we need to update the gallery by starting MediaSanner service.
				mScanner = new MediaScannerConnection(
						AndroidCustomGalleryActivity.this,
						new MediaScannerConnection.MediaScannerConnectionClient() {
							public void onMediaScannerConnected() {
								mScanner.scanFile(imageUri.getPath(), null /* mimeType */);
							}

							public void onScanCompleted(String path, Uri uri) {
								//we can use the uri, to get the newly added image, but it will return path to full sized image
								//e.g. content://media/external/images/media/7
								//we can also update this path by replacing media by thumbnail to get the thumbnail
								//because thumbnail path would be like content://media/external/images/thumbnail/7
								//But the thumbnail is created after some delay by Android OS
								//So you may not get the thumbnail. This is why I started new UI thread
								//and it'll only run after the current thread completed.
								if (path.equals(imageUri.getPath())) {
									mScanner.disconnect();
									//we need to create new UI thread because, we can't update our mail thread from here
									//Both the thread will run one by one, see documentation of android  
									AndroidCustomGalleryActivity.this
											.runOnUiThread(new Runnable() {
												public void run() {
													updateUI();
												}
											});
								}
							}
						});
				mScanner.connect();

			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public void updateUI() {
		imageAdapter.checkForNewImages();
	}

	public class ImageAdapter extends BaseAdapter {
		private LayoutInflater mInflater;
		public ArrayList<ImageItem> images = new ArrayList<ImageItem>();

		public ImageAdapter() {
			mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}

		public void initialize() {
			images.clear();
			final String[] columns = { MediaStore.Images.Thumbnails._ID };
			final String orderBy = MediaStore.Images.Media._ID;
			Cursor imagecursor = managedQuery(
					MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
					null, null, orderBy);
			int image_column_index = imagecursor
					.getColumnIndex(MediaStore.Images.Media._ID);
			int count = imagecursor.getCount();
			for (int i = 0; i < count; i++) {
				imagecursor.moveToPosition(i);
				int id = imagecursor.getInt(image_column_index);
				ImageItem imageItem = new ImageItem();
				imageItem.id = id;
				lastId = id;
				Log.d("l_id", ""+ id);
				imageItem.img = MediaStore.Images.Thumbnails.getThumbnail(
						getApplicationContext().getContentResolver(), id,
						MediaStore.Images.Thumbnails.MICRO_KIND, null);
				images.add(imageItem);
			}
			imagecursor.close();
			notifyDataSetChanged();
		}
		
		public void checkForNewImages(){
			//Here we'll only check for newer images
			final String[] columns = { MediaStore.Images.Thumbnails._ID };
			final String orderBy = MediaStore.Images.Media._ID;
			Cursor imagecursor = managedQuery(
					MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
					MediaStore.Images.Media._ID + " > " + lastId , null, orderBy);
			int image_column_index = imagecursor
					.getColumnIndex(MediaStore.Images.Media._ID);
			int count = imagecursor.getCount();
			for (int i = 0; i < count; i++) {
				imagecursor.moveToPosition(i);
				int id = imagecursor.getInt(image_column_index);
				ImageItem imageItem = new ImageItem();
				imageItem.id = id;
				lastId = id;
				imageItem.img = MediaStore.Images.Thumbnails.getThumbnail(
						getApplicationContext().getContentResolver(), id,
						MediaStore.Images.Thumbnails.MICRO_KIND, null);
				imageItem.selection = true; //newly added item will be selected by default
				images.add(imageItem);
			}
			imagecursor.close();
			notifyDataSetChanged();
		}

		public int getCount() {
			return images.size();
		}

		public Object getItem(int position) {
			return position;
		}

		public long getItemId(int position) {
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder;
			if (convertView == null) {
				holder = new ViewHolder();
				convertView = mInflater.inflate(R.layout.galleryitem, null);
				holder.imageview = (ImageView) convertView
						.findViewById(R.id.thumbImage);
				holder.checkbox = (CheckBox) convertView
						.findViewById(R.id.itemCheckBox);

				convertView.setTag(holder);
			} else {
				holder = (ViewHolder) convertView.getTag();
			}
			ImageItem item = images.get(position);
			holder.checkbox.setId(item.id);
			holder.imageview.setId(item.id);
			holder.checkbox.setOnClickListener(new OnClickListener() {

				public void onClick(View v) {
					// TODO Auto-generated method stub
					CheckBox cb = (CheckBox) v;
					int id = cb.getId();
					if (images.get(id).selection) {
						cb.setChecked(false);
						images.get(id).selection = false;
					} else {
						cb.setChecked(true);
						images.get(id).selection = true;
					}
				}
			});
			holder.imageview.setOnClickListener(new OnClickListener() {

				public void onClick(View v) {
					// TODO Auto-generated method stub
					int id = v.getId();
					Intent intent = new Intent();
					intent.setAction(Intent.ACTION_VIEW);
					final String[] columns = { MediaStore.Images.Media.DATA };
					Cursor imagecursor = managedQuery(
							MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
							MediaStore.Images.Media._ID + " = " + id, null, MediaStore.Images.Media._ID);
					if (imagecursor != null && imagecursor.getCount() > 0){
						imagecursor.moveToPosition(0);
						String path = imagecursor.getString(imagecursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
						imagecursor.close();
						intent.setDataAndType(
								Uri.parse("file://" + path),
								"image/*");
						startActivityForResult(intent, 3);
					}
				}
			});
			holder.imageview.setImageBitmap(item.img);
			holder.checkbox.setChecked(item.selection);
			return convertView;
		}
	}

	class ViewHolder {
		ImageView imageview;
		CheckBox checkbox;
	}

	class ImageItem {
		boolean selection;
		int id;
		Bitmap img;
	}
	
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
	}
}

Update:
I highly recommend to do not use this code, as it is old and with some bugs. Please visit my open source project page, Where I keep updating code.

Android custom image gallery with checkbox in grid to select multiple


Some times we may require to select multiple images from gallery. So using the following method you will be able to select multiple images. Additionally it will also remove gallery app dependency.

It may not be sufficient method as I need to maintain two array in this activity, but it could vary on requirements. Please comment if you have any suggestion in code.

Main.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="fill_parent">
	<Button android:id="@+id/selectBtn"
		android:layout_width="wrap_content" android:layout_height="wrap_content"
		android:text="Select" android:layout_alignParentBottom="true"
		android:layout_centerHorizontal="true"
		android:minWidth="200px" />
	<GridView android:id="@+id/PhoneImageGrid"
		android:layout_width="fill_parent" android:layout_height="fill_parent"
		android:numColumns="auto_fit" android:verticalSpacing="10dp"
		android:horizontalSpacing="10dp" android:columnWidth="90dp"
		android:stretchMode="columnWidth" android:gravity="center"
		android:layout_above="@id/selectBtn" />
</RelativeLayout>

galleryitem.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="fill_parent">
	<ImageView android:id="@+id/thumbImage" android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:layout_centerInParent="true" />
	<CheckBox android:id="@+id/itemCheckBox" android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:layout_alignParentRight="true"
		android:layout_alignParentTop="true" />
</RelativeLayout>

AndroidCustomGalleryActivity.java

package com.isummation.customgallery;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;

public class AndroidCustomGalleryActivity extends Activity {
	private int count;
	private Bitmap[] thumbnails;
	private boolean[] thumbnailsselection;
	private String[] arrPath;
	private ImageAdapter imageAdapter;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		final String[] columns = { MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID };
		final String orderBy = MediaStore.Images.Media._ID;
		Cursor imagecursor = managedQuery(
				MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null,
				null, orderBy);
		int image_column_index = imagecursor.getColumnIndex(MediaStore.Images.Media._ID);
		this.count = imagecursor.getCount();
		this.thumbnails = new Bitmap[this.count];
		this.arrPath = new String[this.count];
		this.thumbnailsselection = new boolean[this.count];
		for (int i = 0; i < this.count; i++) {
			imagecursor.moveToPosition(i);
			int id = imagecursor.getInt(image_column_index);
			int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.DATA);
			thumbnails[i] = MediaStore.Images.Thumbnails.getThumbnail(
					getApplicationContext().getContentResolver(), id,
					MediaStore.Images.Thumbnails.MICRO_KIND, null);
			arrPath[i]= imagecursor.getString(dataColumnIndex);
		}
		GridView imagegrid = (GridView) findViewById(R.id.PhoneImageGrid);
		imageAdapter = new ImageAdapter();
		imagegrid.setAdapter(imageAdapter);
		imagecursor.close();

		final Button selectBtn = (Button) findViewById(R.id.selectBtn);
		selectBtn.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				// TODO Auto-generated method stub
				final int len = thumbnailsselection.length;
				int cnt = 0;
				String selectImages = "";
				for (int i =0; i<len; i++)
				{
					if (thumbnailsselection[i]){
						cnt++;
						selectImages = selectImages + arrPath[i] + "|";
					}
				}
				if (cnt == 0){
					Toast.makeText(getApplicationContext(),
							"Please select at least one image",
							Toast.LENGTH_LONG).show();
				} else {
					Toast.makeText(getApplicationContext(),
							"You've selected Total " + cnt + " image(s).",
							Toast.LENGTH_LONG).show();
					Log.d("SelectedImages", selectImages);
				}
			}
		});
	}

	public class ImageAdapter extends BaseAdapter {
		private LayoutInflater mInflater;

		public ImageAdapter() {
			mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}

		public int getCount() {
			return count;
		}

		public Object getItem(int position) {
			return position;
		}

		public long getItemId(int position) {
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder;
			if (convertView == null) {
				holder = new ViewHolder();
				convertView = mInflater.inflate(
						R.layout.galleryitem, null);
				holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
				holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);

				convertView.setTag(holder);
			}
			else {
				holder = (ViewHolder) convertView.getTag();
			}
			holder.checkbox.setId(position);
			holder.imageview.setId(position);
			holder.checkbox.setOnClickListener(new OnClickListener() {

				public void onClick(View v) {
					// TODO Auto-generated method stub
					CheckBox cb = (CheckBox) v;
					int id = cb.getId();
					if (thumbnailsselection[id]){
						cb.setChecked(false);
						thumbnailsselection[id] = false;
					} else {
						cb.setChecked(true);
						thumbnailsselection[id] = true;
					}
				}
			});
			holder.imageview.setOnClickListener(new OnClickListener() {

				public void onClick(View v) {
					// TODO Auto-generated method stub
					int id = v.getId();
					Intent intent = new Intent();
					intent.setAction(Intent.ACTION_VIEW);
					intent.setDataAndType(Uri.parse("file://" + arrPath[id]), "image/*");
					startActivity(intent);
				}
			});
			holder.imageview.setImageBitmap(thumbnails[position]);
			holder.checkbox.setChecked(thumbnailsselection[position]);
			holder.id = position;
			return convertView;
		}
	}
	class ViewHolder {
		ImageView imageview;
		CheckBox checkbox;
		int id;
	}
}

Download full source code:
Download

Update: need more features? see my open source project
Update: Please remove code that closes cursor. As this will not work in Android 4.0 and newer.

https://vikaskanani.wordpress.com/android-custom-gallery-and-instant-upload-project/

 

 

 

 

Create File Explorer in BlackBerry PhoneGap project


Hi,

I am using PhoneGap + jQuery Mobile for my current project.
It was required to upload images from gallery.

Unfortunately, In BlackBerry we can’t open built in Gallery to pick an image. So though why not to provide my file explorer? What worked pretty well.

As I am using PhoneGap, you can also use the same code for Android and may be for WebOS. In iOS it may not work.

Your index.html file:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> 
<title>File Explorer</title>
<script src="javascript/phonegap.min.js" type="text/javascript"></script>
<link rel="stylesheet" href="stylesheet/jquery.mobile.min.css" />
<script src="javascript/jquery.min.js"></script>
<script src="javascript/jquery.mobile.min.js"></script>
<script src="javascript/source.js"></script>
</head>
<body>
	<div data-role="page" id="FileExplorerPage">
		<div data-role="header" data-position="fixed">
			<h1>
				File Explorer
			</h1>
		</div>
		<div data-role="content">
			<div id="Explorer" style="float:left"></div>
		</div>
	</div>
</body>
</html>

And you JavaScript magic code:

/**
 * File explorer logic
 */
var currentPath = "file:///store";
$('#FileExplorerPage').live('pagebeforeshow', function(event) {
	populate(currentPath);
});
function populate(path){
	try {
		var dirEntry = new DirectoryEntry({fullPath: path});
		var directoryReader = dirEntry.createReader();
		directoryReader.readEntries(successDirectoryReader,failDirectoryReader);
	} catch (e) {
		alert(dump(e));
	}
}
function successDirectoryReader(entries) {
    var i;
    $("#Explorer").html('');
    for (i=0; i<entries.length; i++) {
        if (entries[i].isDirectory) {
        	$("#Explorer").append("<div style='width:104px;float:left;text-align:center;'><div><img src='local:///resources/folder.png' style='border:2px;' onclick='changePath(this)'/></div><div style='width:100px;word-wrap:break-word;'>" + entries[i].name + "</div></div>");
        } else {
        	var fileType = blackberry.io.file.getFileProperties(entries[i].fullPath).mimeType;
        	if (Left(fileType,5) == 'image') {
        		// if file is of type image, then show in small size
        		$("#Explorer").append("<div style='width:104px;float:left;text-align:center;'><div><img src='" + entries[i].fullPath + "' height='80px' width='80px' style='border:2px;' /></div><div  style='width:100px;word-wrap:break-word;'>" + entries[i].name + "</div></div>");
        	} else {
        		$("#Explorer").append("<div style='width:104px;float:left;text-align:center;'><div><img src='local:///resources/file.png' style='border:2px;' /></div><div>" + entries[i].name + "</div></div>");
        	}
        }
    }
    // add an option to go to parent directory
    if (currentPath != "file:///store") {
    	$("#Explorer").append("<div style='width:104px;float:left;text-align:center;'><div><img src='local:///resources/folder.png' style='border:2px;' onclick='backPath()'/></div><div style='width:100px;word-wrap:break-word;'>..</div></div>");
    }
}
function failDirectoryReader(error) {
    alert("Failed to list directory contents: " + error.code);
}
function backPath() {
	currentPath = Left(currentPath, currentPath.lastIndexOf('/'));
	populate(currentPath); 
}
function changePath(ele){
	currentPath = currentPath + "/" + $(ele).parent().next().html();
	populate(currentPath);
}

//Error dump function
function dump(arr,level) {
    var dumped_text = "";
    if(!level) level = 0;

    var level_padding = "";
    for(var j=0;j<level+1;j++) level_padding += "    ";

    if(typeof(arr) == 'object') {  
        for(var item in arr) {
            var value = arr[item];

            if(typeof(value) == 'object') { 
                dumped_text += level_padding + "'" + item + "' ...\n";
                dumped_text += dump(value,level+1);
            } else {
                dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
            }
        }
    } else { 
        dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
    }
    return dumped_text;
}

//String left function
function Left(str, n){
	if (n <= 0)
	    return "";
	else if (n > String(str).length)
	    return str;
	else
	    return String(str).substring(0,n);
}

Download full project from here

Android: Web image, photo, picture gallery


Hi.

Recently I’ve created web image gallery for my application. That took much of the time when I test it under various condition. Each time I need to improve my code. So that finally I decided to post my work.

It is easy to show images from phone, but to display images from web (or from url), you need to take care of downloading images to your application, image size, image exist or not etc..

Consider that your server contains two type of images, one is original and second is thumbnail.

e.g.

Thumbnail: th_3BC52DAA-AFD8-50B5-DA5096B82422275F.jpg

Original: 3BC52DAA-AFD8-50B5-DA5096B82422275F.jpg

All the images are in /upload directory.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent" android:layout_height="fill_parent"	android:orientation="vertical">
	<Gallery xmlns:android="http://schemas.android.com/apk/res/android"
		android:id="@+id/Gallery" android:layout_width="fill_parent"
		android:layout_height="wrap_content" />
	<ImageView android:id="@+id/GalleryView"
		android:layout_width="fill_parent" android:layout_height="wrap_content" />
</LinearLayout>

MyGallery.java

package com.isummation.igallery;

import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.Toast;
public class MyGallery extends Activity {

	private ImageAdapter imageAdapter;

	private ArrayList PhotoURLS = new ArrayList();
	private ProgressDialog dialog;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		imageAdapter = new ImageAdapter(this);
		final ImageView imgView = (ImageView) findViewById(R.id.GalleryView);
		Gallery g = (Gallery) findViewById(R.id.Gallery);
		g.setAdapter(imageAdapter);
		g.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView parent, View v,
					int position, long id) {
				dialog = ProgressDialog.show(ImageGallery.this, "Loading",
						"Please wait...", true);
				new ShowImageTask().execute(position);
			}
		});

		// replace this code to set your image urls in list
		PhotoURLS.add("http://10.0.2.2/upload/3BC52DAA-AFD8-50B5-DA5096B82422275F.jpg");
		PhotoURLS.add("http://10.0.2.2/upload/B652F78D-C760-B674-7A6E61E505A05A0F.jpg");

		new AddImageTask().execute();

	}

	class ShowImageTask extends AsyncTask {
		@Override
		protected Drawable doInBackground(Integer... position) {
			Drawable drawable = LoadImageFromURL(PhotoURLS.get(position[0]));
			return drawable;
		}

		@Override
		protected void onProgressUpdate(Void... unsued) {

		}

		@Override
		protected void onPostExecute(Drawable drawable) {
			imgView.setImageDrawable(drawable);
			imgView.setScaleType(ImageView.ScaleType.FIT_CENTER);
			dialog.dismiss();
		}
	}

	class AddImageTask extends AsyncTask<Void, Void, Void> {
		@Override
		protected Void doInBackground(Void... unused) {
			for (String url : PhotoURLS) {
				String filename = url.substring(url.lastIndexOf("/") + 1,
						url.length());
				filename = "th_" + filename;
				String thumburl = url.substring(0, url.lastIndexOf("/") + 1);
				imageAdapter.addItem(LoadThumbnailFromURL(thumburl + filename));
				publishProgress();
				//SystemClock.sleep(200);
			}

			return (null);
		}

		@Override
		protected void onProgressUpdate(Void... unused) {
			imageAdapter.notifyDataSetChanged();
		}

		@Override
		protected void onPostExecute(Void unused) {
		}
	}

	private Drawable LoadThumbnailFromURL(String url) {
		try {
			URLConnection connection = new URL(url).openConnection();
			String contentType = connection.getHeaderField("Content-Type");
			boolean isImage = contentType.startsWith("image/");
			if(isImage){
				HttpGet httpRequest = new HttpGet(url);
				HttpClient httpclient = new DefaultHttpClient();
				HttpResponse response = (HttpResponse) httpclient
						.execute(httpRequest);
				HttpEntity entity = response.getEntity();
				BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(entity);

				InputStream is = bufferedHttpEntity.getContent();
				Drawable d = Drawable.createFromStream(is, "src Name");
				return d;
			} else {
				Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.no_image);
				Drawable d = new BitmapDrawable(b);
				return d;
			}
		} catch (Exception e) {
			Toast.makeText(getApplicationContext(), "error", Toast.LENGTH_LONG)
					.show();
			Log.e(e.getClass().getName(), e.getMessage(), e);
			return null;
		}
	}

	private Drawable LoadImageFromURL(String url) {
		try {
			URLConnection connection = new URL(url).openConnection();
			String contentType = connection.getHeaderField("Content-Type");
			boolean isImage = contentType.startsWith("image/");
			if(isImage){
				HttpGet httpRequest = new HttpGet(url);
				HttpClient httpclient = new DefaultHttpClient();
				HttpResponse response = (HttpResponse) httpclient
						.execute(httpRequest);
				HttpEntity entity = response.getEntity();
				BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(
						entity);
				InputStream is = bufferedHttpEntity.getContent();

				// Decode image size
				BitmapFactory.Options o = new BitmapFactory.Options();
				o.inJustDecodeBounds = true;
				BitmapFactory.decodeStream(is, null, o);

				// The new size we want to scale to
				final int REQUIRED_SIZE = 150;

				// Find the correct scale value. It should be the power of 2.
				int width_tmp = o.outWidth, height_tmp = o.outHeight;
				int scale = 1;
				while (true) {
					if (width_tmp / 2 &lt; REQUIRED_SIZE
							|| height_tmp / 2 &lt; REQUIRED_SIZE)
						break;
					width_tmp /= 2;
					height_tmp /= 2;
					scale *= 2;
				}

				// Decode with inSampleSize
				is = bufferedHttpEntity.getContent();
				BitmapFactory.Options o2 = new BitmapFactory.Options();
				o2.inSampleSize = scale;
				Bitmap b = BitmapFactory.decodeStream(is, null, o2);
				Drawable d = new BitmapDrawable(b);
				return d;
			} else {
				Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.no_image);
				Drawable d = new BitmapDrawable(b);
				return d;
			}
		} catch (Exception e) {
			Toast.makeText(getApplicationContext(), "error", Toast.LENGTH_LONG)
					.show();
			Log.e(e.getClass().getName(), e.getMessage(), e);
			return null;
		}
	}

	public class ImageAdapter extends BaseAdapter {
		int mGalleryItemBackground;
		private Context mContext;

		ArrayList drawablesFromUrl = new ArrayList();

		public ImageAdapter(Context c) {
			mContext = c;
			TypedArray a = obtainStyledAttributes(R.styleable.GalleryTheme);
			mGalleryItemBackground = a.getResourceId(
					R.styleable.GalleryTheme_android_galleryItemBackground, 0);
			a.recycle();
		}

		public void addItem(Drawable item) {
			drawablesFromUrl.add(item);
		}

		public int getCount() {
			return drawablesFromUrl.size();
		}

		public Drawable getItem(int position) {
			return drawablesFromUrl.get(position);
		}

		public long getItemId(int position) {
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			ImageView i = new ImageView(mContext);

			i.setImageDrawable(drawablesFromUrl.get(position));
			i.setLayoutParams(new Gallery.LayoutParams(80, 70));
			i.setScaleType(ImageView.ScaleType.FIT_CENTER);
			i.setBackgroundResource(mGalleryItemBackground);

			return i;
		}
	}

}

Also /res/values/attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="GalleryTheme">
        <attr name="android:galleryItemBackground" />
    </declare-styleable>
</resources>

Dont forget to add permission in AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"/>

Also add this image to Drawable:

Note: Some code is taken from Stackoverflow.com and Androidpeople.com

Update:

Download source code: Download