Custom Hyperlink Control for Android

I developed a custom control to mimic the Hyperlink behavior as Android doesn’t have a built-in/native Hyperlink Control.

Implementation

public class CustomHyperlink extends TextView {

    private int mDefaultColor = Color.BLACK;
    private int mPressedColor = Color.GREEN;

    //region #Constructors

    public CustomHyperlink(Context context) {
        super(context);

        this.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE)
                    setTextColor(mPressedColor);
                if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_OUTSIDE
                        || event.getAction() == MotionEvent.ACTION_CANCEL) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                    setTextColor(mDefaultColor);
                }
                return false;
            }
        });
    }

    public CustomHyperlink(Context context, AttributeSet attrs) {
        super(context, attrs);
        setCustomAttrValues(context, attrs);

        this.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE)
                    setTextColor(mPressedColor);
                if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_OUTSIDE
                        || event.getAction() == MotionEvent.ACTION_CANCEL) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                    setTextColor(mDefaultColor);
                }
                return false;
            }
        });
    }

    public CustomHyperlink(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setCustomAttrValues(context, attrs);

        this.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE)
                    setTextColor(mPressedColor);
                if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_OUTSIDE
                        || event.getAction() == MotionEvent.ACTION_CANCEL) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                    setTextColor(mDefaultColor);
                }
                return false;
            }
        });
    }

    //endregion

    //region #Getters, Setters

    public int getDefaultColor() {
        return mDefaultColor;
    }

    public void setDefaultColor(int defaultColor) {
        this.mDefaultColor = defaultColor;
    }

    public int getPressedColor() {
        return mPressedColor;
    }

    public void setPressedColor(int pressedColor) {
        this.mPressedColor = pressedColor;
    }

    //endregion

    //region #Methods

    public void setLinkText(String value) {
        if (MetrixStringHelper.isNullOrEmpty(value)) return;

        SpannableString content = new SpannableString(value);
        content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
        setText(content);

        setTextColor(mDefaultColor);j
    }

    public void setLinkText(String value, int start, int end) throws Exception {
        if (MetrixStringHelper.isNullOrEmpty(value)) return;

        if (end > value.length())
            throw new Exception(AndroidResourceHelper.getMessage("EndValIsGreaterThan"));

        SpannableString content = new SpannableString(value);
        content.setSpan(new UnderlineSpan(), start, end, 0);
        setText(content);

        setTextColor(mDefaultColor);
    }

    public String getLinkText() {
        return this.getText().toString();
    }

    private void setCustomAttrValues(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomHyperlinkAttr);
		if (typedArray != null) {
			//region #setLinkText
			String s = typedArray.getString(R.styleable.CustomHyperlinkAttr_linkText);
			if (!MetrixStringHelper.isNullOrEmpty(s))
				setLinkText(s);
			//endregion
		}
    }

    //endregion
}

I hope you have some basic understanding about the android custom attributes. You can declare your own attributes in a xml file such as attrs.xml and it can be placed inside res\values\ folder.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomHyperlinkAttr">
        <attr name="linkText" format="string"></attr>
    </declare-styleable>
</resources>

Usage (Inside a XML layout)


<com.architecture.utilities.MetrixHyperlink
ndroid:id="@+id/web_url"
attr:linkText="www.abc.com"
android:gravity="center_horizontal"/>

Don’t forget to add the following line into the top most layout.
xmlns:attr=”http://schemas.android.com/apk/res-auto&#8221;

Ex:


<?xml version="1.0" encoding="utf-8"?> <LinearLayout style="@style/LinearBase.Normal.Vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns="http://schemas.android.com/tools"
xmlns:attr="http://schemas.android.com/apk/res-auto">

Usage (Inside a Class)


CustomHyperlink webUrlHyperLink = (CustomHyperlink) findViewById(R.id.web_url);
webUrlHyperLink.setLinkText("www.xyz.com");

Happy coding…. 🙂

Forcing newly entered characters to be in UPPERCASE in a TextBox

For Windows Store Apps(Windows 8.1 & Windows Phone 8.1)


///
<summary>
/// Identify whether the pressed key is a Letter(Ex: a, B..)
/// </summary>

/// <param name="sender"></param>
/// <param name="e"></param>
static void textBox_KeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
{
	int keyValue = (int)e.Key;
	if (keyValue >= 0x41 && keyValue <= 0x5A)
		isLetter = true;
}

///
<summary>
/// Identify whether a text PASTE is happened.
/// </summary>

/// <param name="sender"></param>
/// <param name="e"></param>
static void textBox_Paste(object sender, TextControlPasteEventArgs e)
{
	var textBox = sender as TextBox;
	startingLocation = textBox.SelectionStart;
	pasteOccurred = true;
}

///
<summary>
/// Change the newly entered character's case to upper case / a set of characters (Ex: text Paste)
/// </summary>

/// <param name="sender"></param>
/// <param name="e"></param>
static void textBox_TextChanged(object sender, TextChangedEventArgs e)
{
	var textBox = sender as TextBox;
	var newText = textBox.Text;
	int currentPosition = textBox.SelectionStart;

	#region text paste

	if (pasteOccurred)
	{
		string newCharacters = newText.Substring(startingLocation, (currentPosition-startingLocation));
		newText = newText.Remove(startingLocation, newCharacters.Length).Insert(startingLocation, newCharacters.ToUpper());
		textBox.Text = newText;
		textBox.SelectionStart = currentPosition;

		pasteOccurred = false;
		startingLocation = -1;

		return;
	}

	#endregion

	if (!isLetter) return;

	currentPosition = textBox.SelectionStart - 1;
	if (currentPosition < 0) return; 	if (Char.IsLower(newText, currentPosition)) 	{ 		string newCharacter = newText.Substring(currentPosition, 1); 		newText = newText.Remove(currentPosition, 1).Insert(currentPosition, newCharacter.ToUpper()); 		textBox.Text = newText; 		textBox.SelectionStart = currentPosition + 1; 	} 	isLetter = false; } 

For Android(TextWatcher implementation)

 final EditText editText = (EditText) view; //new region force -> uppercase implementation
final TextWatcher textWatcher = new TextWatcher() {
	boolean shouldContinue = true;

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count, int after) {
		//To avoid executing of text change listener -> onTextChanged when the time of data binding..
		shouldContinue = editText.hasFocus() ? true : false;
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		if(!shouldContinue)return;

		int curCursorLoc = editText.getSelectionEnd();
		if(curCursorLoc < 1) return;

		CharSequence charSet = s.subSequence(start, (start + count));
		if(charSet != null) {
			String upperStr = charSet.toString().toUpperCase();
			StringBuilder stringBuilder = new StringBuilder(s);
			stringBuilder.replace(start, (start + count), upperStr);
			editText.setText(stringBuilder.toString());
			editText.setSelection(curCursorLoc);
		}
	}

	@Override
	public void afterTextChanged(Editable s) {
	}
};

editText.addTextChangedListener(textWatcher);
//endregion

For iOS (iPhone or iPad)


- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    BOOL shouldChange;
    NSRange lowercaseCharRange;
	lowercaseCharRange = [string rangeOfCharacterFromSet:[NSCharacterSet lowercaseLetterCharacterSet]];

	if (lowercaseCharRange.location != NSNotFound) {
		textField.text = [textField.text stringByReplacingCharactersInRange:range
																 withString:[string uppercaseString]];
		UITextPosition *newCursorPosition = [textField positionFromPosition:textField.beginningOfDocument inDirection:UITextLayoutDirectionRight offset:(range.location + 1)];
		UITextRange *newCursorRange = [textField textRangeFromPosition:newCursorPosition toPosition:newCursorPosition];
		[textField setSelectedTextRange:newCursorRange];
		shouldChange = NO;
	}
	else
		shouldChange = YES;

    return shouldChange;
}

Dealing with EMFILE(Too many open files) & OOM(OutOfMemory) Exceptions in Android

Today I’m going to write about some of the issues I faced while developing an Image Gallery with caching techniques, efficient bitmap loading and what tactics that I’ve taken to overcome the issues.

I have developed a custom image gallery with the use of android GridView. Key requirement was to load large amount of images with limited time. In addition the user should be able to smoothly scroll up-down the gallery control.

In order to accomplish this, I have used caching techniques like LruCache, scale down the images before loading (low memory consumption) and loading the images asynchronously (with the use of AsyncTask).

I experienced the above mentioned EMFILE(Too many open files) exception while I was testing this. At this time there were 50-100 images were loaded into the Image Gallery and I was scrolling up and down for around 10-20 times.

EMFILE(Too many open files)

This was happening due a limitation in Android(We can say this is an inherited behavior of Linux). The reason behind this is Android limits the max open files per process to 1024. So this can be experienced in a scenario like Image Gallery with large amount of files, unless we carefully handle the file processing techniques.

But finally got a clue.

It was the process of scaling down the images. It had few FileInputStream objects which were not closed after consuming.

protected static Bitmap decodeFile(File imageFile, int requiredHeight, int requiredWidth) throws Exception {

	// Decode image size
	BitmapFactory.Options oSize = new BitmapFactory.Options();

	oSize.inJustDecodeBounds = true;
	oSize.inDither = false;
	oSize.inPurgeable = true;
	oSize.inInputShareable = true;

	//FileInputStream is used, but it's not closing after consuming...
	BitmapFactory.decodeStream(new FileInputStream(imageFile), null, oSize);

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

	// Decode with inSampleSize
	BitmapFactory.Options oPreview = new BitmapFactory.Options();
	oPreview.inSampleSize = scale;
	oPreview.inDither = false;
	oPreview.inPurgeable = true;
	oPreview.inJustDecodeBounds = false;
	oPreview.inInputShareable = true;

	//FileInputStream is used, but it's not closing after consuming...
	return BitmapFactory.decodeStream(new FileInputStream(imageFile), null, oPreview);

}

Following is the modified version of the code block, and I was able to get rid of EMFILE(Too many open files) exception.


protected static Bitmap decodeFile(File imageFile, int requiredHeight, int requiredWidth) throws Exception {

	FileInputStream fileInputStreamIn = null;
	FileInputStream fileInputStreamOut = null;
	
	try{
		// Decode image size
		BitmapFactory.Options oSize = new BitmapFactory.Options();
		
		oSize.inJustDecodeBounds = true;
		oSize.inDither = false;
		oSize.inPurgeable = true;
		oSize.inInputShareable = true;
		
		fileInputStreamIn = new FileInputStream(imageFile);
		BitmapFactory.decodeStream(fileInputStreamIn, null, oSize);

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

		// Decode with inSampleSize
		BitmapFactory.Options oPreview = new BitmapFactory.Options();
		oPreview.inSampleSize = scale;
		oPreview.inDither = false;
		oPreview.inPurgeable = true;
		oPreview.inJustDecodeBounds = false;
		oPreview.inInputShareable = true;
		
		fileInputStreamOut = new FileInputStream(imageFile);
		return BitmapFactory.decodeStream(fileInputStreamOut, null, oPreview);
	}
	finally{
		//Got rid of EMFILE Exception(Too many file open)
		if(fileInputStreamIn != null)
			fileInputStreamIn.close();
		if(fileInputStreamOut != null)
			fileInputStreamOut.close();
	}

}

OOM(OutOfMemory)

The application got crashed, soon after I left the screen which had the Image Gallery. This was due to OOM Exception. This issue was also bit tricky, since there was no straight forward way of identifying the reason behind this. The Image Gallery (Custom GridView) Adapter was fully enhanced to reuse the views (using of ViewHolder pattern which Android has suggested), so I thought this wasn’t causing the error. Then my eyes turned into the implementation of LruCache. There was a slight mistake in LruCache, because when the time of initializing it I have used a fixed size for it.

So, DON’T DO THIS,


mMemoryCache = new LruCache<String, Bitmap>(30)

because what Android has suggested is, set the size of LruCache dynamically depending of the available memory.


final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

final int cacheSize = maxMemory / 8;

mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
	@Override
	protected int sizeOf(String key, Bitmap bitmap) {
		return (bitmap.getRowBytes() * bitmap.getHeight()) / 1024;
	}
};

With the help of above modification, I was able to get rid of the OOM Exception.

Happy Coding…. 🙂

Creating a workable Android 5.0 (Lollipop) Emulator

At the beginning I was struggling while setup and running a Android Lollipop emulator. So I thought putting all the steps into one place and sharing it in a simpler manner.

This was fully tested in Windows 7 (64 bit) environment with Eclipse JUNO Version: 4.2.1.

1. Please make sure that you have the latest Android SDK Tools and Android SDK Platform-tools. If not please update them to the latest version.

2

2. Install necessary components of Android 5.0(API21). For the moment, I didn’t install the components related to Android TV.

4

3. Make sure that you have installed Android SDK Build-tools -> Rev. 21.

3

3. Make sure that you have the latest component of Android Support Library & Google Play services.

5

4. You must install Intel x86 Emulator Accelerator(HAXM installer). Don’t use the Android SDK Manager for installing that.

6

Because at the moment the SDK Manager gives you HAMX installer version 1.1.0. But to build up Android Lollipop emulator, it requires the latest version of HAMX which is 1.1.1. This can be found in the following link Intel x86 Emulator Accelerator(HAMX installer)

5. Next go and build the Android Lollipop emulator.

6. I have selected Nexus 5 as the device.

11

7. When you are creating the Android Lollipop emulator(AVD) make sure to select Android 5.0-API Level 21 as the Target.

7

If you select Google APIs – API Level 21, you might get a warning even if you have installed Google APIs Intel Atom(x86) system image.

Warning

8. For CPU/ABI, I have chosen Google APIs Intel Atom(x86_64).

8

9. Make sure that you have selected Use Host GPU option rather than Snapshot in Emulation Options. Otherwise when the emulator starts you will see nothing but a black blank screen only.

9

Finally you are ready to go. Start your newly created Android Lollipop emulator(AVD) from the AVD list.

12

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>

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

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