Generic Parcelable Implementation

Today I’m going to post you about a generic implementation of Parcelable interface in Android.

Implementation


import android.os.Parcel;
import android.os.Parcelable;

public class GenericParcelable<T> implements Parcelable {

	private T mValue;
	private static ClassLoader mClassLoader;

	@Override
	public int describeContents() {
		return 0;
	}

	@Override
	public void writeToParcel(Parcel parcelOut, int flags) {
        parcelOut.writeValue(mValue);
    }

    @SuppressWarnings("rawtypes")
	public static final Parcelable.Creator<GenericParcelable> CREATOR = new Parcelable.Creator<GenericParcelable>() {

        public GenericParcelable createFromParcel(Parcel in) {
            return new GenericParcelable(in);
        }

        public GenericParcelable[] newArray(int size) {
            return new GenericParcelable[size];
        }
    };

    public GenericParcelable(T value){
    	this.mValue = value;
    	if(this.mValue != null)
    		GenericParcelable.mClassLoader = value.getClass().getClassLoader();
    } 

	@SuppressWarnings("unchecked")
	private GenericParcelable(Parcel parcelIn) {
    	try{
            //reading the passed value
    		mValue = (T)parcelIn.readValue(GenericParcelable.mClassLoader);
    	}
    	catch(Exception e){
    		e.printStackTrace();
    	}
    }

    //generic method of obtaining the parcel value
	public T getValue(){
		return (T) mValue;
    }

}

Usage

This is the way of adding a value to Parcelable object in an Activity class.


Intent intent = new Intent(this, NextActivity.class);
//Create the Parcelable object with an int value
intent.putExtra("myKey", new GenericParcelable<Integer>(15));
startActivity(intent);

Obtaining the value in a different Activity.

int passedValue;
GenericParcelable<Integer> genericParcelable = getIntent().getParcelableExtra("myKey");
if (genericParcelable != null){
   passedValue = genericParcelable .getValue();
}

Happy coding ūüôā

Unexpected behavior of text color transparency in Android 4.0.4

Came across an unexpected behavior when setting the text color of a Check box while developing an android application. Actually the text color which is transparent color was set in the XML layout like below.

<CheckBox
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/text_state"
    android:textColor="#00000000">
</CheckBox>

The code above worked as expected in Android 2.3.4, 4.1.2. But the transparency trick didn’t work in Android 4.0.4. But when I refer this color via the resource file, it worked in all versions including 4.0.4

Ex:

<CheckBox
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/text_state"
    android:textColor="@color/my_transparent">
</CheckBox>

Walkthrough for Installing the Team Foundation Server Plug-in for Eclipse

Even though I have experienced in using Tortoise-SVN, I’m a newbie for Team Foundation Server which provides by Microsoft. At the moment I am involved in an Android Project and for that I have to use TFS as the Version Controller and Eclipse as my IDE.

Here is one of the best walkthrough which describes how to install & configure TFS Plugin-in for Eclipse.

Note: I’m using the latest Eclipse IDE(Build: v22.3.0-887826) which provided via Windows ADT Bundle.

Visual Studio 2012 Premium + Team Foundation Server Error When Comparing Files + “Cannot load the configured tool..”

I’m a newbie to Team Foundation Server source control. I came across an issue few days back while I was using it. When I tried to compare a file, I got the below shown error.vfs

 

 

 

 

In my Office-PC, I had Windows 7 Enterprise 64x Edition(Service Pack 1), and Visual Studio 2012 Premium Edition(not with the latest update). After spending sometime on the net, I found out that for comparing feature Team Foundation Server uses a file called “vsDiffMerge.exe“.If it was there, the location for the path would be

  • 64bit – “C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE
  • 32bit – “C:\Program Files\Microsoft Visual Studio 11.0\Common7\IDE

But later I found out that, “vsDiffMerge.exe” was not in the specified location.

The solution was to install the latest Update for VS2012(Update 3/4). http://www.microsoft.com/en-us/download/details.aspx?id=39305

After that All Is Well. File comparing feature will work smoothly.

 

Developing a Simple Google Map Application in Android [debug/release modes] (Android 4.0, Google Play Service, Google Maps Android API v2)

Today I’m going to post about an android application which uses Google Maps. I’m going to use Google Maps Android API v2(since Google Maps Android API v1 is deprecated) and it is not easy to use as Google Maps Android API v1. The steps which you have to follow is mentioned below.

Remember, please don’t waste time try running this application with an Emulator. I have seen many people tried run these types of application with an Emulator, but most of the time it has failed.

My Development Environment

Samsung S2(GT-I9100) with Android version 4.0.3(which was upgraded from Android 2.0+). Also this is quite important, I had the latest Google Play Service installed in it.

If you have this kind of environment I guaranteed that the application will run smoothly.

Because of Google Maps Android API v2, is strongly connected with Google Play Service library, you need to download it first. You can easily do it using the Android SDK Manager.

Play

Once it is downloaded you can find a folder called google-play-services_lib. It will be available in your Android-SDK -> Extras -> Google -> google_play_services -> libproject folder.
Ex: C:\Program Files (x86)\Android\android-sdk\extras\google\google_play_services\libproject\google-play-services_lib

Import it as an android project to your Eclipse environment/your workspace.

project-import

Once the project is imported, we can start implementing our Android Map Application.

First you have to create an Android Project, in my case I set the target Platform into Android 4.0 & API Level 14. My project name was Rakimap and the package name was com.rakimap. The Activity name was MainActivity, which is added by default.

Then what you have to do is you have to reference the google-play-services_lib project which you have imported earlier.

import-play

Then it comes to the most easiest but trickiest part of the project, In order to you the Google Map API Services you have to obtain a key. Whether you are in the debug environment or release environment you have to use a key in order to use the facilities of this API. So here’s how you do it.

Debug Environment

You need to use the debug.keystore file, if you are using Eclipse IDE you will be able to find it under Users -> <current-user-name> -> .android folder. Ex: C:\Users\rawilk\.android

The open the command prompt and navigate to you jdk-version\bin folder (Ex: C:\Program Files (x86)\Java\jdk1.5.0\bin), where you can find the keytool.exe. In there you have to execute this command.

keytool.exe -list -v -keystore “<file path>\debug.keystore” -alias androiddebugkey -storepass android -keypass android

debug key

Once it is executed it will response back with set of lines.

debug key-sha

There you can find two types of certificate fingerprints and you have to copy the SHA1 value for later usage.

Then you should visit this link Google Api Console. As I prefer the new Google Cloud API Console, you will be seen a page like this once you logged-in. You have to go to APIs section which is under APIs & auth. In there if the Google Maps Android API v2 status is OFF, turn it ON.

google-api-console

Once it’s done move to the Credentials section. In there click the Create new Key button.

google-api-console-new-key

Once you click it a popup dialog will be opened. There you press the button named as Android key.

google-api-console-new-key-android

Once you click it you will be seen another pop-up screen which asks the SHA1 value which you have copied earlier. Once you put it, then enter a semi-colon and then enter the name of the package as it is in the project. (This is the package which contains the Activity which will be used for displaying the Google Map later in this). In my case it was com.rakimap.

google-api-console-new-key-android-sha

Once you click the Create button you will be able to get the API key. Copy it and keep it somewhere because we are going to use it later in the project that you have created.

Finally here we go with the blank activity which you created earlier. Let’s make it really simple. Here’s how the MainActivity class would be.

package com.rakimap;

import android.app.Activity;
import android.os.Bundle;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends Activity {

	static final LatLng COLOMBO = new LatLng(6.927, 79.861);
	private GoogleMap map;

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

		map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
				.getMap();

		Marker markerColombo = map.addMarker(new MarkerOptions().position(
				COLOMBO).title("Hamburg"));

		// Move the camera to Colombo area with the zoom level of 20.
		map.moveCamera(CameraUpdateFactory.newLatLngZoom(COLOMBO, 20));

		// Animating the camera while zooming.
		map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
	}

}

Make the layout file like this. In my case it was the 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"
    tools:context=".MainActivity" >

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.MapFragment" />

</RelativeLayout>

Here’s how the AndroidManifest.xml is going to be.

You have to put the obtained Google API Key inside a meta-data tag block, as well as set some additional user permissions as below mentioned.  Also remember to use the correct package name where necessary.
Ex: com.rakimap.permission.MAPS_RECEIVE

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.rakimap"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="14" />

    <permission
        android:name="com.rakimap.permission.MAPS_RECEIVE"
        android:protectionLevel="signature" />

    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />

    <uses-permission android:name="com.rakimap.permission.MAPS_RECEIVE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.rakimap.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="AIzaSyAb8-sm4w3X9SXAHFCDhFdDZkayPfLjgiw" />
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

    </application>

</manifest>

Once this is done, try building the project to rectify any compile time errors. If there are no errors, plug-in your android device(I hope you have the per-requisites knowledge of how to handle an android device in development environment) and try deploying it.

You will be seen this if All Is Well.

Screenshot_2014-01-10-10-53-55

Release Environment

When it comes to release the application as an APK, obtaining of the Google API Key will same, but you need to create a separate key-store for this.(you won’t automatically get a key-store like debug.keystore).

Open command prompt and navigate to the location of keytool.exe. Once you there you have to execute the below command in order to create the private key which you will be used in exporting the android application.

keytool.exe -genkey -v -keystore “<path of the release key to be stored>\<name of the file>” -alias <release key alias name> -keyalg RSA -keysize 2048 -validity 10000

Ex: keytool.exe -genkey -v -keystore “C:\RakiMap\raki-release.keystore” -alias raki-release-key -keyalg¬†¬†¬† RSA -keysize 2048 -validity 10000

release-key1

Once you execute this, you will be asked a series of questions which you need to be answered. Answering for some of the questions are not needed. Refer the below shown image to get an idea.

release-key2

If the key generation is successful(please locate where it resides), you can follow the same steps to obtain a new Google API Key for release mode. Before that you need to get the SHA1 value for the newly generated key. To do that execute the below command.

keytool.exe -list -v -keystore “<path of the release key to be stored>\<name of the file>”

Ex: keytool.exe -list -v -keystore “C:\RakiMap\raki-release.keystore”

release-key3

So once you obtain the new Google API Key for release mode, you have to modify the AndroidManifest.xml file.

Then you can rebuild the program and you are ready to export the application for releasing. I hope you know the initial steps of exporting the android application when it comes to the Keystore selection dialog, you have to set the newly generated keystore file and use the same password which you used when building the key.

release1

Once you press next you will be seen a dialog like this. There you have to select the alias name which you have given when you building the key. Use the same password as well.

release2

After that it is pretty straightforward, you have to set a path to generate the APK file. Once the APK file is generated try installing it in the device. If All Is Well you will be seen this again.

Screenshot_2014-01-10-10-53-55

CRUD Operations in SQLite Database using ORMLite with Dependency Injection(Android, SQLite, ORMLite 4.47, RoboGuice 2.0)

Today I’m going to post about data manipulation in Android environment. My implementation consisted with techniques like Object Relational Mapping and Dependency Injection. Detail configuration and using of these two technologies as follows.

ORMLite

ORMLite is a very Lightweight Java ORM which is compatible with Android and SQLite database. You can read more about it on ORMLite Home Page.

Before using this, you have to download these two files and add it into your libs folder.

  1. ormlite.com/releases/4.47/ormlite-core-4.47.jar
  2. ormlite.com/releases/4.47/ormlite-android-4.47.jar

RoboGuice

RoboGuice is a framework which supports Dependency Injection in Android development environment. Read more about this on code.google.com/p/roboguice/

Before using this, download these files and add them into your libs folder.

  1. http://repo1.maven.org/maven2/org/roboguice/roboguice/2.0/roboguice-2.0.jar
  2. http://repo1.maven.org/maven2/com/google/inject/guice/3.0/guice-3.0-no_aop.jar
  3. http://repo1.maven.org/maven2/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar

Include javax.inject.jar into your libs folder too. File can be found in http://code.google.com/p/atinject/downloads/detail?name=javax.inject.zip

RoboGuice configuration

In-order to up and running RoboGuice and make use of dependency injection, you have to make use of the AbstractModule class. Here is the implementation.

AbstractModule

public class BaseModule extends AbstractModule {

	@Override
	protected void configure() {
        //binding will be placed here.....
	}

}

Add file called roboguice.xml to res/values folder.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="roboguice_modules">
    	<item>com.androidrobo.BaseModule</item>
    </string-array>
</resources>

com.androidrobo was the package where BaseModule class was resided.

ORMLite configuration, database and table creation

Here is my Product class for ORMLite table, field mapping, etc.

@DatabaseTable(tableName = "Product")
public class Product implements Serializable{

	private static final long serialVersionUID = 1L;

	// this is the primary key column which is not automatically generated
	@DatabaseField(columnName = "Id", id = true, generatedId = false, canBeNull = false)
	private String code;

	@DatabaseField(columnName = "Description", canBeNull = false)
	private String description;

	@DatabaseField(columnName = "Price", canBeNull = false)
	private double price;

	@DatabaseField(columnName = "Qty")
	private int qty;

	public void setCode(String code) {
		this.code = code;
	}

	public String getCode() {
		return code;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getDescription() {
		return description;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public double getPrice() {
		return price;
	}

	public void setQty(int qty) {
		this.qty = qty;
	}

	public int getQty() {
		return qty;
	}
}

Here is the initial database creation helper class. There you can see a static class called TableUtils which was used for table creation with mapping classes.

public class DbHelper extends OrmLiteSqliteOpenHelper {

	private final static String DATABASENAME = "Main.db";
	private final static int DATABASEVERSION = 4;

	@Inject
	public DbHelper(Context context) {
		super(context, DATABASENAME, null, DATABASEVERSION);
	}

	@Override
	public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) {
		try {
			TableUtils.createTableIfNotExists(connectionSource, Product.class);
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource,
			int oldVersion, int newVersion) {
	}

}

Extended Application class can be used for initial database creation.
Note: Application class is the first starting point of the application.

Ex:

public class InitApp extends Application {

	@Override
	public void onCreate() {

		super.onCreate();
		//initial database creation..
		new DbHelper(getApplicationContext()).getWritableDatabase();

	}
}

Above section concludes, the database creation with relevant table.

Here is how the CRUD Operations were performed using ProductRepo. In-order to perform CRUD Operations we have to use a Data Access Object(Dao) for each entity(Product) which is provided by ORMLite. So here how it was implemented. DaoManager is a static class which is used for getting the Dao Object.

public class ProductDaoProvider implements Provider<Dao<Product, String>> {

	private ConnectionSource connectionSource;

	@Inject
	public ProductDaoProvider(DbHelper dbHelper) {
		connectionSource = dbHelper.getConnectionSource();
	}

	@Override
	public Dao<Product, String> get() {
		try {
			return DaoManager.createDao(connectionSource, Product.class);
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
}

Here is the IProductRepo interface which used to construct concrete ProductRepo class.

public interface IProductRepo {

	public List GetProducts() throws SQLException;
	public Product GetProduct(String id) throws SQLException;
	public void DeleteProduct(Product deleteProduct) throws SQLException;
	public void SaveProduct(Product saveProduct) throws SQLException;
	public void UpdateProduct(Product updateProduct) throws SQLException;

}

Implementation of ProductRepo class as follows.

public class ProductRepo implements IProductRepo {

	private Dao<Product, String> _productDao;

	@Inject
	public ProductRepo(Context context, ProductDaoProvider productDaoProvider) {
		_productDao = productDaoProvider.get();
	}

	@Override
	public List GetProducts() throws SQLException {
		return _productDao.queryForAll();
	}

	@Override
	public Product GetProduct(String id) throws SQLException {
		return _productDao.queryForId(id);
	}

	@Override
	public void DeleteProduct(Product deleteProduct) throws SQLException {
		_productDao.delete(deleteProduct);
	}

	@Override
	public void SaveProduct(Product deleteProduct) throws SQLException {
		_productDao.create(deleteProduct);
	}

	@Override
	public void UpdateProduct(Product updateProduct) throws SQLException {
		_productDao.update(updateProduct);
	}
}

Implementation of ProductRepo binding was done by modifying configure method in BaseModule class.

public class BaseModule extends AbstractModule {

	@Override
	protected void configure() {
		bind(IProductRepo.class).to(ProductRepo.class);
	}
}

Finally, I’m going to show how to perform the CRUD Operations in Activities.

1. Implementation of Product List Activity.

Layout : product_list_row.xml

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/black"
    android:padding="10dp" >

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent" >

        <TextView
            android:id="@+id/listProductId"
            android:layout_width="0px"
            android:layout_height="wrap_content"
            android:layout_weight=".3"
            android:gravity="left"
            android:height="20dip"
            android:textColor="@android:color/white">
        </TextView>

        <TextView
            android:id="@+id/listProductDescription"
            android:layout_width="0px"
            android:layout_height="wrap_content"
            android:layout_weight=".7"
            android:gravity="left"
            android:textColor="@android:color/white">
        </TextView>

    </TableRow>

    <TableRow
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent" >

        <TextView
            android:id="@+id/listProductPrice"
            android:layout_width="0px"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="left"
            android:textColor="@android:color/white">
        </TextView>

    </TableRow>

</TableLayout>

Adapter : ProducListAdapter

public class ProducListAdapter extends BaseAdapter {

	private List _productList;
	private Context _context;

	public ProducListAdapter(Context context, List products) {
		_context = context;
		_productList = products;
	}

	static class ViewHolder {
		protected TextView textViewProductId, textViewProductDescription,
				textViewProductPrice;
	}

	@Override
	public View getView(final int position, View convertView, ViewGroup parent) {

		ViewHolder holder = null;
		LayoutInflater inflater = LayoutInflater.from(_context);

		if (convertView == null) {

			convertView = inflater.inflate(R.layout.product_list_row, null);
			holder = new ViewHolder();

			holder.textViewProductId = (TextView) convertView
					.findViewById(R.id.listProductId);
			holder.textViewProductDescription = (TextView) convertView
					.findViewById(R.id.listProductDescription);
			holder.textViewProductPrice = (TextView) convertView
					.findViewById(R.id.listProductPrice);

			convertView.setTag(holder);

		} else {
			holder = (ViewHolder) convertView.getTag();
		}

		Product product = _productList.get(position);

		if (product != null) {

			try {

				holder.textViewProductId.setText(String.format(_context
						.getString(R.string.list_product_code_format,
								product.getCode())));
				holder.textViewProductDescription.setText(String
						.format(_context.getString(
								R.string.list_product_description_format,
								product.getDescription())));
				holder.textViewProductPrice.setText(String.format(_context
						.getString(R.string.list_product_price_format,
								String.valueOf(product.getPrice()))));

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

		}

		return convertView;
	}

	@Override
	public int getCount() {
		return _productList.size();
	}

	@Override
	public Object getItem(int pos) {
		return _productList.get(pos);
	}

	@Override
	public long getItemId(int pos) {
		return pos;
	}
}

Layout : product_list.xml

<?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" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight=".9" >

        <ListView
            android:id="@+id/listviewProduct"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:clickable="true"
            android:fastScrollEnabled="true"
            android:scrollingCache="true"
            android:textFilterEnabled="true" >
        </ListView>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_weight=".1"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <Button
            android:id="@+id/buttonProductAdd"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:text="@string/productbutton_add_label" />
    </LinearLayout>

</LinearLayout>

Activity : ProductListActivity

@ContentView(R.layout.product_list)
public class ProductListActivity extends RoboActivity {

	@Inject
	private IProductRepo _productRepo;

	@InjectView(R.id.listviewProduct)
	private ListView _listViewProduct;

	@InjectView(R.id.buttonProductAdd)
	private Button _buttonProductAdd;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		try {

			List products = _productRepo.GetProducts();
			ProducListAdapter producListAdapter = new ProducListAdapter(
					getApplicationContext(), products);
			_listViewProduct.setAdapter(producListAdapter);

			_buttonProductAdd.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {

					Intent intent = new Intent(ProductListActivity.this,
							ProductEditActivity.class);
					intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					startActivityForResult(intent, 0);
					finish();

				}
			});

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

}

Note: used RoboActivity as the base class instead of Activity class.

2. Implementation of Product Edit Activity.

Layout : product_edit.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/labelProductId"
            android:layout_width="0px"
            android:layout_weight="2"
            android:layout_height="wrap_content"
            android:text="@string/productid_label" />

        <EditText
            android:id="@+id/editTextProductId"
            android:layout_weight="8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/labelProductName"
            android:layout_width="0px"
            android:layout_weight="2"
            android:layout_height="wrap_content"
            android:text="@string/productname_label" />

        <EditText
            android:id="@+id/editTextProductName"
            android:layout_weight="8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/labelProductPrice"
            android:layout_width="0px"
            android:layout_weight="2"
            android:layout_height="wrap_content"
            android:text="@string/productprice_label" />

        <EditText
            android:id="@+id/editTextProductPrice"
            android:layout_weight="8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/labelProductQuantity"
            android:layout_width="0px"
            android:layout_weight="2"
            android:layout_height="wrap_content"
            android:text="@string/productqty_label" />

        <EditText
            android:id="@+id/editTextProductQty"
            android:layout_weight="8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/buttonProductSave"
            android:layout_width="0px"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="@string/productbutton_save_label" />

        <Button
            android:id="@+id/buttonProductDelete"
            android:layout_width="0px"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="@string/productbutton_delete_label" />

    </LinearLayout>

</LinearLayout>

Activity : ProductEditActivity

@ContentView(R.layout.product_edit)
public class ProductEditActivity extends RoboActivity {

	@Inject
	private IProductRepo _productRepo;

	@InjectView(R.id.editTextProductId)
	private EditText _editTextProductCode;

	@InjectView(R.id.editTextProductName)
	private EditText _editTextProductDescription;

	@InjectView(R.id.editTextProductPrice)
	private EditText _editTextProductPrice;

	@InjectView(R.id.editTextProductQty)
	private EditText _editTextProductQty;

	@InjectView(R.id.buttonProductSave)
	private Button _buttonProductSave;

	@InjectView(R.id.buttonProductDelete)
	private Button _buttonProductDelete;

	private Product _selectedProduct;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		_selectedProduct = (Product) (getIntent()
				.getSerializableExtra("Product"));
		loadSelectedProduct(_selectedProduct);

		_buttonProductSave.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				try {

					if (_selectedProduct == null) {

						Product product = new Product();

						product.setCode(_editTextProductCode.getText()
								.toString());

						product.setDescription(_editTextProductDescription
								.getText().toString());
						product.setPrice(Double
								.parseDouble(_editTextProductPrice.getText()
										.toString()));
						product.setQty(Integer.parseInt(_editTextProductQty
								.getText().toString()));

						_productRepo.SaveProduct(product);

					} else {

						_selectedProduct
								.setDescription(_editTextProductDescription
										.getText().toString());
						_selectedProduct.setPrice(Double
								.parseDouble(_editTextProductPrice.getText()
										.toString()));
						_selectedProduct.setQty(Integer
								.parseInt(_editTextProductQty.getText()
										.toString()));

						_productRepo.UpdateProduct(_selectedProduct);

					}

					Intent intent = new Intent(ProductEditActivity.this,
							ProductListActivity.class);
					intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					startActivityForResult(intent, 0);
					finish();

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

			}
		});

		_buttonProductDelete.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {

				if (_selectedProduct != null) {

					try {

						_productRepo.DeleteProduct(_selectedProduct);
						Intent intent = new Intent(ProductEditActivity.this,
								ProductListActivity.class);
						intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
						startActivityForResult(intent, 0);
						finish();

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

			}
		});
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	private void loadSelectedProduct(Product selectedProduct) {

		if (selectedProduct != null) {

			_editTextProductCode.setText(selectedProduct.getCode());
			_editTextProductCode.setEnabled(false);

			_editTextProductDescription.setText(selectedProduct
					.getDescription());
			_editTextProductPrice.setText(String.valueOf(selectedProduct
					.getPrice()));
			_editTextProductQty
					.setText(String.valueOf(selectedProduct.getQty()));
		}

	}

}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.androidrobo"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="12" />

    <application
        android:allowBackup="true"
        android:name="InitApp"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.androidrobo.ProductListActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.androidrobo.ProductEditActivity" >
        </activity>
    </application>

</manifest>

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">AndroidRobo</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>

    <string name="productid_label">Code</string>
    <string name="productname_label">Description</string>
    <string name="productprice_label">Price</string>
    <string name="productqty_label">Quantity</string>

    <string name="productbutton_save_label">Save</string>
    <string name="productbutton_delete_label">Delete</string>
    <string name="productbutton_add_label">New</string>

    <string formatted="false" name="list_product_code_format">Code %s</string>
	<string formatted="false" name="list_product_description_format">Name %s</string>
    <string formatted="false" name="list_product_price_format">Price %s</string>

</resources>

Screen-shots

Product List

list
Add New Product

new

Edit/Delete Product

edit-delete

Save image file content to Database with resizing (EF 4.1, SQLServer 2008 R2, MVC4)

File uploading is a very common task in nowadays specially with web applications. Normally what we do is we save the uploading files in the server-side. Recently, I have developed a software component which can be used to save images directly to a database table field(even with re-sizing if needed). For this module, I have used Entity Framework, Sql Server 2008 R2 and MVC4. How it has been achieved is described below.

Table – Content

table

Content table contains two fields FileName, FileContent and FIleType, which are nvarchar(64), varbinary(MAX) and nvarchar(64) respectively. The file contain was stored in FileContent field.

Entity Class – Content

public class Content : EntityBase
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Uid { get; set; }

    [StringLength(64)]
    [Display(Name = "File Name")]
    [Required]
    public string FileName { get; set; }

    [Required]
    public byte[] FileContent { get; set; }

    [StringLength(64)]
    [Display(Name = "File Type")]
    [Required]
    public string FileType { get; set; }

}

Entity Map – ContentMap

public class ContentMap : EntityTypeConfiguration<Entity.FileContent.Content>
{
    public ContentMap()
    {
        ToTable("Content");
        HasKey(t => t.Uid);
    }
}

Helper Class РImageHelper 

I have implemented ToByteArray method as an extension method for HttpPostedFileBase. As this described if the image dimension is not meet your desired height or width it will be re-sized and stored.
public static class ImageHelper
{
    /// <summary>
    /// Checking whether the image needs to be resized
    /// </summary>
    /// <param name="uploadImage"></param>
    /// <param name="height"></param>
    /// <param name="width"></param>
    /// <returns>true or false depending on the size</returns>
    private static bool IsResizeNeeded(Image uploadImage, int height, int width)
    {
        var originalWidth = uploadImage.Width;
        var originalHeight = uploadImage.Height;
        return (originalHeight != height) || (originalWidth != width);
    }

    /// <summary>
    /// Resize the image depending on the size given
    /// </summary>
    /// <param name="uploadImage"></param>
    /// <param name="height"></param>
    /// <param name="width"></param>
    /// <returns></returns>
    private static Image ResizeBySize(Image uploadImage, int height, int width)
    {
        var originalWidth = uploadImage.Width;
        var originalHeight = uploadImage.Height;

        var modifiedHeight = height;
        var modifiedWidth = width;

        var bitmap = new Bitmap(modifiedWidth, modifiedHeight,
                                 PixelFormat.Format32bppPArgb);
        bitmap.SetResolution(uploadImage.HorizontalResolution, uploadImage.VerticalResolution);

        var graphics = Graphics.FromImage(bitmap);
        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

        graphics.DrawImage(uploadImage,
                          new Rectangle(0, 0, modifiedWidth, modifiedHeight),
                          new Rectangle(0, 0, originalWidth, originalHeight),
                          GraphicsUnit.Pixel);

        graphics.Dispose();

        return bitmap;
    }

    /// <summary>
    /// Since we need the ImageFormat inorder to convert Image -> MemoryStream
    /// </summary>
    /// <param name="imageType"></param>
    /// <returns>ImageFormat according to the image type(Ex: jpg, jpeg etc.)</returns>
    private static ImageFormat GetImageFormat(string imageType)
    {
        ImageFormat imageFormat;
        switch (imageType)
        {
            case "image/jpg":
                imageFormat = ImageFormat.Jpeg;
                break;
            case "image/jpeg":
                imageFormat = ImageFormat.Jpeg;
                break;
            case "image/pjpeg":
                imageFormat = ImageFormat.Jpeg;
                break;
            case "image/gif":
                imageFormat = ImageFormat.Gif;
                break;
            case "image/png":
                imageFormat = ImageFormat.Png;
                break;
            case "image/x-png":
                imageFormat = ImageFormat.Png;
                break;
            default:
                throw new Exception("Unsupported image type !");
        }

        return imageFormat;
    }

    /// <summary>
    /// Convert files to byte array(Special function added for images which needs to be resized)
    /// </summary>
    /// <param name="fileUpLoad"></param>
    /// <returns>byte array of the image file</returns>
    public static byte[] ToByteArray(this HttpPostedFileBase fileUpLoad)
    {
        byte[] byteArray;

        if (IsImage(fileUpLoad))
        {
            //getting the height and width of the image to be uploaded
            var theHeight = Int32.Parse(WebConfigurationManager.AppSettings["UploadImageHeight"]);
            var theWidth = Int32.Parse(WebConfigurationManager.AppSettings["UploadImageWidth"]);

            //converting to a bitmap
            var uploadImage = new Bitmap(fileUpLoad.InputStream);

            //checking whether resize is needed
            if (IsResizeNeeded(uploadImage, theHeight, theWidth))
            {
                //resizing the image
                var resizedImage = ResizeBySize(uploadImage, theHeight, theWidth);
                //getting the image format(not the type)
                var resizedImageFormat = GetImageFormat(fileUpLoad.ContentType);

                using (resizedImage)
                {
                    using (var memoryStream = new MemoryStream())
                    {
                        //loading it to the memory stream
                        if (resizedImageFormat != null)
                        {
                            resizedImage.Save(memoryStream, resizedImageFormat);
                        }
                        memoryStream.Position = 0;
                        byteArray = memoryStream.ToArray();
                    }
                }
            }
            else
            {
                byteArray = ByteArrayConvertion(fileUpLoad);
            }
        }
        // for non-image files
        else
        {
            byteArray = ByteArrayConvertion(fileUpLoad);
        }

        return byteArray;
    }

    /// <summary>
    /// Default byte array creation
    /// </summary>
    /// <param name="fileUpload"></param>
    /// <returns>byte array</returns>
    private static byte[] ByteArrayConvertion(HttpPostedFileBase fileUpload)
    {
        byte[] byteArray;

        using (fileUpload.InputStream)
        {
            using (var memoryStream = new MemoryStream())
            {
                fileUpload.InputStream.CopyTo(memoryStream);
                byteArray = memoryStream.ToArray();
            }
        }
        return byteArray;
    }

    /// <summary>
    /// Checking the file is an image....
    /// </summary>
    /// <param name="fileUpload"></param>
    /// <returns>True if the file is an image</returns>
    /// http://yassershaikh.com/how-to-check-if-an-uploaded-file-is-an-image-or-not-in-asp-net-mvc-3/
    private static bool IsImage(HttpPostedFileBase fileUpload)
    {
        if (fileUpload.ContentType.Contains("image"))
        {
            return true;
        }

        var formats = new string[] { ".jpg", ".png", ".gif", ".jpeg" }; // add more if u like...

        // linq from Henrik Stenbæk
        return formats.Any(item => fileUpload.FileName.EndsWith(item, StringComparison.OrdinalIgnoreCase));
    }
}
Note: If you are hoping to store non-image files in DB, still it can be accomplished using ToByteArray extension method.
View
@using (Html.BeginForm("Upload", "ContentFile", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <input type="file" name="FileUpload" />
    <input type="submit" name="Submit" id="Submit" value="Upload" />
}
Controller – ContentFileController
I have used the extension method ToByteArray with the width and height parameters which obtained by web.config.
[HttpPost]
public ActionResult Upload(FileUploadModel fileUploadModel)
{
    HttpPostedFileBase file = Request.Files[0];

    if (file != null && file.ContentLength > 0)
    {
        //creating the content entity using repository
        Content fileUpload = _fileContentRepository.Create();
        fileUpload.FileName = Path.GetFileName(file.FileName);

        var extension = Path.GetExtension(file.FileName);
        if (extension != null)
            fileUpload.FileType = extension.TrimStart('.');

        //getting the height and width of the image to be uploaded
        var theHeight = Int32.Parse(WebConfigurationManager.AppSettings["UploadImageHeight"]);
        var theWidth = Int32.Parse(WebConfigurationManager.AppSettings["UploadImageWidth"]);

        fileUpload.FileContent = file.ToByteArray(theHeight, theWidth);

        _fileContentRepository.SaveOrUpdate(fileUpload);
        _unitOfWork.Commit();

    }

    var uploadedFiles = _fileContentRepository.GetAll();
    ViewData["UploadedFiles"] = uploadedFiles;

    return View(fileUploadModel);
}
View – Uploaded Files
@using DinotaMSM.Entity.FileContent
@using MvcContrib.UI.Grid
@using TekMVC.Models
@model FileUploadModel
@{
    ViewBag.Title = "Upload";
}

<div>
    @if (Model != null)
    {
        Html.Grid((IEnumerable<Content>) ViewData["UploadedFiles"])
            .Columns(column =>
                         {
                             column.For(c => @Html.ActionLink(c.Uid.ToString(), "GetFile", new {uid = c.Uid})).Named("ID");
                             column.For(c => c.FileName);
                             column.For(c => "<img src=" + string.Format("data:image/{0};base64,{1}", c.FileType, Convert.ToBase64String(c.FileContent)) + ">").Encode(false);
                         }).Render();
    }
</div>
Output
output

Binding WebGrid to Dynamic Collection (XML, SQL Server 2008 R2, dynamic, ExpandoObject, MVC 3, WebGrid)

Recently I have experienced with some of the new features (I guess these components are rarely used) of C# 4.0 such the dynamic type, ExpandoObject. My initial requirement was to build a dynamically created object collection out of XML formatted SQL result. Then it has to be used as a data-source for my grid.

Note: The select statement was dynamically generated and the result were vary from one query to another. My intent was to generate the data-source (list of objects) without using a well-structured mapping-class. With the use of ExpandoObject I was able to generate an object in run-time with dynamic properties.

SQL Query which return a XML formatted result

sql-query

XML Formatted result

query-result

For ease of explanation purpose I have copied the XML result to a XML file called “SQLResult1.xml”.

Helper Class – DynamicXmlConverter

public class XmlDynamicParser
{
    /// <summary>
    /// returns a List<dynamic> generated by xml datasource
    /// </summary>
    /// <param name="descendantName"></param>
    /// <param name="filePath"></param>
    /// <returns>List<dynamic></returns>
    public static List<dynamic> GenerateGridDataSource(string descendantName, string filePath)
    {
        //initialize list of dynamic objects
        var dataList = new List<dynamic>();

        //xml-string
        var doc = XDocument.Load(filePath);

        //selecting all the Descendats of Ex: "Result"
        var descendants = doc.Descendants(descendantName);

        //loop through each Descendats
        foreach (var descendant in descendants)
        {
            //creatingthe ExpandoObject
            dynamic expandoObject = new ExpandoObject();

            //casting it to a dictionary object
            var dictionaryExpandoObject = (IDictionary<string, object>)expandoObject;

            //loop through each elements of descendant
            foreach (var element in descendant.Elements())
            {
                //assiging of element name as propertyName
                string propertyName = element.Name.LocalName;

                //adding the property name and value to the dictionary
                dictionaryExpandoObject.Add(propertyName, element.Value);
            }

            //finally add each ExpandoObject to list
            dataList.Add(dictionaryExpandoObject);

        }

        return dataList;
    }
}

Controller ‚Äď HomeController

[Authorize]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult LoadGrid()
    {
        var dataList = XmlDynamicParser.GenerateGridDataSource("Result", Server.MapPath("SQLResult1.xml"));
        return View(dataList);
    }
}

View – Load Grid

@{
    ViewBag.Title = "Load Grid";
}
@using System.Collections
@model IEnumerable
@{
    var grid = new WebGrid((IEnumerable<dynamic>)Model, canPage: true, rowsPerPage: 5);
}
@grid.GetHtml()

Output

grid

Accessing WCF Service via Android (WCF, EF 4.1, SQLServer 2008 R2, Android, Gson)

Recent past as an R&D Project I was working on a prototype basis Shopping cart application (assuming that the end-users are always in a connected environment-WiFi/3G) which has no local database so that it had to interact with WCF Service for data-manipulation.

WCF Service, data handling section was developed using Entity Framework(Code First approach). There were several modules like Item, Category, Order etc. Among those I picked Item module for further explanation.

Entity Class – Item

public class Item
{
	public string Id { get; set; }

	public string Name { get; set; }

	public string Url { get; set; }

	public int InStock { get; set; }

	public decimal Price { get; set; }
}

Entity Map ‚Äď ItemMap

public class ItemMap : EntityTypeConfiguration<Item>
{
	public ItemMap()
	{
		ToTable("tbl_Item");
		HasKey(item => item.Id);
	}
}

Repository – ItemRepo

public class ItemRepo
{
    protected IDbSet<Item> ItemSet;
    protected DataContext Context;

    public ItemRepo(DataContext dataContext)
    {
        Context = dataContext;
        ItemSet = dataContext.Set<Item>();
    }

    public List<Item> GetItems(string from, string to)
    {
        IEnumerable<Item> items = (from a in ItemSet
                                   select a).OrderBy(a => a.Id).Skip(Convert.ToInt32(from)).Take(Convert.ToInt32(to));

        return items.ToList();
    }
}

WCF Service Method

[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class Html5Service
{
    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json)]
    public List<Item> GetItems(string From, string To)
    {
        var itemRepo = new ItemRepo(new DataContext());
        return itemRepo.GetItems(Convert.ToInt32(From), Convert.ToInt32(To));
    }
}

Client(Android) side implementation was as follows.

You have to access the WCF Service with a similar function like below. I have used a third party library called gson-1.7.1(not the latest one), which can be downloaded from the below link.
download google-gson

Item-Mapping [since my mapping properties had the same name with compared to the json result item list, i have not used the SerializedName annotation]

Class – Item

public class Item{

	private String Id;
	private String Name;
	private String Url;
	private int InStock;
	private Double Price;

	public String getId() {
		return Id;
	}
	public void setId(String id) {
		Id = url;
	}

	public String getName() {
		return Name;
	}
	public void setName(String name) {
		Name = name;
	}

	public String getUrl() {
		return Url;
	}
	public void setUrl(String url) {
		Url = url;
	}

	public int getInStock() {
		return InStock;
	}
	public void setInStock(int inStock) {
		InStock = inStock;
	}

	public Double getPrice() {
		return Price;
	}
	public void setPrice(Double price) {
		Price = price;
	}
}

WCF Service call

public List<Item> getItems(String from, String to) {

	List<Item> items = null;
	Gson gson = new Gson();

	try {

		String urlWithParam = String.format("http://app.dinotait.com/Items/HTML5Service.svc/GetItems?From=%s&To=%s",from, to);

		HttpGet request = new HttpGet(urlWithParam);

		request.setHeader("Accept", "application/json");
		request.setHeader("Content-type", "application/json");

		DefaultHttpClient httpClient = new DefaultHttpClient();
		HttpResponse response = httpClient.execute(request);

		HttpEntity responseEntity = response.getEntity();

		// Read response data into buffer
		char[] buffer = new char[(int) responseEntity.getContentLength()];
		InputStream stream = responseEntity.getContent();
		InputStreamReader reader = new InputStreamReader(stream);
		reader.read(buffer);
		stream.close();

		Type type = new TypeToken<List<Item>>(){}.getType();
		items = gson.fromJson(new String(buffer), type);

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

	return items;
}

Remember that you have to execute this function within an AsyncTask or similar approach since this is a network operation.

Android MapActivity cannot be resolved

While I was working in a Android Map based application, I came across that MapActivty couldn’t¬†be resolved. Since I was upgraded my SDK Tools & SDK Platform Tools to the very latest versions, I was unable to set the target of my app to Google API [desired version] as mentioned in many tutorials. Finnaly I was able to fix the issue by manually setting the Android Build Target of my project to¬†Google API(Platform 3.1, API Level 12)

Eclipse -> Select the project -> Properties -> Android -> Target Name -> tick the desired Google API level