Tuesday, 20 September 2011

Two ListViews Side by Side in Android

The following XML shows how to place two ListViews side by side, add some seperator views and button bars for any actions needed.
Even though fragment now make the creation and maintenance this type of layout much easier, simple application might benefit from this without having to include the compatibility library.

The result will look like this:


(The layout file is after the break)

Monday, 19 September 2011

Getting a Bitmap out of a Zip file in Android (or Java in general)

The following function will extract an image from a zip file stored anywhere on the filesystem (for as long as the application has access to it).

It will return a bitmap object if the image is found or null otherwise. This function should work in pure java as well with minor alterations (replacing the Log calls with system.outs).


public Bitmap getBtimapFromZip(final String zipFilePath, final String imageFileInZip){
	Log.d(TAG, "Getting image '" + imageFileInZip + "' from '" + zipFilePath +"'");
	Bitmap result = null;
	try {
		FileInputStream fis = new FileInputStream(zipFilePath);
		ZipInputStream zis = new ZipInputStream(fis);
		ZipEntry ze = null;
		while ((ze = zis.getNextEntry()) != null) {
			if (ze.getName().equals(imageFileInZip)) {
				result = BitmapFactory.decodeStream(zis);
				break;
			}
		}
	} catch (FileNotFoundException e) {
		Log.e(Constants.TAG, "Extracting file: Error opening zip file - FileNotFoundException: ", e);
		e.printStackTrace();
	} catch (IOException e) {
		Log.e(Constants.TAG, "Extracting file: Error opening zip file - IOException: ", e);
		e.printStackTrace();
	}
	return result;
}

If you you use a wrapper function like this:
private void loadImage(ImageButton button, String image){
	// Use this drawable by default
	Drawable d = context.getResources().getDrawable(R.drawable.no_image);
	Bitmap b = getBtimapFromZip("path_to_zip_file", image);
	
	if(b != null){ // if the bitmap is not null, load that instead.
		d = new BitmapDrawable(b);
	}
	
	button.setImageDrawable(d);
}

you can have a fallback drawable to display if something goes wrong (the above bit is Android specific).

A few things to keep in mind:
  1. To get the image out of the zip file you are scanning through all records in the archive sequentially. This could be a performance hit if you have many images. 
  2. If the function returns null but you know that the image is in there, check that you havent accidentally archived the top directory along with the images when creating the zip.