Thursday, December 15, 2011

A Basic Android Database Example

In this post we shall develop a basic Android Database Example.

Every Android phone contains an inbuilt SQLite database. Therefore, no separate setup or configuration is required.

In this post we shall create a SQLite table, insert some data into it, and also perform a select query.The table contains two fields bookname of type text, and price of type int.
This application contains three buttons Select,Insert and Create for selecting, inserting and creating the table respectively. It also contains two EditBoxes for supplying the Book Name and Price values. There is a TextView for providing status messages.Here is a picture of the User Interface:-



The main classes involved are:-
android.database.sqlite.SQLiteOpenHelper
This class needs to be subclassed to provide for creation of the database.
It has two methods
    @Override
    public void onCreate(SQLiteDatabase database) {
//Called when the database is created.       

   }

    @Override
    public void onUpgrade(SQLiteDatabase database, int oldversion, int newversion) {
//Called when the database is upgraded.
       
    }


 android.database.sqlite.SQLiteDatabase
Encapsulates a connection to a SQLite database and provides methods for sending queries to the Database and recovering the result.


android.database.Cursor
This class provides methods for accessing the results of a select query.It can be compared to the java.sql.ResultSet.
Here is the code for the DatabaseHelper
DatabaseHelper.java

package project.hypatia.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) {
        super(context, "hypatiadata", null, 1);

//hypatiadata is the name of the database
// 1 is the version no.
//The null parameter can be used to pass a CursorFactory. We are not using it, so it is null.
        // TODO Auto-generated constructor stub
    }

        @Override
    public void onCreate(SQLiteDatabase database) {
        // TODO Auto-generated method stub
       

    }

    @Override
    public void onUpgrade(SQLiteDatabase database, int oldversion, int newversion) {
        // TODO Auto-generated method stub
       
    }

}


This is the code for the ProjectActivity
It contains a subclass DataHandler which contains the click events for the three buttons.
The select button
//*********************************************************************************
  if(b.equals(bttnselect))
                {
                    try
                    {
                        String bookname="" + txtBookName.getText();
                        bookname=bookname.replaceAll("'", "''").trim();
                       
                   
                        String[] columns={"Price"};
                        String selection="BookName='"+ bookname + "'";
                       
                    cursor=    database.query("HypatiaBooks", columns, selection, null, null, null, null);
//The Parameters mean
//1) The Name of the Table
//2) A string array containing the fields to be queried.
//3) A string containing the selection criteria
//4) A string array of selection arguments
//5) groupby statement
//6) having
//7) orderby
//The ones not being used are null
                    if(cursor==null)
                    {
                        txtResult.setText("No Data Found");
                        return;
                    }
                    if(cursor.moveToFirst())
                    {
                    int price=cursor.getInt(0);
                    txtPrice.setText("" + price);
                        txtResult.setText("Data Selected");
                    }
                    else
                        txtResult.setText("No Data Found");
                        cursor.close();
                    }
                    catch (Exception ex) {
                        // TODO: handle exception
                        txtResult.setText(ex.getMessage());
                    }
                }
//*********************************************************************************
the cursor provides methods for accessing the data fields, unlike jdbc the indexing starts at 0.

Here is the complete code

HypatiaAndroidProjectActivity.java


package project.hypatia.database;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.database.*;
import android.database.sqlite.*;
public class HypatiaAndroidProjectActivity extends Activity {
    /** Called when the activity is first created. */
    Button bttncreate,bttninsert,bttnselect;
    EditText txtBookName,txtPrice;
    TextView txtResult;
   
    private Cursor cursor;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        bttncreate=(Button)findViewById(R.id.button1);
        bttninsert=(Button)findViewById(R.id.button2);
        bttnselect=(Button)findViewById(R.id.button3);
        txtBookName=(EditText)findViewById(R.id.txtBookName);
        txtPrice=(EditText)findViewById(R.id.txtPrice);
        txtResult=(TextView)findViewById(R.id.txtOutput);
        DataHandler dh=new  DataHandler();
        DatabaseHelper dhh=new DatabaseHelper(this);
       database= dhh.getWritableDatabase();
       bttncreate.setOnClickListener(dh);
       bttninsert.setOnClickListener(dh);
       bttnselect.setOnClickListener(dh);
    }
    //****************************************************************
   SQLiteDatabase database;
    class DataHandler implements OnClickListener
    {

        @Override
        public void onClick(View view) {
            // TODO Auto-generated method stub
       
           
                Button b=(Button)view;
                if(b.equals(bttncreate))
                {
                    try
                    {
                        database.execSQL( "create table HypatiaBooks(bookname text primary key,price integer not null )");
                        txtResult.setText("Table Created");
                    }
                    catch (Exception ex) {
                        // TODO: handle exception
                        txtResult.setText(ex.getMessage());
                    }
                }
                if(b.equals(bttninsert))
                {
                    try
                    {
                        String bookname="" + txtBookName.getText();
                        bookname=bookname.replaceAll("'", "''").trim();
                        String price="" + txtPrice.getText();
                        price=price.replaceAll("'","''").trim();
                        database.execSQL("insert into HypatiaBooks values('" + bookname + "'," + price + ")");
                        txtResult.setText("Data Inserted");
                    }
                    catch (Exception ex) {
                        // TODO: handle exception
                        txtResult.setText(ex.getMessage());
                    }
                }
               
                if(b.equals(bttnselect))
                {
                    try
                    {
                        String bookname="" + txtBookName.getText();
                        bookname=bookname.replaceAll("'", "''").trim();
                       
                   
                        String[] columns={"Price"};
                        String selection="BookName='"+ bookname + "'";
                       
                    cursor=    database.query("HypatiaBooks", columns, selection, null, null, null, null);
                    if(cursor==null)
                    {
                        txtResult.setText("No Data Found");
                        return;
                    }
                    if(cursor.moveToFirst())
                    {
                    int price=cursor.getInt(0);
                    txtPrice.setText("" + price);
                        txtResult.setText("Data Selected");
                    }
                    else
                        txtResult.setText("No Data Found");
                        cursor.close();
                    }
                    catch (Exception ex) {
                        // TODO: handle exception
                        txtResult.setText(ex.getMessage());
                    }
                }
            }
           
           
           
        }
      
      
          
      
    }
   
    //****************************************************************


 Here is the main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >


    <EditText
        android:id="@+id/txtBookName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <requestFocus />
    </EditText>


    <EditText
        android:id="@+id/txtPrice"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="number"
         />


    <TextView
        android:id="@+id/txtOutput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />



    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/bttncreate" />



    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/bttninsert" />



    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/bttnselect" />

  

</LinearLayout>


Here is the design view:-


The application in Eclipse

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

    <string name="hello">Hypatia Basic Android Database </string>
    <string name="app_name">Hypatia Basic Android Database </string>
    <string name="b1">Insert</string>
    <string name="b2">Select</string>
    <string name="bttnselect">select</string>
    <string name="bttninsert">Insert</string>
    <string name="bttncreate">create</string>

</resources>


Next, we shall focus on using the Camera in an Android Device.

Saturday, December 10, 2011

A Basic Android Animation Example

In this Post we shall develop a very simple Android Animation Example.
The classes involved are:-

 For an explanation of the Graphics classes , please refer the previous post at:-
http://champakonline.blogspot.com/2011/12/basic-android-graphics-example.html
The classes you would find there are View,Canvas,Paint,Path,Bitmap, etc.
 Drawing was done by putting the code in the onDraw method of the View class.
You might want a quick review of that post before continuing.


Basic classes for Animation
1) android.view.animation.Animation
This class represents an Android Animation. There are many sub classes of this animation namely:-
    a) android.view.animation.ScaleAnimation
    b) android.view.animationAlphaAnimation
    c) android.view.animation.RotateAnimation
    d) android.view.animation.TranslateAnimation;
In this example we implement an animation using AlphaAnimation and RotateAnimation.

Main functionality of the Animation class
The Animation class provides methods for  setting the RepeatMode , RepeatCount, Interpolator, setDuration.
RepeatMode: This is the RepeatMode of the Animation. Possible values are Animation.REVERSE,Animation.RESTART.
RepeatCount: Possible values are Animation.INFINITE,Animation.ABSOLUTE.
setDuration(); The value gives the duration of one round of the Animation.

setInterpolator

This method is used to set an Interpolator. We have used an android.view.animation.AccelerateDecelerateInterpolator.
other interpolators are :-
 android.view.animation.AccelerateInterpolator,
android.view.animation.AnticipateOvershootInterpolator,
android.view.animation.BounceInterpolator,
android.view.animation.DecelerateInterpolator,
android.view.animation.AnticipateInterpolator,
android.view.animation.CycleInterpolator,
android.view.animation.LinearInterpolator,
android.view.animation.OvershootInterpolator .


We have used the android.view.animation.AccelerateDecelerateInterpolator.
The interpolator decides the progress and restart of the Animation.




 The Code:-
 HypatiaAnimationView.java 

package hypatia.animation.basic;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.RotateAnimation;


public class HypatiaAnimationView extends View implements AnimationListener {
String themessage="Reserve your right to think, for even to think wrongly is better than not to think at all.";
    public HypatiaAnimationView(Context context) {
        super(context);
        paint = new Paint();
        paint.setColor(HypatiaBasicAnimationActivity.colors[HypatiaBasicAnimationActivity.colorno]);
        HypatiaBasicAnimationActivity.colorno=(HypatiaBasicAnimationActivity.colorno + 1) % HypatiaBasicAnimationActivity.colors.length;
       
        // TODO Auto-generated constructor stub
    }
    Paint paint;//The paint object for the drawing
    @Override
public void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
            if (hypatiaanimationset == null) {//If the animation set is null, create it
                //***********************Create the Animation Set****************************
                {
       
                hypatiaanimationset=new AnimationSet(true);
                animation = new AlphaAnimation(1F, 0F);
                animation.setRepeatMode(Animation.REVERSE);
                animation.setRepeatCount(Animation.INFINITE);
              
                animation.setDuration(5000);
                animation.setAnimationListener(this);
                hypatiaanimationset.addAnimation(animation);
                animation = new RotateAnimation(0, 360,canvas.getWidth()/2,canvas.getHeight()/2);
                animation.setRepeatMode(Animation.REVERSE);
                animation.setRepeatCount(Animation.INFINITE);
                animation.setDuration(1000);
                hypatiaanimationset.addAnimation(animation);
               
                hypatiaanimationset.setInterpolator(new android.view.animation.AccelerateDecelerateInterpolator());
                startAnimation(hypatiaanimationset);
                }
                //***************************************************************************
           
        }

        Path circle = new Path();

        int cx = canvas.getWidth() / 2;
        int cy = canvas.getHeight() / 2;
        int r = Math.min(cx, cy);
        paint.setTextSize(48);
        if(HypatiaBasicAnimationActivity.colorno % 2==0)
       circle.addCircle(cx, cy, r-5, Direction.CW);
        else
        circle.addCircle(cx, cy, r-35, Direction.CCW);
        canvas.drawTextOnPath(themessage, circle, 0, 30, paint);
        Bitmap hypatiaportrait = BitmapFactory.decodeResource(getResources(),R.drawable.hypatia);
        canvas.drawBitmap(hypatiaportrait,cx-hypatiaportrait.getWidth()/2,cy-hypatiaportrait.getHeight()/2,null);

    }
   
   
   
    private Animation animation;
private AnimationSet hypatiaanimationset;
 
    @Override
    public void onAnimationEnd(Animation animation) {
        // TODO Auto-generated method stub
       
    }
    @Override
    public void onAnimationRepeat(Animation animation) {
        // TODO Auto-generated method stub
       
        paint.setColor(HypatiaBasicAnimationActivity.colors[HypatiaBasicAnimationActivity.colorno]);
        HypatiaBasicAnimationActivity.colorno=(HypatiaBasicAnimationActivity.colorno + 1) % HypatiaBasicAnimationActivity.colors.length;
        HypatiaBasicAnimationActivity.v.invalidate();
    }
    @Override
    public void onAnimationStart(Animation animation) {
        // TODO Auto-generated method stub
       
    }
}
 

HypatiaBasicAnimationActivity.java

package hypatia.animation.basic;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;

public class HypatiaBasicAnimationActivity extends Activity {
    /** Called when the activity is first created. */
static    HypatiaAnimationView v;
static int[] colors={Color.WHITE,Color.YELLOW,Color.MAGENTA,Color.GREEN,Color.RED};
static int colorno=0;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        //This is the first method to be executed
       
        super.onCreate(savedInstanceState);
         v=new HypatiaAnimationView(this);//Create the view and store it in a static variable for further use
        setContentView(v);//Make this view the current view. This means that whenever the view is invalidated it's onDraw method will be called
    }
  
   
   
}


In the next Post of the series we shall create an Animation using an XML File.

Monday, December 5, 2011

A Basic Android Graphics Example

In this example we shall explore the basics of drawing in Android. In particular we shall learn the basics of the Paint class , the Canvas class and their methods.We shall also learn how to add pictures as resources, and how to access them.

The OnDraw Method.
This method is the exact equivalent of the paintComponent method in Java. This method is called automatically whenever the View needs to be redrawn. It has a parameter of type Canvas which can be used for drawing on the View. Like the Graphics class in Java the Canvas class provides drawing methods.

The Paint class provides facilities for managing the coloring, the strokes, fonts, and also measurements of Strings. The Bitmap class encapsulates a Bitmap, it also supports drawing.

We start by creating a new Project called Hypatia  Drawing  Basics

Then import a PNG file into resources
1)

2)
3)
4)



Next subclass the View class.     HypatiaDrawingView

public class HypatiaDrawingView extends View {

    public HypatiaDrawingView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }
}

Now create the OnDraw Method inside the HypatiaDrawingView class

@Override
protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);
    Paint paint=new Paint();
    paint.setStyle(Style.FILL);
    canvas.drawPaint(paint);
    paint.setColor(Color.GREEN);
    int width=canvas.getWidth();
    int height=canvas.getHeight();
    int radius;
    if(width<height)
        radius=width/2;
    else
        radius=height/2;
   
   
   
    canvas.drawCircle(width/2, height/2, radius, paint);
    paint.setColor(Color.YELLOW);
    Path ph=new Path();
   
    ph.setLastPoint(0, height/2);
    ph.lineTo(width/2, height/2+radius);
    ph.lineTo(width, height/2);
    ph.lineTo(width/2, height/2-radius);
    canvas.drawPath(ph, paint);
   
   
     Bitmap bruno = BitmapFactory.decodeResource(getResources(),
             R.drawable.giordanobruno);

canvas.drawBitmap(bruno,width/2-bruno.getWidth()/2, height/2-bruno.getHeight()/2,null);
paint.setColor(Color.MAGENTA);
paint.setTextSize(40);
String headline="Hypatia Software Solutions";


 float textwidth=paint.measureText(headline);

canvas.drawText(headline,width/2-textwidth/2,height/4,paint);
   
   
    }
The methods we have used should basically be self explanatory. 
paint.setStyle(Style.FILL); Sets the drawing style. Fill means that closed surfaces are automatically filled.

paint.setColor(Color.GREEN); Sets the drawing color.

paint.setStyle(Style.FILL); Sets the drawing style. Fill means that closed surfaces are automatically filled.

The Path class represents a Polygon. The Last point is also the first point and are automatically joined. Other points are joined serially.
To set the last point we use
  ph.setLastPoint(0, height/2);
For other points
    ph.lineTo(width/2, height/2+radius);
    To draw the Polygon
    canvas.drawPath(ph, paint);

Drawing the Bitmap

First we access the imported resource.

Then draw it

Bitmap bruno = BitmapFactory.decodeResource(getResources(),
             R.drawable.giordanobruno);

canvas.drawBitmap(bruno,width/2-bruno.getWidth()/2, height/2-bruno.getHeight()/2,null);

The last parameter represents the paint object.We are not using it, so it is null.

Here is the complete application as it looks in Eclipse

 

The Complete Code
HypatiaDrawingBasicsActivity.java
package hypatia.drawing.basics;

import android.app.Activity;
import android.os.Bundle;

public class HypatiaDrawingBasicsActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        HypatiaDrawingView view=new HypatiaDrawingView(this);
        setContentView(view);
    }
}

HypatiaDrawingView.java
package hypatia.drawing.basics;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Rect;
import android.view.View;

public class HypatiaDrawingView extends View {

    public HypatiaDrawingView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }
@Override
protected void onDraw(Canvas canvas) {
    // TODO Auto-generated method stub
    super.onDraw(canvas);
    Paint paint=new Paint();
    paint.setStyle(Style.FILL);
    canvas.drawPaint(paint);
    paint.setColor(Color.GREEN);
    int width=canvas.getWidth();
    int height=canvas.getHeight();
    int radius;
    if(width<height)
        radius=width/2;
    else
        radius=height/2;
   
   
   
    canvas.drawCircle(width/2, height/2, radius, paint);
    paint.setColor(Color.YELLOW);
    Path ph=new Path();
   
    ph.setLastPoint(0, height/2);
    ph.lineTo(width/2, height/2+radius);
    ph.lineTo(width, height/2);
    ph.lineTo(width/2, height/2-radius);
    canvas.drawPath(ph, paint);
   
   
     Bitmap bruno = BitmapFactory.decodeResource(getResources(),
             R.drawable.giordanobruno);

canvas.drawBitmap(bruno,width/2-bruno.getWidth()/2, height/2-bruno.getHeight()/2,null);
paint.setColor(Color.MAGENTA);
paint.setTextSize(40);
String headline="Hypatia Software Solutions";


 float textwidth=paint.measureText(headline);

canvas.drawText(headline,width/2-textwidth/2,height/4,paint);
   
   
    }
}

strings.xml

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

    <string name="hello">Hypatia Drawing Basics Activity!</string>
    <string name="app_name">Hypatia  Drawing  Basics</string>

</resources>


The app as it appears in the emulator.

 

Next we shall attempt moving graphics.