Android : Singleton Approach

1. Create an Android Project.

2. Create a class for your application extending Application(android.app.Application). This class has single object throughout application through which we can maintain singleton database.

package com.swap.app;

import android.app.Application;

public class YourApplication extends Application {
	
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
	}
	
	@Override
	public void onTerminate() {
		// TODO Auto-generated method stub
		super.onTerminate();
	}

}

3. Create a Database Helper class by extending SQLiteOpenHelper & implement all its unimplemented methods also add constructer for it. Now create DatabaseAdapter where we can write methods for CRUD operations.

4. For handling network operations create WebServiceClient class as follows. Before that add libraries for json & http in libs folder(Find in sample project provided with this tutorial). This class contains basic authentication GET request, GET & POST requests. We just have to pass service url & hashmap for JSON.

package com.swap.client;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;

import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import android.util.Log;

import com.google.gson.JsonObject;

public class WebServiceClient {
	
	private static final int TIMEOUT_WAIT_TO_CONNECT = 30000;
	private static final int TIMEOUT_WAIT_FOR_DATA = 60000;
	private static final String tag = "WebServiceClient";
	public static String CONTENT_TYPE_FORM_ENCODED = "application/x-www-form-urlencoded";
	public static String CONTENT_TYPE_JSON = "application/json";
	public static String CONTENT_TYPE_TEXT = "Text/HTML";
  
	 private String m_BaseUri = "http://IP:PORT/TestRServer/rest";
	 private static final String SERVER_IP = "IP";   

	private static final int SERVER_PORT = 8080;

	public WebServiceClient() {

	}

	//Basic Authentication
	public String doGetLogin(String service, String userName, String password) {
		try {

			return getLoginRequest(service, userName, password,
					CONTENT_TYPE_JSON);

		} catch (ClientProtocolException cpe) {

			cpe.printStackTrace();

		} catch (IOException ioe) {
			ioe.printStackTrace();

		}
		return null;

	}

	public String doGet(String service) {
		try {

			return getRequest(service, CONTENT_TYPE_JSON);

		} catch (ClientProtocolException cpe) {

			cpe.printStackTrace();

		} catch (IOException ioe) {
			ioe.printStackTrace();

		}
		return null;

	}

	public String doPost(String service, HashMap params) {
		try {

			return postRequest(service, encodeUrl(params), CONTENT_TYPE_JSON);

		} catch (ClientProtocolException cpe) {
			cpe.printStackTrace();

		} catch (IOException ioe) {
			ioe.printStackTrace();

		}
		return null;

	}

	public String doPost(String service, JsonObject params) {
		try {

			return postRequest(service, params.toString(), CONTENT_TYPE_JSON);
		} catch (ClientProtocolException cpe) {
			cpe.printStackTrace();

		} catch (IOException ioe) {
			ioe.printStackTrace();

		}
		return null;
	}

	public String doPost(String service, String params) {
		try {

			return postRequest(service, params, CONTENT_TYPE_JSON);
		} catch (ClientProtocolException cpe) {
			cpe.printStackTrace();

		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		return null;
	}

	public String doPost(String service) {
		try {

			return postRequest(service, null, CONTENT_TYPE_JSON);
		} catch (ClientProtocolException cpe) {
			cpe.printStackTrace();

		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		return null;
	}

	public String getLoginRequest(String url, String userName, String password,
			String contentType) throws ClientProtocolException, IOException {

		String serviceUri = m_BaseUri + "/" + url;

		DefaultHttpClient client = new DefaultHttpClient();

		client.getParams().setParameter("http.socket.timeout",
				new Integer(TIMEOUT_WAIT_TO_CONNECT));
		client.getParams().setParameter("http.connection.timeout",
				new Integer(TIMEOUT_WAIT_FOR_DATA));

		HttpGet get = new HttpGet(serviceUri);

		client.getCredentialsProvider().setCredentials(
				new AuthScope(SERVER_IP, SERVER_PORT),
				new UsernamePasswordCredentials(userName, password));

		get.setHeader(HTTP.CONTENT_TYPE, contentType);

		try {
			HttpResponse response = client.execute(get);

			String responseBody = EntityUtils.toString(response.getEntity());
			System.out.println(responseBody);

			if (response.getStatusLine().getStatusCode() == 200) {

				return responseBody;
			}

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

	public String getRequest(String url, String contentType)
			throws ClientProtocolException, IOException {

		String serviceUri = m_BaseUri + "/" + url;

		Log.d("WebServiceClient", serviceUri);

		HttpClient client = new DefaultHttpClient();

		client.getParams().setParameter("http.socket.timeout",
				new Integer(TIMEOUT_WAIT_TO_CONNECT));
		client.getParams().setParameter("http.connection.timeout",
				new Integer(TIMEOUT_WAIT_FOR_DATA));

		HttpGet get = new HttpGet(serviceUri);

		get.setHeader(HTTP.CONTENT_TYPE, contentType);

		try {
			HttpResponse response = client.execute(get);

			System.out.println(response);

			String responseBody = EntityUtils.toString(response.getEntity());
			if (response.getStatusLine().getStatusCode() == 200) {
				return responseBody;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public String getRequest(String url, String params, String contentType)
			throws ClientProtocolException, IOException {

		String serviceUri = m_BaseUri + "/" + url;

		Log.d("WebServiceClient", serviceUri);

		HttpClient client = new DefaultHttpClient();

		client.getParams().setParameter("http.socket.timeout",
				new Integer(TIMEOUT_WAIT_TO_CONNECT));
		client.getParams().setParameter("http.connection.timeout",
				new Integer(TIMEOUT_WAIT_FOR_DATA));

		HttpGet get = new HttpGet(serviceUri);
		get.setHeader(HTTP.CONTENT_TYPE, contentType);

		try {
			HttpResponse response = client.execute(get);
			System.out.println(response);
			String responseBody = EntityUtils.toString(response.getEntity());
			if (response.getStatusLine().getStatusCode() == 200) {
				return responseBody;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public String postRequest(String url, String params, String contentType)
			throws ClientProtocolException, IOException {

		String serviceUri = m_BaseUri + "/" + url;

		Log.d("WebServiceClient", serviceUri);

		HttpClient client = new DefaultHttpClient();

		client.getParams().setParameter("http.socket.timeout",
				new Integer(TIMEOUT_WAIT_TO_CONNECT));
		client.getParams().setParameter("http.connection.timeout",
				new Integer(TIMEOUT_WAIT_FOR_DATA));

		HttpPost post = new HttpPost(serviceUri);
		post.setHeader(HTTP.CONTENT_TYPE, contentType);

		if (params != null) {

			post.setEntity(new StringEntity(params));
		}

		try {

			HttpResponse response = client.execute(post);
			String responseBody = EntityUtils.toString(response.getEntity());
			if (response.getStatusLine().getStatusCode() == 200) {
				return responseBody;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	public String encodeUrl(HashMap parameters) {
		if (parameters == null) {
			return "";
		}

		StringBuilder sb = new StringBuilder();
		boolean first = true;
		for (String key : parameters.keySet()) {
			if (first)
				first = false;
			else
				sb.append("&");
			sb.append(URLEncoder.encode(key) + "="
					+ URLEncoder.encode(parameters.get(key).toString()));
		}
		// System.out.println("encodeUrl:"+sb.toString());
		return sb.toString();
	}

	private HashMap decodeUrl(String s) {
		HashMap params = new HashMap();
		if (s != null) {
			String array[] = s.split("&");
			for (String parameter : array) {
				String v[] = parameter.split("=");
				params.put(URLDecoder.decode(v[0]), URLDecoder.decode(v[1]));
			}
		}
		return params;
	}

	/**
	 * Parse a URL query and fragment parameters into a key-value bundle.
	 * 
	 * @param url
	 *            the URL to parse
	 * @return a dictionary bundle of keys and values
	 */
	private HashMap parseUrl(String url) {
		// hack to prevent MalformedURLException
		url = url.replace("fbconnect", "http");
		try {
			URL u = new URL(url);
			HashMap b = decodeUrl(u.getQuery());
			b.putAll(decodeUrl(u.getRef()));
			return b;
		} catch (MalformedURLException e) {
			return new HashMap();
		}
	}

}

5. To implement those methods create another class WebServiceObjectClient. Here we are going to add our custom methods for service calls, receive response & create json from it.

6. Now create Entity classes for entities in your application. (I have created sample entity as Person).

package com.swap.entity;

public class Person {

	private String firstName;
	private String lastName;
	private int age;
	private String address;
	private String gender;
	private String nationality;
	private String occupation;
	private long income;
	private boolean isSomeBoolenProperty;

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getNationality() {
		return nationality;
	}

	public void setNationality(String nationality) {
		this.nationality = nationality;
	}

	public String getOccupation() {
		return occupation;
	}

	public void setOccupation(String occupation) {
		this.occupation = occupation;
	}

	public long getIncome() {
		return income;
	}

	public void setIncome(long income) {
		this.income = income;
	}

	public boolean isSomeBoolenProperty() {
		return isSomeBoolenProperty;
	}

	public void setSomeBoolenProperty(boolean isSomeBoolenProperty) {
		this.isSomeBoolenProperty = isSomeBoolenProperty;
	}
}

7. Here we begin with actual implementation. Lets start with database.
In DatabaseAdapter create open() & close() methods to get writable database from DatabaseHelper class.

package com.swap.database;
 
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class DatabaseAdapter {
	
	private static final String tag = "DataBaseAdapter";
	private Context context;
	private static final String DATABASE_NAME = "SampleDatabase";
	private static final int DATABASE_VERSION = 1;
	private static SQLiteDatabase db;
	private static  DatabaseHelper dataBaseHelper;
	
	public void open() {
		Log.d(tag, "Database open");

		dataBaseHelper = new DatabaseHelper(context, DATABASE_NAME, null,
				DATABASE_VERSION);

		db = dataBaseHelper.getWritableDatabase();
	} 
	
	public void close() {
		db.close();
	}

}

8. In DatabaseHelper, override onCreate method & create database tables by executing sql in onCreate method.

package com.swap.database;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHelper extends SQLiteOpenHelper{

	public DatabaseHelper(Context context, String name, CursorFactory factory,
			int version) {
		super(context, name, factory, version);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		
		db.execSQL("");
		
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub
		
	}
}

(will continue with post tomorrow …)

iOS : Simple Hand Drawing With Eraser.

This tutorial will explain you, how to create simple hand drawing in iOS.

1. Create a new project as Single View Application. Check Automatic Reference Counting.

2. Add BezierInterpView.h & BezierInterpView.m to your project. Provided with Sample Code with this tutorial.

3. BezierInterpView.h

#import 

@interface BezierInterpView : UIView

@property (nonatomic,retain)  UIImage *incrementalImage;
@property (nonatomic,retain)  UIBezierPath *path;
@property (nonatomic, retain) UIBezierPath *rectpath;
 
@property  NSInteger flag;
  
@end
   

4. BezierInterpView.m

 #import "BezierInterpView.h"
 
@implementation BezierInterpView
{ 
    CGPoint pts[4]; // to keep track of the four points of our Bezier segment
    uint ctr; // a counter variable to keep track of the point index
    
    NSInteger lineWidth;
    NSInteger eraserWidth; 
}

@synthesize incrementalImage;
@synthesize rectpath;
@synthesize path;
 
@synthesize flag;

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder])
    {
        [self setMultipleTouchEnabled:NO];
        
        lineWidth = 2.0;
        eraserWidth = 8.0;
        
        flag = 1;
         
        path = [UIBezierPath bezierPath]; 
        [path setLineWidth:lineWidth];
                 
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(eraserActived:)
                                                     name:@"eraserActived"
                                                   object:nil];
    }
    
    return self; 
}

- (void)drawRect:(CGRect)rect   
{  
    if(flag == 0){
        [[UIColor whiteColor] setStroke];
    }else{
        [[UIColor blackColor] setStroke];
    }
    
    [incrementalImage drawInRect:rect];  
    [path stroke]; 
} 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  
{
    if(flag == 0){
        [path setLineWidth:eraserWidth];
    }else{  
        [path setLineWidth:lineWidth];
    } 
    
    ctr = 0;
    UITouch *touch = [touches anyObject];
    pts[0] = [touch locationInView:self];
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{           
    UITouch *touch = [touches anyObject];
    CGPoint p = [touch locationInView:self];
    ctr++;
    pts[ctr] = p;
    if (ctr == 3) // 4th point
    {
        [path moveToPoint:pts[0]];
        [path addCurveToPoint:pts[3] controlPoint1:pts[1] controlPoint2:pts[2]]; // this is how a Bezier curve is appended to a path
        [self setNeedsDisplay];
        pts[0] = [path currentPoint];
        ctr = 0;
    }
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{     
    [self drawBitmap];
    [self setNeedsDisplay];
    pts[0] = [path currentPoint]; // let the second endpoint of the current Bezier segment be the first one for the next Bezier segment
    [path removeAllPoints];
    ctr = 0; 
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesEnded:touches withEvent:event];
}

- (void)drawBitmap
{
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0.0);
    
    if(flag == 0){
        [[UIColor whiteColor] setStroke];        
    }else{
        [[UIColor blackColor] setStroke];        
    }    
    
    if (!incrementalImage) // first time; paint background white
    {
        rectpath = [UIBezierPath bezierPathWithRect:self.bounds];
        [[UIColor whiteColor] setFill];
        [rectpath fill];
    }
    [incrementalImage drawAtPoint:CGPointZero];
    [path stroke];
    incrementalImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
}

- (void)eraserActived:(NSNotification*)notification
{
    if ([[notification name] isEqualToString:@"eraserActived"]){ 
        flag = [[[notification userInfo] valueForKey:@"eraser"] integerValue]; 
        NSLog(@"Notification With X1 %d", flag); 
    }
}
 
@end
  

5. Now, in xib create One View to draw drawing on it & One Button to toggle pencil & eraser.

View in Xib

6. Change class of Drawing View to BezierInterpView. Access view in Code & Add IBAction on Button.

7. We are going to send notification to to toggle pencil & eraser.(There are other ways to perform this thing.)

8. Create on BOOL variable eraserActived to maintain eraser state. Create method to send notification & Call it on button click.

- (void)sendNotification
{
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    
    if (_eraserActived) {
        _eraserActived = NO; 
        [_eraserButton setImage:[UIImage imageNamed:@"pencil.png"] forState:UIControlStateNormal]; 
        [dict setValue:[NSString stringWithFormat:@"%d", 0] forKey:@"eraser"]; 
    }else{
        _eraserActived = YES; 
        [_eraserButton setImage:[UIImage imageNamed:@"eraser.png"] forState:UIControlStateNormal]; 
        [dict setValue:[NSString stringWithFormat:@"%d", 1] forKey:@"eraser"];
    }
    
    [[NSNotificationCenter defaultCenter] postNotificationName:@"eraserActived" object:self userInfo:dict];
}
   

7. Now run application. Try drawing something. It must work, if not for some reason then see sample code with this tutorial.

After drawing

8. Create on more button to clear view. On it’s action run following code.

    if(_drawingView.incrementalImage){
        _drawingView.incrementalImage = FALSE;
        [_drawingView setNeedsDisplay]; 
        _eraserActived = NO;    
        [self sendNotification]; 
    }
   

9. Download: Source Code

Android : Simple Hand Drawing On Canvas With Eraser.

Sometimes we may need to create scratchpad in our Android application.
We can create it on Canvas

First, create a main layout file for your activity.

<LinearLayout
         xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/drawing_question"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginLeft="40dp"
                android:layout_marginRight="30dp"
                android:background="#FFFFFF"
                android:orientation="horizontal" >

                <com.swap.handdrawing.DrawingView
                    android:id="@+id/drawing"
                    android:layout_width="0dp"
                    android:layout_height="fill_parent"
                    android:layout_marginBottom="10dp"
                    android:layout_marginRight="5dp"
                    android:layout_weight="1" >
                </com.swap.handdrawing.DrawingView>

                <LinearLayout
                    android:id="@+id/eraserView"
                    android:layout_width="50dp"
                    android:layout_height="fill_parent"
                    android:layout_marginBottom="10dp"
                    android:background="@drawable/custom_edit_text"
                    android:padding="5dp" >

                    <ImageView
                        android:id="@+id/eraser"
                        android:layout_width="40dp"
                        android:layout_height="40dp"
                        android:layout_gravity="center"
                        android:src="@drawable/eraser" />
                </LinearLayout>
</LinearLayout>

Next, create DrawingView class extending View & implementing OnTouchListener.

 
package com.swap.handdrawing;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class DrawingView extends View implements OnTouchListener {
	private Canvas m_Canvas;

	private Path m_Path;

	private Paint m_Paint;

	ArrayList<Pair> paths = new ArrayList<Pair>();
 
	private float mX, mY;

	private static final float TOUCH_TOLERANCE = 4;

	public static boolean isEraserActive = false; 

	public DrawingView(Context context, AttributeSet attr) {
		super(context);
		setFocusable(true);
		setFocusableInTouchMode(true);

		setBackgroundColor(Color.WHITE);

		this.setOnTouchListener(this);

		onCanvasInitialization();
	}

	public void onCanvasInitialization() {
		m_Paint = new Paint();
		m_Paint.setAntiAlias(true);
		m_Paint.setDither(true);
		m_Paint.setColor(Color.parseColor("#000000")); 
		m_Paint.setStyle(Paint.Style.STROKE);
		m_Paint.setStrokeJoin(Paint.Join.ROUND);
		m_Paint.setStrokeCap(Paint.Cap.ROUND);
		m_Paint.setStrokeWidth(2);

		m_Canvas = new Canvas();
 
		m_Path = new Path();
		Paint newPaint = new Paint(m_Paint);
		paths.add(new Pair(m_Path, newPaint));
 
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
	}

	public boolean onTouch(View arg0, MotionEvent event) {
		float x = event.getX();
		float y = event.getY();

		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			touch_start(x, y);
			invalidate();
			break;
		case MotionEvent.ACTION_MOVE:
			touch_move(x, y);
			invalidate();
			break;
		case MotionEvent.ACTION_UP:
			touch_up();
			invalidate();
			break;
		}
		return true;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		for (Pair p : paths) {
			canvas.drawPath(p.first, p.second);
		}
	}

	private void touch_start(float x, float y) {

		if (isEraserActive) {
			m_Paint.setColor(Color.WHITE);
			m_Paint.setStrokeWidth(6);
			Paint newPaint = new Paint(m_Paint); // Clones the mPaint object
			paths.add(new Pair(m_Path, newPaint));
		} else { 
			m_Paint.setColor(Color.BLACK);
			m_Paint.setStrokeWidth(2);
			Paint newPaint = new Paint(m_Paint); // Clones the mPaint object
			paths.add(new Pair(m_Path, newPaint));
		}
 
		m_Path.reset();
		m_Path.moveTo(x, y);
		mX = x;
		mY = y;
	}

	private void touch_move(float x, float y) {
		float dx = Math.abs(x - mX);
		float dy = Math.abs(y - mY);
		if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
			m_Path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
			mX = x;
			mY = y;
		}
	}

	private void touch_up() {
		m_Path.lineTo(mX, mY);

		// commit the path to our offscreen
		m_Canvas.drawPath(m_Path, m_Paint);

		// kill this so we don't double draw
		m_Path = new Path();
		Paint newPaint = new Paint(m_Paint); // Clones the mPaint object
		paths.add(new Pair(m_Path, newPaint));
	}   
} 
 

Then access DrawingView in your MainActivity. Toggle between eraser & pencil by changing isEraserActive & it’s image.


package com.swap.handdrawing;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;

public class MainActivity extends Activity {

	private ImageView eraser;


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

		final DrawingView drawingView = (DrawingView) findViewById(R.id.drawing);

		eraser = (ImageView) findViewById(R.id.eraser);
		eraser.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				if (drawingView.isEraserActive) {
					drawingView.isEraserActive = false;

					eraser.setImageResource(R.drawable.eraser);

				} else {
					drawingView.isEraserActive = true;

					eraser.setImageResource(R.drawable.pencil);
				}

			}
		});

	}

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

}

 

You can get resources & drawables used in above tutorial by downloading source code. You can add colors to your drawing by changing color of path.
Any suggestions are always welcome.

Download: Source Code.

Mac OS X : Install MySQL 5.5 on Mac OS X Lion 10.7

First you need to download latest version of MySQL.(For me it was mysql-5.5.29-osx10.6-x86_64)
http://dev.mysql.com/downloads/mysql/

You must download dmg archive (32 bit or 64 bit) under MySQL Community Server 5.5.29.
(It works perfectly fine on Mac OS X Lion even site says download for Mac OS X 10.6 Snow Leopard)

Next, you need to open that dmg file & install mysql-5.5.29-osx10.6-x86_64.pkg.
You can install MySQLStartupItem.pkg & MySQL.prefPane for starting MySQL Server on startup of your machine.

Open terminal & type

mysql -u root

Terminal can’t find mysql. It’s not done yet !

1. Open your text editor & open a file /User/your_username/.bash_profile.
(If it doesn’t exist then create it.)

2. Add following line to bash_profile.

export PATH=$PATH:/usr/local/mysql/bin

3. Save this file & relaunch terminal. In order to check $PATH is set properly, in terminal type

echo $PATH

This will display something like this

/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:
/Swap/android-sdk-macosx/tools:/Swap/android-sdk-macosx
/platform-tools:/usr/local/git/bin:/usr/local/mysql/bin

4. Now, you should be able to run.

mysql -u root

This means you can login into mysql server without password.

5. To Set your password.

GRANT ALL ON *.* TO 'root'@'localhost' IDENTIFIED BY 
'set_your_password_here' WITH GRANT OPTION;

6. Now you can login into mysql server with password as

mysql -u root -pyour_password_here

(Note: There is no space between -p & your password. Eg. If my password is swap123 then, I will login as mysql -u root -pswap123)

Done !

Mobile Web : Detect mobile device & platform from mobile website

You can detect mobile device & platform from mobile website with following javascript
This has worked for me on iPad 2, iPod 4G, iPhone 4G, Nexus 7, HTC Sensation, Sony Xperia, Samsung duos, View Sonic tab.

 
function MobilePlatform() {
    var platform = navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i);

    if (platform == "iPad" || platform == "iPhone" || platform == "iPod") {
        return "iOS";
    } else {

        if (platform == null) {
            return "Not Specified";
        }

        return platform;
    }
}

function MobileDevice() {
    var string = navigator.userAgent;
    var mobile = string.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i);

    if (mobile == "iPad" || mobile == "iPhone" || mobile == "iPod") {
        return mobile;
    } else {
        var s = string.indexOf("Build");
        //alert(s);
        var str = "";
        if (s == -1) {
            str = string.substring(string.indexOf(";"), string.lastIndexOf(";") - 1);
            str = str.substring(str.lastIndexOf(";") + 1, str.length);
        } else {
            str = string.substring(string.lastIndexOf(";") + 1, string.indexOf("Build") - 1);
        }

        return str;
    }

}

alert("Device : "+ MobileDevice() +" Platform : "+ MobilePlatform() );

Thanks to Jugal Desai

Website : Spring Security Basic Authorization in Javascript.

This example explains basic authorization for spring security.

You need to include Base64.js

 
var BASE_URI = "http://localhost:8080/";

//Encode username & password in Base64
function make_base_auth(user, password) {
    var tok = user + ':' + password;
    var hash = Base64.encode(tok);
    return "Basic " + hash;
}

//Get Authorization cookie 
function getAuthCookie() {
    var cn = "Authorization=";
    var idx = document.cookie.indexOf(cn)

    if (idx != -1) {
        var end = document.cookie.indexOf(";", idx + 1);
        if (end == -1) end = document.cookie.length;
        return unescape(document.cookie.substring(idx + cn.length, end));
    } else {
        return "";
    }
} 
$("#btnLogin").live("click", function () { 
    
    //At first Login create authorization cookie. 
    var auth = make_base_auth($('#email').val().trim(), $('#password').val().trim());
    document.cookie = "Authorization=" + auth;

    $.ajax({
        url: BASE_URI + "user",
        method: "GET",
        beforeSend: function (xhr) {
            //Set authorization header
            xhr.setRequestHeader('Authorization', getAuthCookie());
        },
        xhrFields: {
            withCredentials: true
        }, 
        accept: "application/json",
        contentType: "application/json", 
        statusCode: {
            404: function () {
                console.log("Page Not Found");
            },
            401: function () { 
                // You can show failure message here.
                document.cookie = encodeURIComponent('Authorization') + "=deleted; expires=" + new Date(0).toUTCString();
            }
        }

    }).success(function (response) {
        console.log("Login SUCCESS " +  JSON.stringify(response)); 
    }).fail(function (response) {
        console.log("Login FAILED " + JSON.stringify(response));
    }).then(function (response) { 
    });

HTML5 : Handle browser back button in single html file while navigating through multiple section’s.

<!DOCTYPE HTML>

<html>
	<head>
		<title>Navigation</title>
 
		<script type="text/javascript" src="js/jquery-1.7.2.js"></script>

		<style type="text/css">
			.section {
				border: 1px solid red;
				text-align: center;
			} 
		</style>

		<script type="text/javascript">
			(function(original) {// overwrite history.pushState so that it also calls
				// the change function when called
				history.pushState = function(state) {
					//change(state);
					return original.apply(this, arguments);
				};
			})(history.pushState);

			function change(state) {

				if(state === null) {// initial page

				} else {
					
					if(state.url){
						$(".section").hide();
						$("#"+state.url).show();  
					}

				}
			}


			$(document).ready(function() { 

                                 history.pushState({ url: "section1" }, "section1", "#section1");
				
				$(window).bind("popstate", function(e) {
					change(e.originalEvent.state);
				});
				
				var x = 1;
				
				$(".section").live("click", function(e){
					
					if(x < 8){
						$(".section").hide();
						$("#section"+ (++x)).show(); 
						
						e.preventDefault();
                                                history.pushState({ url: "section"+x }, "section"+x, "#section"+x);
						
						
					}else if(x == 8) {
						 alert("Done"); 
                                                 ++x;
					}
					 
				});
				

			});

		</script>

	</head>

	<body>

		<section id="section1" class="section"> 
			<h1> Section 1</h1> 
		</section>

		<section id="section2" class="section" style="display: none"> 
			<h1> Section 2</h1> 
		</section>

		<section id="section3" class="section" style="display: none"> 
			<h1> Section 3</h1> 
		</section>

		<section id="section4" class="section" style="display: none"> 
			<h1> Section 4</h1> 
		</section>

		<section id="section5" class="section" style="display: none"> 
			<h1> Section 5</h1> 
		</section>

		<section id="section6" class="section" style="display: none"> 
			<h1> Section 6</h1> 
		</section>

		<section id="section7" class="section" style="display: none"> 
			<h1> Section 7</h1> 
		</section>

		<section id="section8" class="section" style="display: none"> 
			<h1> Section 8</h1> 
		</section>

	</body>

</html>

Download : Source Code