Sie sind auf Seite 1von 146

Workshop Android

Programming

This workshop will teach you basic Android programming.

Audience
This workshop has been prepared for the beginners to help them understand basic Android
programming. After completing this workshop, hopefully you will be able to complete your PSM
project successfully.
Prerequisites
Android programming is based on Java programming language so if you have basic
understanding on Java programming then it will be a fun to learn Android application
development.

SOURCE: Google Mobile Blog

What is Android?
Android is an open source and Linux-based Operating System for mobile devices such as
smartphones and tablet computers. Android was developed by the Open Handset Alliance, led
by Google, and other companies.
Android offers a unified approach to application development for mobile devices which
means developers need only develop for Android, and their applications should be able to run on
different devices powered by Android.

The first beta version of the Android Software Development Kit (SDK) was released by
Google in 2007 where as the first commercial version, Android 1.0, was released in September
2008.

On June 27, 2012, at the Google I/O conference, Google announced the next Android
version, 4.1 Jelly Bean. Jelly Bean is an incremental update, with the primary aim of improving
the user interface, both in terms of functionality and performance.

The android historical version distribution is shown below:

The source code for Android is available under free and open source software licenses.
Google publishes most of the code under the Apache License version 2.0 and the rest, Linux
kernel changes, under the GNU General Public License version 2.
Features of Android
Android is a powerful operating system competing with Apple 4GS and supports great features.
Few of them are listed below:

Feature Description

Beautiful UI Android OS basic screen provides a beautiful and intuitive user interface.

GSM/EDGE, IDEN, CDMA, EV-DO, UMTS, Bluetooth, Wi-Fi, LTE, NFC and
Connectivity
WiMAX.

Storage SQLite, a lightweight relational database, is used for data storage purposes.

H.263, H.264, MPEG-4 SP, AMR, AMR-WB, AAC, HE-AAC, AAC 5.1, MP3,
Media support
MIDI, Ogg Vorbis, WAV, JPEG, PNG, GIF, and BMP

Messaging SMS and MMS

Based on the open-source WebKit layout engine, coupled with Chrome's V8


Web browser
JavaScript engine supporting HTML5 and CSS3.

Android has native support for multi-touch which was initially made available
Multi-touch
in handsets such as the HTC Hero.

User can jump from one task to another and same time various application
Multi-tasking
can run simultaneously.

Widgets are resizable, so users can expand them to show more content or
Resizable widgets
shrink them to save space

Multi-Language Supports single direction and bi-directional text.

Google Cloud Messaging (GCM) is a service that lets developers send short
GCM message data to their users on Android devices, without needing a
proprietary sync solution.

A technology that lets apps discover and pair directly, over a high-bandwidth
Wi-Fi Direct
peer-to-peer connection.

A popular NFC-based technology that lets users instantly share, just by


Android Beam
touching two NFC-enabled phones together.
Android Applications
Android applications are usually developed in the Java language using the Android Software
Development Kit.

Once developed, Android applications can be packaged easily and sold out either
through a store such asGoogle Play or the Amazon Appstore.

Android powers hundreds of millions of mobile devices in more than 190 countries around the
world. It's the largest installed base of any mobile platform and growing fast. Every day more
than 1 million new Android devices are activated worldwide.

This tutorial has been written with an aim to teach you how to develop and package Android
application. We will start from environment setup for Android application programming and then
drill down to look into various aspects of Android applications.
Development Tools
Installation
You can start your Android application development on either of the following operating systems:

Microsoft Windows XP or later version.

Mac OS X 10.5.8 or later version with Intel chip.

Linux including GNU C Library 2.7 or later.

We will use Windows Operating System for this workshop.

Second point is that all the required tools to develop Android applications are freely
available and can be downloaded from the Web. Following is the list of software's you will need
before you start your Android application programming.

Java JDK5 or JDK6

Android SDK

Eclipse IDE for Java Developers (optional)

Android Development Tools (ADT) Eclipse Plugin (optional)

Here last two components are optional and if you are working on Windows machine then
these components make your life easy while doing Java based application development. So let
us have a look how to proceed to set required environment.

Step 1 - Setup Java Development Kit (JDK)


You can download the latest version of Java JDK from Oracle's Java site: Java SE Downloads.
You will find instructions for installing JDK in downloaded files, follow the given instructions to
install and configure the setup. Finally set PATH and JAVA_HOME environment variables to
refer to the directory that contains java andjavac, typically java_install_dir/bin and
java_install_dir respectively.

If you are running Windows and installed the JDK in C:\jdk1.6.0_15, you would
have to put the following line in your C:\autoexec.bat file.
set PATH=C:\jdk1.6.0_15\bin;%PATH%
set JAVA_HOME=C:\jdk1.6.0_15

Alternatively, you could also right-click on My Computer, select Properties,


then Advanced System Setting, then Environment Variables. Then, you
would update the PATH value and press the OK button, as depicted in the picture bellow.

Fig. 1: Right Click: My Computer|Properties


Fig-2: Right Click: My Computer|Properties|Advanced System Setting

Fig-3: Right Click: My Computer|Properties|Advanced System Setting|Environment Variables


Fig-4: Right Click: My Computer|Properties|Advanced System Setting|Environment Variables|New

Fig-5: Right Click: My Computer|Properties|Advanced System Setting|Environment Variables|New

Alternatively, if you use an Integrated Development Environment (IDE) Eclipse, then it


will know automatically where you have installed your Java.

Step 2 - Download Android SDK


You can download the latest version of Android SDK from Android official website : Android SDK
Downloads. The Android SDK provides you the API libraries and developer tools necessary to
build, test, and debug apps for Android.

Fig-6: Download Android SDK


If you're a new Android developer, we recommend you download the ADT Bundle to
quickly start developing apps. It includes the essential Android SDK components and a version of
the Eclipse IDE with built-in ADT (Android Developer Tools) to streamline your Android app
development.

With a single download, the ADT Bundle (file size around 500MB) includes everything
you need to begin developing apps:

Eclipse + ADT plugin


Android SDK Tools
Android Platform-tools
The latest Android platform
The latest Android system image for the emulator

Step 3 - Setting Up the ADT Bundle


The ADT Bundle provides everything you need to start developing apps, including a version of
the Eclipse IDE with built-in ADT (Android Developer Tools) to streamline your Android app
development.

Install the SDK and Eclipse IDE

Unpack the ZIP file (named adt-bundle-<os_platform>.zip) and save it to an


appropriate location, such as a "Development" directory in your home directory.
Open the adt-bundle-<os_platform>/eclipse/ directory and launch eclipse.

Fig-7: Unzip ADT Bundle fro windows


Fig-8: Launch eclipse

That's it! The IDE is already loaded with the Android Developer Tools plugin and the SDK
is ready to go. To start developing, read Building Your First App.

Caution: Do not move any of the files or directories from the adt-bundle-
<os_platform> directory. If you move the eclipse or sdk directory, ADT will not be able
to locate the SDK and you'll need to manually update the ADT preferences.

Use an Existing IDE


If you already have an IDE you want to use for Android app development, setting up a new SDK
requires that you download the SDK Tools, then select additional Android SDK packages to
install (such as the Android platform and system image). If you'll be using an existing version of
Eclipse, then you can add the ADT plugin to it.

Download the SDK Tools for Windows


The SDK Tools package is not the complete SDK environment. It includes only the core
SDK tools, which you can use to download the rest of the SDK packages (such as the latest
system image).

Your download package is an executable file that starts an installer. The installer checks
your machine for required tools, such as the proper Java SE Development Kit (JDK) and installs
it if necessary. The installer then saves the Android SDK Tools into a default location (or you can
specify the location).

Double-click the executable (installer_rXX-windows.exe file) to start the install.


Make a note of the name and location in which it saves the SDK on your systemyou will need
to refer to the SDK directory later, when setting up the ADT plugin and when using the SDK tools
from the command line.
Once the installation completes, the installer offers to start the Android SDK Manager. If you'll be
using Eclipse, do not start the Android SDK Manager, and instead move on to Installing the
Eclipse Plugin.

Installing the Eclipse Plugin


Android offers a custom plugin for the Eclipse IDE, called Android Development Tools (ADT).
This plugin provides a powerful, integrated environment in which to develop Android apps. It
extends the capabilities of Eclipse to let you quickly set up new Android projects, build an app UI,
debug your app, and export signed (or unsigned) app packages (APKs) for distribution.

If you need to install Eclipse, you can download it from eclipse.org/downloads/.

Note: If you prefer to work in a different IDE, you do not need to install Eclipse or ADT. Instead,
you can directly use the SDK tools to build and debug your application.
Download the ADT Plugin

Start Eclipse, then select Help > Install New Software.

Click Add, in the top-right corner.


In the Add Repository dialog that appears, enter "ADT Plugin" for the Name and the following
URL for theLocation:

https://dl-ssl.google.com/android/eclipse/
Click OK.

If you have trouble acquiring the plugin, try using "http" in the Location URL, instead of "https"
(https is preferred for security reasons).
In the Available Software dialog, select the checkbox next to Developer Tools and click Next.
In the next window, you'll see a list of the tools to be downloaded. Click Next.
Read and accept the license agreements, then click Finish.

If you get a security warning saying that the authenticity or validity of the software can't be
established, click OK.

When the installation completes, restart Eclipse.

Configure the ADT Plugin

Once Eclipse restarts, you must specify the location of your Android SDK directory:

In the "Welcome to Android Development" window that appears, select Use existing SDKs.
Browse and select the location of the Android SDK directory you recently downloaded and
unpacked.
Click Next.

Note: Your Eclipse IDE is now set up to develop Android apps, but you need to add the latest
SDK platform tools and an Android platform to your environment. To get these packages
for your SDK, continue to Adding Platforms and Packages.
Development Tools
Tutorial
Adding Platforms and Packages
The Android SDK separates tools, platforms, and other components into packages you can
download using theAndroid SDK Manager. The original SDK package you've downloaded
includes only the SDK Tools. To develop an Android app, you also need to download at least
one Android platform and the latest SDK Platform-tools.

You can launch the SDK Manager in one of the following ways:

From Eclipse (with ADT), select Window > Android SDK Manager.
On Windows, double-click the SDK Manager.exe file at the root of the Android SDK
directory.

The SDK Manager shows all the SDK packages available for you to add to your Android
SDK. As a minimum configuration for your SDK, we recommend you install the following:

The latest Tools packages (check the Tools folder).


The latest version of Android (check the first Android folder).
The Android Support Library (open the Extras folder and check Android Support Library).
Fig 16. The Android SDK Manager shows the SDK packages that are available, already installed,
or for which an update is available.

Once you've chosen your packages, click Install. The Android SDK Manager installs the
selected packages into your Android SDK environment.

Note: If your computer/laptop has minimal resources (CPU & memory), try to download the older
android platform, for example Android 2.3.3 (API 10).
For more information about using the SDK Manager and some of the available packages,
see the SDK Manager document.
Create Android Virtual Device
To test your Android applications you will need a virtual Android device. So before we start
writing our code, let us create an Android virtual device. Launch Android AVD Manager using
Eclipse menu options Window > Android Virtual Device Manager which will launch Android
AVD Manager.
Use New button to create a new Android Virtual Device and enter the following information.
A new window appear, then atleast you should give a name and select device (screen size) for
your new AVD. Type any name in the AVD name, for example 'MyFirstAVD', and then select a
device 5.1" WVGA (480 x 800: mdpi), let the other parts as it is, and click OK.

Now, you have one android virtual device "MyFirstAVD", this AVD will be shown in the list
of Android Virtual Device Manager, as shown in the figure bellow:
To activate your "MyFirstAVD", in the Android Virtual Device Manager window select an
AVD then click buttonStart.

A new windows will be appear (see figure bellow), then click button Launch.
Then "MyFirstAVD" will be started, you can see two windows appear, like figure bellow:
The AVD not ready yet until you see windows like bellow, when your MyFirstAVD is
ready for Android application development.

Now, you have a new android, you can operate it as real android.
Android Hello World
Welcome to Android application development!

This session teaches you how to build your first Android app. Youll learn how to create
an Android project and run a debuggable version of the app. You'll also learn some fundamentals
of Android app design, including how to build a simple user interface and handle user input.

This session uses a tutorial format that incrementally builds a small Android app that
teaches you some fundamental concepts about Android development, so it's important that you
follow each step.

Creating an Android Project


An Android project contains all the files that comprise the source code for your Android app. The
Android SDK tools make it easy to start a new Android project with a set of default project
directories and files.

This lesson shows how to create a new project either using Eclipse (with the ADT plugin)
or using the SDK tools from a command line.

Note: You should already have the Android SDK installed, and if you're using Eclipse, you
should also have the ADT plugin installed (version 21.0.0 or higher). If you don't have these,
follow the guide to Installing the Android SDK before you start this lesson.

1. Click New in the toolbar.


2. In the window that appears, open the Android folder, select Android Application Project,
and click Next.
Figure 1. The New Android App Project wizard in Eclipse.

3. Fill in the form that appears:

a. Application Name is the app name that appears to users. For this project, use "Hello
Wolrd."
b. Project Name is the name of your project directory and the name visible in Eclipse.
c. Package Name is the package namespace for your app (following the same rules as
packages in the Java programming language). Your package name must be unique
across all packages installed on the Android system. For this reason, it's generally best
if you use a name that begins with the reverse domain name of your organization or
publisher entity. For this project, you can use something like "com.example.helloworld."
However, you cannot publish your app on Google Play using the "com.example"
namespace.
d. Minimum Required SDK is the lowest version of Android that your app supports,
indicated using the API level. To support as many devices as possible, you should set
this to the lowest version available that allows your app to provide its core feature set. If
any feature of your app is possible only on newer versions of Android and it's not critical
to the app's core feature set, you can enable the feature only when running on the
versions that support it. Leave this set to the default value for this project.
e. Target SDK indicates the highest version of Android (also using the API level) with
which you have tested with your application.

As new versions of Android become available, you should test your app on the
new version and update this value to match the latest API level in order to take
advantage of new platform features.

f. Compile With is the platform version against which you will compile your app. By
default, this is set to the latest version of Android available in your SDK. (It should be
Android 4.1 or greater; if you don't have such a version available, you must install one
using the SDK Manager). You can still build your app to support older versions, but
setting the build target to the latest version allows you to enable new features and
optimize your app for a great user experience on the latest devices.
g. Theme specifies the Android UI style to apply for your app. You can leave this alone.
Click Next.

4. On the next screen to configure the project, leave the default selections and click Next.

Figure 2. Configure the project.


5. The next screen can help you create a launcher icon for your app.

Figure 3. Create a launcher icon.

You can customize an icon in several ways and the tool generates an icon for all screen
densities. Before you publish your app, you should be sure your icon meets the specifications
defined in the Iconography design guide.

Click Next.
6. Now you can select an activity template from which to begin building your app.

Figure 4. Create Activity.

For this project, select BlankActivity and click Next.


7. Leave all the details for the activity in their default state and click Finish.

Figure 5. Leave in their default state.


Once your project is created successfully, you will have following project screen:

Figure 6. Hello world screen project in Eclipse IDE.


Anatomy of Android Application
Before you run your app, you should be aware of a few directories and files in the Android
project:

Figure 7. The structure of project directory.


S.N. Folder, File & Description

src
This contains the .java source files for your project. By default, it includes
1
an MainActivity.java source file having an activity class that runs when your app is
launched using the app icon.

gen
2 This contains the .R file, a compiler-generated file that references all the resources found
in your project.You should not modify this file.

bin
3 This folder contains the Android package files .apk built by the ADT during the build
process and everything else needed to run an Android application.

res/drawable-hdpi
4
This is a directory for drawable objects that are designed for high-density screens.

res/layout
5
This is a directory for files that define your app's user interface.

res/values
6 This is a directory for other various XML files that contain a collection of resources, such
as strings and colors definitions.

AndroidManifest.xml
7 This is the manifest file which describes the fundamental characteristics of the app and
defines each of its components.

Following section will give a brief overview few of the important application files.
The Main Activity File
The main activity code is a Java file MainActivity.java. This is the actual application file which
ultimately gets converted to a Dalvik executable and runs your application. Following is the
default code generated by the application wizard for Hello World! application:

package com.example.helloworld;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.MenuItem;
import android.support.v4.app.NavUtils;

public class MainActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}

Here, R.layout.activity_main refers to the activity_main.xml file located in


the res/layout folder. The onCreate()method is one of many methods that are fi red when an
activity is loaded.
The Manifest File
Whatever component you develop as a part of your application, you must declare all its
components in amanifest file called AndroidManifest.xml which ressides at the root of the
application project directory. This file works as an interface between Android OS and your
application, so if you do not declare your component in this file, then it will not be considered by
the OS. For example, a default manifest file will look like as following file:

<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.helloworld"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action
android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

Here <application>...</application> tags enclosed the components related to the


application. Attributeandroid:icon will point to the application icon available under res/drawable-
hdpi. The application uses the image named ic_launcher.png located in the drawable folders.

The <activity> tag is used to specify an activity and android:name attribute specifies the
fully qualified class name of the Activity subclass and the android:label attributes specifies a
string to use as the label for the activity. You can specify multiple activities using <activity> tags.
The action for the intent filter is named android.intent.action.MAIN to indicate that this activity
serves as the entry point for the application. The category for the intent-filter is
named android.intent.category.LAUNCHER to indicate that the application can be launched from
the device's launcher icon.
The @string refers to the strings.xml file explained below.
Hence, @string/app_name refers to the app_name string defined in the strings.xml fi le, which is
"HelloWorld". Similar way, other strings get populated in the application.

Following is the list of tags which you will use in your manifest file to specify different
Android application components:

1. <activity> elements for activities


2. <service> elements for services
3. <receiver> elements for broadcast receivers
4. <provider> elements for content providers

The Strings File


The strings.xml file is located in the res/values folder and it contains all the text that your
application uses. For example, the names of buttons, labels, default text, and similar types of
strings go into this file. This file is responsible for their textual content. For example, a default
strings file will look like as following file:

<resources>
<string name="app_name">HelloWorld</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_main">MainActivity</string>
</resources>

The R File
The gen/com.example.helloworld/R.java file is the glue between the activity Java
files likeMainActivity.java and the resources like strings.xml. It is an automatically generated file
and you should not modify the content of the R.java file. Following is a sample of R.java file:

/* AUTO-GENERATED FILE. DO NOT MODIFY.


*
* This class was automatically generated by the
* aapt tool from the resource data it found. It
* should not be modified by hand.
*/

package com.example.helloworld;

public final class R {


public static final class attr {
}
public static final class dimen {
public static final int padding_large=0x7f040002;
public static final int padding_medium=0x7f040001;
public static final int padding_small=0x7f040000;
}
public static final class drawable {
public static final int ic_action_search=0x7f020000;
public static final int ic_launcher=0x7f020001;
}
public static final class id {
public static final int menu_settings=0x7f080000;
}
public static final class layout {
public static final int activity_main=0x7f030000;
}
public static final class menu {
public static final int activity_main=0x7f070000;
}
public static final class string {
public static final int app_name=0x7f050000;
public static final int hello_world=0x7f050001;
public static final int menu_settings=0x7f050002;
public static final int
title_activity_main=0x7f050003;
}
public static final class style {
public static final int AppTheme=0x7f060000;
}
}

The Layout File


The activity_main.xml is a layout file available in res/layout directory, that is referenced by your
application when building its interface. You will modify this file very frequently to change the
layout of your application. For your "Hello World!" application, this file will have following content
related to default layout:

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

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:padding="@dimen/padding_medium"
android:text="@string/hello_world"
tools:context=".MainActivity" />

</RelativeLayout>

This is an example of simple RelativeLayout which we will study in a separate chapter.


The TextView is an Android control used to build the GUI and it have various attribuites
like android:layout_width,android:layout_height etc which are being used to set its width and
height etc. The @string refers to the strings.xml file located in the res/values folder. Hence,
@string/hello_world refers to the hello string defined in the strings.xml fi le, which is "Hello
World!".

Running the Application


Let's try to run our Hello World! application we just created. I assume you had created
your AVD while doing environment setup. To run the app from Eclipse IDE, you can do one of
the following way:

1. Open one of your project's activity files and click Run icon from the toolbar.

2. Go to the Package Explorer window, right click on the name of your project (Hello World),
then select Run As, and 1. Android Application.
Eclipse will automatically installs the app on your AVD and starts it and if everything is fine with
your setup and application, it will display following Emulator window:
Figure 8. AVD running Hello World.

Congratulations!!! you have developed your first Android Application and now just keep
following rest of the tutorial step by step to become a great Android Developer. All the very best.
Run 'Hello World' on a
Real Device
If you have a real Android-powered device, here's how you can install and run your app:

1. Plug in your device to your development machine with a USB cable. If you're developing on
Windows, you might need to install the appropriate USB driver for your device. For help
installing drivers, see the OEM USB Drivers document.

The ADT plugin offers a facility to monitor, what kind of device that attaches to your
machine. To show this facility, select menu Window|Show View|Other, as shown in figure
below:

Figure 1. Menu Window|Show View|Other.


Then from a window that appear, click on android folder, then select Device item and
click OK, see figure bellow:

Figure 2. Window that appear after you click menu Window|Show View|Other.

A tab Device will appear at the bottom tab of Eclipse IDE. If your window system have a
USB driver match with your device, then your device will be shown on that device tab.
Figure 3. Eclipse IDE with a Android-powered device attach on USB port.

2. Enable USB debugging on your device.

a. On most devices running Android 3.2 or older, you can find the option under Settings >
Applications > Development

.
b. On Android 4.0 and newer, it's in Settings > Developer options.

Note: On Android 4.2 and newer, Developer options is hidden by default. To make it available,
go toSettings > About phone and tap Build number seven times. Return to the previous
screen to findDeveloper options.

To run the app from Eclipse:

1. Open one of your project's files and click Run from the toolbar.
2. In the Run as window that appears, select Android Application and click OK.

Eclipse installs the app on your connected device and starts it.

Run an application on a real android device, sometime faster, so your development process
also will be faster.
Building Simple Interface
In this lesson, you'll create a layout in XML that includes a text field and a button. You'll respond
when the button is pressed by sending the content of the text field to another activity (page). First
time, Create a new project as we learn in section "Hello Wolrd in AVD" and named it as
"Simpleui"

Create a Linear Layout


Open the activity_main.xml file from the res/layout/ directory.

Note: In Eclipse, when you open a layout file, youre first shown the Graphical Layout editor. This
is an editor that helps you build layouts using WYSIWYG tools. For this lesson, youre going to
work directly with the XML, so click the activity_main.xml tab at the bottom of the screen to open
the XML editor.

The BlankActivity template you chose when you created this project includes
the activity_main.xml file with a RelativeLayout root view and a TextView child
view.

First, delete the <TextView> element and change the <RelativeLayout>


element to <LinearLayout>. Then add the android:orientation attribute and set it
to "horizontal". The result looks like this:

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


<LinearLayout
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"
android:orientation="horizontal" >
</LinearLayout>

LinearLayout is a view group (a subclass of ViewGroup) that lays out child views
in either a vertical or horizontal orientation, as specified by
the android:orientation attribute. Each child of a LinearLayout appears on the
screen in the order in which it appears in the XML.
The other two attributes, android:layout_width and
android:layout_height, are required for all views in order to specify their size.

Because the LinearLayout is the root view in the layout, it should fill the entire
screen area that's available to the app by setting the width and height to "match_parent".
This value declares that the view should expand its width or height to match the width or height
of the parent view.

For more information about layout properties, see the Layout guide.

Add a Text Field

To create a user-editable text field, add an <EditText> element inside


the <LinearLayout>.

Like every View object, you must define certain XML attributes to specify
the EditText object's properties. Heres how you should declare it inside
the <LinearLayout> element:

<EditText android:id="@+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />

About these attributes:

android:id
This provides a unique identifier for the view, which you can use to reference the object from
your app code, such as to read and manipulate the object (you'll see this in the next lesson).

The at sign (@) is required when you're referring to any resource object from XML. It is
followed by the resource type (id in this case), a slash, then the resource name
(edit_message).

The plus sign (+) before the resource type is needed only when you're defining a
resource ID for the first time. When you compile the app, the SDK tools use the ID name to
create a new resource ID in your project's gen/R.java file that refers to
the EditText element. Once the resource ID is declared once this way, other references to
the ID do not need the plus sign. Using the plus sign is necessary only when specifying a new
resource ID and not needed for concrete resources such as strings or layouts. See the sidebox
for more information about resource objects.

android:layout_width and android:layout_height

Instead of using specific sizes for the width and height, the "wrap_content" value specifies
that the view should be only as big as needed to fit the contents of the view. If you were to
instead use "match_parent", then the EditText element would fill the screen, because it
would match the size of the parent LinearLayout. For more information, see
the Layouts guide.

android:hint
This is a default string to display when the text field is empty. Instead of using a hard-coded
string as the value, the "@string/edit_message" value refers to a string resource
defined in a separate file. Because this refers to a concrete resource (not just an identifier), it
does not need the plus sign. However, because you haven't defined the string resource yet,
youll see a compiler error at first. You'll fix this in the next section by defining the string.

Note: This string resource has the same name as the element ID: edit_message. However,
references to resources are always scoped by the resource type (such as id or string), so
using the same name does not cause collisions.

Add String Resources

When you need to add text in the user interface, you should always specify each string as a
resource. String resources allow you to manage all UI text in a single location, which makes it
easier to find and update text. Externalizing the strings also allows you to localize your app to
different languages by providing alternative definitions for each string resource.

By default, your Android project includes a string resource file


at res/values/strings.xml. Add a new string named "edit_message" and set the
value to "Enter a message." (You can delete the "hello_world" string.)

While youre in this file, also add a "Send" string for the button youll soon add,
called "button_send".
The result for strings.xml looks like this:

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


<resources>
<string name="app_name">Simple UI</string>
<string name="edit_message">Enter a message</string>
<string name="button_send">Send</string>
<string name="action_settings">Settings</string>
<string name="title_activity_main">MainActivity</string>
</resources>

For more information about using string resources to localize your app for other languages, see
the Supporting Different Devices class.

Add a Button

Now add a <Button> to the layout, immediately following the <EditText> element:

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send" />

The height and width are set to "wrap_content" so the button is only as big as
necessary to fit the button's text. This button doesn't need the android:id attribute, because
it won't be referenced from the activity code.

Make the Input Box Fill in the Screen Width

The layout is currently designed so that both the EditText and Button widgets are only as
big as necessary to fit their content, as shown in figure 1.

Figure 1. The EditText and Button widgets have their widths set to "wrap_content".
This works fine for the button, but not as well for the text field, because the user might
type something longer. So, it would be nice to fill the unused screen width with the text field. You
can do this inside a LinearLayout with the weight property, which you can specify using
the android:layout_weight attribute.

The weight value is a number that specifies the amount of remaining space each view
should consume, relative to the amount consumed by sibling views. This works kind of like the
amount of ingredients in a drink recipe: "2 parts milk, 1 part coffee" means two-thirds of the drink
is milk. For example, if you give one view a weight of 2 and another one a weight of 1, the sum is
3, so the first view fills 2/3 of the remaining space and the second view fills the rest. If you add a
third view and give it a weight of 1, then the first view (with weight of 2) now gets 1/2 the
remaining space, while the remaining two each get 1/4.

The default weight for all views is 0, so if you specify any weight value greater than 0 to
only one view, then that view fills whatever space remains after all views are given the space
they require. So, to fill the remaining space in your layout with the EditText element, give it a
weight of 1 and leave the button with no weight.

<EditText
android:layout_weight="1"
... />

In order to improve the layout efficiency when you specify the weight, you should change
the width of the EditText to be zero (0dp). Setting the width to zero improves layout
performance because using "wrap_content" as the width requires the system to calculate a
width that is ultimately irrelevant because the weight value requires another width calculation to
fill the remaining space.

<EditText
android:layout_weight="1"
android:layout_width="0dp"
... />

Figure 2 shows the result when you assign all weight to the EditText element.
Figure 2. The EditText widget is given all the layout weight, so fills the remaining space in
the LinearLayout.

Heres how your complete layout file should now look:

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


<LinearLayout
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"
android:orientation="horizontal">
<EditText android:id="@+id/edit_message"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send" />
</LinearLayout>

This layout is applied by the default Activity class that the SDK tools generated
when you created the project, so you can now run the app to see the results:

In Eclipse, click Run from the toolbar.

Starting Another Activity


After completing the previous step, you have an app that shows an activity (a single screen) with
a text field and a button. In this section, youll add some code to MainActivity that starts a
new activity when the user clicks the Send button.

Respond to the Send Button


To respond to the button's on-click event, open the activity_main.xml layout file and add
the android:onClick attribute to the <Button> element:

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send"
android:onClick="sendMessage" />

The android:onClick attributes value, "sendMessage", is the name of a


method in your activity that the system calls when the user clicks the button.
Open the MainActivity class (located in the project's src/ directory) and add the
corresponding method:

/** Called when the user clicks the Send button */


public void sendMessage(View view) {
// Do something in response to button
}

This requires that you import the View class:

import android.view.View;

Tip: In Eclipse, press Ctrl + Shift + O to import missing classes.

In order for the system to match this method to the method name given
to android:onClick, the signature must be exactly as shown. Specifically, the method
must:

Be public
Have a void return value
Have a View as the only parameter (this will be the View that was clicked)

Next, youll fill in this method to read the contents of the text field and deliver that text to
another activity.

Build an Intent
An Intent is an object that provides runtime binding between separate components (such as
two activities). The Intent represents an apps "intent to do something." You can use intents
for a wide variety of tasks, but most often theyre used to start another activity.

Inside the sendMessage() method, create an Intent to start an activity called


DisplayMessageActivity:

Intent intent = new Intent(this,


DisplayMessageActivity.class);

SENDING AN INTENT TO OTHER APPS

The intent created in this lesson is what's considered an explicit intent, because
the Intent specifies the exact app component to which the intent should be given. However,
intents can also be implicit, in which case the Intent does not specify the desired component,
but allows any app installed on the device to respond to the intent as long as it satisfies the meta-
data specifications for the action that's specified in various Intent parameters. For more
information, see the class about Interacting with Other Apps.

The constructor used here takes two parameters:

A Context as its first parameter (this is used because the Activity class is a
subclass of Context)
The Class of the app component to which the system should deliver the Intent (in this
case, the activity that should be started)

Note: The reference to DisplayMessageActivity will raise an error if youre using an


IDE such as Eclipse because the class doesnt exist yet. Ignore the error for now; youll create
the class soon.

An intent not only allows you to start another activity, but it can carry a bundle of data to
the activity as well. Inside the sendMessage()method, use findViewById() to get
the EditText element and add its text value to the intent:

Intent intent = new Intent(this,


DisplayMessageActivity.class);
EditText editText = (EditText)
findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
Note: You now statements for android.content.Intent and
need import
android.widget.EditText. You'll define the EXTRA_MESSAGE constant in a moment.

An Intent can carry a collection of various data types as key-value pairs called extras.
The putExtra()method takes the key name in the first parameter and the value in the
second parameter.

In order for the next activity to query the extra data, you should define the key for your
intent's extra using a public constant. So add the EXTRA_MESSAGE definition to the top of
the MainActivity class:

public class MainActivity extends Activity {


public final static String EXTRA_MESSAGE =
"fsktm.ws.android.MESSAGE";
...
}

It's generally a good practice to define keys for intent extras using your app's package
name as a prefix. This ensures they are unique, in case your app interacts with other apps.

Start the Second Activity

To start an activity, call startActivity() and pass it your Intent. The system receives
this call and starts an instance of the Activity specified by the Intent.
With this new code, the complete sendMessage() method that's invoked by the Send button
now looks like this:

/** Called when the user clicks the Send button */


public void sendMessage(View view) {
Intent intent = new Intent(this,
DisplayMessageActivity.class);
EditText editText = (EditText)
findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}

Now you need to create the DisplayMessageActivity class in order for this to work.

Create the Second Activity

To create a new activity using Eclipse:


1. Click New in the toolbar.
2. In the window that appears, open the Android folder and select Android Activity.
Click Next.
3. Select BlankActivity and click Next.
4. Fill in the activity details:
o Project: Simpleui
o Activity Name: DisplayMessageActivity
o Layout Name: activity_display_message
o Title: My Message
o Hierarchial Parent: com.example.myfirstapp.MainActivity
o Navigation Type: None

Click Finish.

Figure 3. The new activity wizard in Eclipse.

If you're using a different IDE or the command line tools, create a new file named
DisplayMessageActivity.java in the project's src/ directory, next to the original
MainActivity.java file.
Open the DisplayMessageActivity.java file. If you used Eclipse to create this
activity:
The class already includes an implementation of the required onCreate() method.
There's also an implementation of the onCreateOptionsMenu() method, but you
won't need it for this app so you can remove it.
There's also an implementation of onOptionsItemSelected() which handles the
behavior for the action bar's Up behavior. Keep this one the way it is.
Because the ActionBar APIs are available only on HONEYCOMB (API level 11) and
higher, you must add a condition around the getActionBar() method to check the
current platform version. Additionally, you must add
the @SuppressLint("NewApi") tag to the onCreate() method to
avoid lint errors.
The DisplayMessageActivity class should now look like this:

public class DisplayMessageActivity extends Activity {

@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);

// Make sure we're running on Honeycomb or higher to


use ActionBar APIs
if (Build.VERSION.SDK_INT >=
Build.VERSION_CODES.HONEYCOMB) {
// Show the Up button in the action bar.
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
If you used an IDE other than Eclipse, update
your DisplayMessageActivity class with the above code.

All subclasses of Activity must implement the onCreate() method. The system
calls this when creating a new instance of the activity. This method is where you must define the
activity layout with the setContentView() method and is where you should perform initial
setup for the activity components.

ADD IT TO THE MANIFEST


All activities must be declared in your manifest file, AndroidManifest.xml, using
an <activity> element.

When you use the Eclipse tools to create the activity, it creates a default entry. If you're
using a different IDE, you need to add the manifest entry yourself. It should look like this:

<application ... >


...
<activity

android:name="com.example.myfirstapp.DisplayMessageActivity"
android:label="@string/title_activity_display_message"

android:parentActivityName="com.example.myfirstapp.MainActivit
y" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"

android:value="com.example.myfirstapp.MainActivity" />
</activity>
</application>

The android:parentActivityName attribute declares the name of this activity's


parent activity within the app's logical hierarchy. The system uses this value to implement default
navigation behaviors, such as Up navigation on Android 4.1 (API level 16) and higher. You can
provide the same navigation behaviors for older versions of Android by using the Support
Library and adding the <meta-data> element as shown here.

Note: Your Android SDK should already include the latest Android Support Library. It's included
with the ADT Bundle but if you're using a different IDE, you should have installed it during
the Adding Platforms and Packages step. When using the templates in Eclipse, the Support
Library is automatically added to your app project (you can see the library's JAR file listed
under Android Dependencies). If you're not using Eclipse, you need to manually add the library
to your projectfollow the guide for setting up the Support Library then return here.
If you're developing with Eclipse, you can run the app now, but not much happens.
Clicking the Send button starts the second activity but it uses a default "Hello world" layout
provided by the template. You'll soon update the activity to instead display a custom text view, so
if you're using a different IDE, don't worry that the app won't yet compile.

Receive the Intent

Every Activity is invoked by an Intent, regardless of how the user navigated there. You
can get the Intent that started your activity by calling getIntent() and retrieve the data
contained within it.

In the DisplayMessageActivity classs onCreate() method, get the intent


and extract the message delivered by MainActivity:

Intent intent = getIntent();


String message =
intent.getStringExtra(MainActivity.EXTRA_MESSAGE);

Display the Message

To show the message on the screen, create a TextView widget and set the text
using setText(). Then add the TextView as the root view of the activitys layout by
passing it to setContentView().

The complete onCreate() method for DisplayMessageActivity now looks like this:

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

// Get the message from the intent


Intent intent = getIntent();
String message =
intent.getStringExtra(MainActivity.EXTRA_MESSAGE);

// Create the text view


TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);

// Set the text view as the activity layout


setContentView(textView);
}

You can now run the app. When it opens, type a message in the text field, click Send, and the
message appears on the second activity.
Figure 4. Both activities in the final app, running on Android 4.0.

That's it, you've built your first simple user interface app!
ListView
This section will teach you how to build simple android ListView. This article is about creating
listview and launching new activity on selecting single list item. Below is screenshot of final
output.

Figure 1. Android ListView.

Crate a new project for Listview


Create a new project by going to File New Android Project. Fill all the details and name your
activity as MyListView. Fill package name with fsktm.ws.android.mylistview.

Then set the Target SDK same with your virtual/real android version. Then
click Next twice and finish. Once the project is created open your main activity java file (in
this case MainActivity.java) and extend the class from ListActivity, and then
remove the line code in line 12. The complete code will be as the following code:
package fsktm.ws.android.mylistview;

import android.os.Bundle;
import android.app.ListActivity;

public class MainActivity extends ListActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//TO DO here

}
}

If there is many error appear in eclipse editor, you have to do this, move your cursor to
the ListActivity text, then click Import "ListActivity" (android.app).

Now we need a string resources file to store all list item labels. So create an XML file
under values folder and name it as list_data.xml, you can do by Right Click
on res/values > New > Android XML File > list_data [enter], and
paste the following code.

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


<resources>
<string-array name="adobe_products">
<item>Adobe After Effects</item>
<item>Adobe Bridge</item>
<item>Adobe Dreamweaver</item>
<item>Adobe Edge</item>
<item>Adobe Fireworks</item>
<item>Adobe Flash</item>
<item>Adobe Photoshop</item>
<item>Adobe Premiere</item>
<item>Adobe Reader</item>
<item>Adobe Illustrator</item>
</string-array>
</resources>

In ListView each list item will be an xml layout, so we can customize each list item.
Create an XML file under res/layout folder and name it as list_item.xml (you can do
by Right Click on res/layout > New > Android XML File, then type the name),
and then type the following code.

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


<!-- Single List Item Design -->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/label"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:textStyle="bold" >
</TextView>

This xml layout will be single list item row.

Now open your main activity java file (MyListView.java). Paste the code bellow
under //TO DO here. The complete code will be as following code:

package fsktm.ws.android.mylistview;

import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.app.ListActivity;

public class MainActivity extends ListActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//TO DO here
// storing string resources into Array
String[] adobe_products =
getResources().getStringArray(R.array.adobe_products);

// Binding resources Array to ListAdapter


this.setListAdapter(new ArrayAdapter<String>(this,
R.layout.list_item, R.id.label, adobe_products));
}
}

In that code xml resources data was imported and storing them in an Array
(adobe_products). The next line code is binding the array to ListAdapter.

Now run your project you can see listview with list of array items, as shown in
the figure 2. But on clicking single list item you can see no action. So we need to start new
activity on selecting single list item.
Figure 2.MyListView screen show the list.

Launching new Activity on selecting single list item


Now create new activity class under src folder. Right Click on src/package folder >
New > Class and name it as SingleListItem. (SingleListItem.java).
Open your MyListView.java and modify the code to following. In the following code the
selected list item string(product name) will be send to the new Activity.

package fsktm.ws.android.mylistview;

import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.app.ListActivity;
///
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.content.Intent;

public class MainActivity extends ListActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//TO DO here
// storing string resources into Array
String[] adobe_products =
getResources().getStringArray(R.array.adobe_products);

// Binding resources Array to ListAdapter


this.setListAdapter(new ArrayAdapter<String>(this,
R.layout.list_item, R.id.label, adobe_products));

ListView lv = getListView();
// listening to single list item on click
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View
view,
int position, long id) {

// selected item
String product = ((TextView)
view).getText().toString();

// Launching new Activity on selecting single


List Item
Intent i = new Intent(getApplicationContext(),
SingleListItem.class);
// sending data to new activity
i.putExtra("product", product);
startActivity(i);
}
});
}
}

Now in new activity we need to display the received from listview activity.

Create a new xml file under res/layout and name it


as single_list_item_view.xml and type the following code. This XML file will be
layout for SingleListItem.java

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


<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:id="@+id/product_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textStyle="bold"
android:padding="10dp" />
</LinearLayout>

Now open your second activity file i.e SingleListItem.java and paste the
following code.

package fsktm.ws.android.mylistview;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class SingleListItem extends Activity{


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.single_list_item_view);

TextView txtProduct = (TextView)


findViewById(R.id.product_label);

Intent i = getIntent();
// getting attached intent data
String product = i.getStringExtra("product");
// displaying selected product name
txtProduct.setText(product);

}
}

The final step is to add an entry of new activity name in AndroidManifest.xml file.
Open your AndroidManifest.xml file and modify the code as below.

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


<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="fsktm.ws.android.mylistview"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="14" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity

android:name="fsktm.ws.android.mylistview.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>
<activity android:name=".SingleListItem"
android:label="Single Item
Selected"></activity>
</application>

</manifest>

Finally run your project by right clicking on your project folder > Run As > 1 Android
Application.
Figure 2. Android ListView.

Figure 3.Show the selected item


Connect with PHP and
MySQL
We are going see how to make a very simple Android app (in our case, a product inventory app)
that will call a PHP script to perform basic CRUD(Create, Read, Update, Delete) operations. To
brief you on the architecture, this is how it works. First your android app calls a PHP script in
order to perform a data operation, lets say create. The PHP script then connects to your
MySQL database to perform the operation. So the data flows from your Android app to PHP
script then finally is stored in your MySQL database. All right, lets dig deeper.

Please note that the purpose of the code that I have provided here is to, ease you
(beginner level) into connecting an Android app with PHP, MYSQL. You should not take this as a
standard or secure coding practice. In production environment, you ideally need to avoid any
code that will potentially inject vulnerabilities (like MYSQL Injection). MySQL injection itself is a
huge topic and cannot be covered in this single post and that is not the agenda of this post
either.

What is XAMPP
XAMPP is an easy to install Apache distribution containing MySQL, PHP and Perl. XAMPP is
really very easy to install and to use - just download, extract and start. By installing this software
you will be installing Apache, MySQL and PHP.

Installing and Running XAMPP


Download & Install XAMPP from www.apachefriends.org/en. Once you have installed XAMPP,
launch the program from folder installation and dobleclick on xampp-control.exe, see
figure-1, and then in windows Xampp-console click start button for Apache and MySQL, see
figure-2, You can test your server by opening the address http://localhost/ in your browser. Also
you can check phpmyadmin by openinghttp://localhost/phpmyadmin.
Figure 1.Starting XAMPP.

Figure 2.Starting Apache and MySQL.

Creating MySQL Database and Tables


This lesson used a simple database with one table, to perform example operations. Now open
phpmyadmin by opening the address http://localhost/phpmyadmin/ in your browser. You can use
the PhpMyAdmin tool to create a database and a table.

CREATE DATABASE mydb;


Figure 3.Create database using phpMyAdmin.

CREATE TABLE products(


pid int(11) primary key auto_increment,
name varchar(100) not null,
price decimal(10,2) not null,
description text,
created_at timestamp default now(),
updated_at timestamp
);
Figure 4.Create table using phpMyAdmin.

Connecting to MySQL database using PHP


Now the actual server side coding starts. Create a folder bellow ../XAMPP/htdocs folder
and name it as mobile_services. Create a PHP class to connect to MySQL database. The
main purpose of this class is to open a connection to database and close the connection
whenever its not needed. So create two files called db_config.php
and db_connect.php, and put those in mobile_services folder.

db_config.php will have database connection variables


db_connect.php a class file to connect to database
Following is code for two php files:

db_config.php
<?php

/*
* All database connection variables
*/

define('DB_USER', "root"); // db user


define('DB_PASSWORD', ""); // db password (mention your db
password here)
define('DB_DATABASE', "mydb"); // database name
define('DB_SERVER', "localhost"); // db server
?>

db_connect.php
<?php

/**
* A class file to connect to database
*/
class DB_CONNECT {

// constructor
function __construct() {
// connecting to database
$this->connect();
}

// destructor
function __destruct() {
// closing db connection
$this->close();
}

/**
* Function to connect with database
*/
function connect() {
// import database connection variables
require_once __DIR__ . '/db_config.php';

// Connecting to mysql database


$con = mysql_connect(DB_SERVER, DB_USER, DB_PASSWORD)
or die(mysql_error());

// Selecing database
$db = mysql_select_db(DB_DATABASE) or
die(mysql_error()) or die(mysql_error());

// returing connection cursor


return $con;
}

/**
* Function to close db connection
*/
function close() {
// closing db connection
mysql_close();
}

?>

Usage: When ever you want to connect to MySQL database and do some operations use
the db_connect.php class like this

$db = new DB_CONNECT(); // creating class object(will open


database connection)

Basic MySQL CRUD Operations using


PHP
This lesson covers basic CRUD (Create, Read, Update, Delete) operations on MySQL database
using PHP. If you are a novice about PHP and MySQL, you can learn basic PHPand SQL here.

Creating a row in MySQL (Creating a new product


row)
In your PHP project create a new php file called create_product.php and place the
following code. This file is mainly for creating a new product in products table. The following code
will read product data via POST and storing them in products table. At the end the code echoing
appropriate JSON as response.
create_product.php
<?php

/*
* Following code will create a new product row
* All product details are read from HTTP Post Request
*/

// array for JSON response


$response = array();

// check for required fields


if (isset($_POST['name']) && isset($_POST['price']) &&
isset($_POST['description'])) {

$name = $_POST['name'];
$price = $_POST['price'];
$description = $_POST['description'];

// include db connect class


require_once __DIR__ . '/db_connect.php';

// connecting to db
$db = new DB_CONNECT();

// mysql inserting a new row


$result = mysql_query("INSERT INTO products(name, price,
description) VALUES('$name', '$price', '$description')");

// check if row inserted or not


if ($result) {
// successfully inserted into database
$response["success"] = 1;
$response["message"] = "Product successfully
created.";

// echoing JSON response


echo json_encode($response);
} else {
// failed to insert row
$response["success"] = 0;
$response["message"] = "Oops! An error occurred.";

// echoing JSON response


echo json_encode($response);
}
} else {
// required field is missing
$response["success"] = 0;
$response["message"] = "Required field(s) is missing";
// echoing JSON response
echo json_encode($response);
}
?>

For the above code JSON response will be like

{
"success": 0,
"message": "Required field(s) is missing"
}

When POST param(s) is missing

{
"success": 1,
"message": "Product successfully created."
}

When product is successfully created

{
"success": 0,
"message": "Oops! An error occurred."
}

When error occurred while inserting data

Reading a Row from MySQL (Reading product


details)
Create a new php file called get_product_details.php and write the following code.
This file will get single product details by taking product id (pid) as post parameter.

get_product_details.php
<?php

/*
* Following code will get single product details
* A product is identified by product id (pid)
*/

// array for JSON response


$response = array();
// include db connect class
require_once __DIR__ . '/db_connect.php';

// connecting to db
$db = new DB_CONNECT();

// check for post data


if (isset($_GET["pid"])) {
$pid = $_GET['pid'];

// get a product from products table


$result = mysql_query("SELECT *FROM products WHERE pid =
$pid");

if (!empty($result)) {
// check for empty result
if (mysql_num_rows($result) > 0) {

$result = mysql_fetch_array($result);

$product = array();
$product["pid"] = $result["pid"];
$product["name"] = $result["name"];
$product["price"] = $result["price"];
$product["description"] = $result["description"];
$product["created_at"] = $result["created_at"];
$product["updated_at"] = $result["updated_at"];
// success
$response["success"] = 1;

// user node
$response["product"] = array();

array_push($response["product"], $product);

// echoing JSON response


echo json_encode($response);
} else {
// no product found
$response["success"] = 0;
$response["message"] = "No product found";

// echo no users JSON


echo json_encode($response);
}
} else {
// no product found
$response["success"] = 0;
$response["message"] = "No product found";
// echo no users JSON
echo json_encode($response);
}
} else {
// required field is missing
$response["success"] = 0;
$response["message"] = "Required field(s) is missing";

// echoing JSON response


echo json_encode($response);
}
?>

The json response for the above file will be

{
"success": 1,
"product": [
{
"pid": "1",
"name": "iPHone 4S",
"price": "300.00",
"description": "iPhone 4S white",
"created_at": "2012-04-29 01:41:42",
"updated_at": "0000-00-00 00:00:00"
}
]
}

When successfully getting product details

{
"success": 0,
"message": "No product found"
}

When no product found with matched pid

Reading All Rows from MySQL (Reading all


products)
We need a json to list all the products on android device. So create a new php file named
get_all_products.php and write following code.

get_all_products.php
<?php
/*
* Following code will list all the products
*/

// array for JSON response


$response = array();

// include db connect class


require_once __DIR__ . '/db_connect.php';

// connecting to db
$db = new DB_CONNECT();

// get all products from products table


$result = mysql_query("SELECT *FROM products") or
die(mysql_error());

// check for empty result


if (mysql_num_rows($result) > 0) {
// looping through all results
// products node
$response["products"] = array();

while ($row = mysql_fetch_array($result)) {


// temp user array
$product = array();
$product["pid"] = $row["pid"];
$product["name"] = $row["name"];
$product["price"] = $row["price"];
$product["created_at"] = $row["created_at"];
$product["updated_at"] = $row["updated_at"];

// push single product into final response array


array_push($response["products"], $product);
}
// success
$response["success"] = 1;

// echoing JSON response


echo json_encode($response);
} else {
// no products found
$response["success"] = 0;
$response["message"] = "No products found";

// echo no users JSON


echo json_encode($response);
}
?>

And the JSON response for above code will be like


{
"products": [
{
"pid": "1",
"name": "iPhone 4S",
"price": "300.00",
"created_at": "2012-04-29 02:04:02",
"updated_at": "0000-00-00 00:00:00"
},
{
"pid": "2",
"name": "Macbook Pro",
"price": "600.00",
"created_at": "2012-04-29 02:04:51",
"updated_at": "0000-00-00 00:00:00"
},
{
"pid": "3",
"name": "Macbook Air",
"price": "800.00",
"created_at": "2012-04-29 02:05:57",
"updated_at": "0000-00-00 00:00:00"
},
{
"pid": "4",
"name": "OS X Lion",
"price": "100.00",
"created_at": "2012-04-29 02:07:14",
"updated_at": "0000-00-00 00:00:00"
}
],
"success": 1
}

Listing all Products

{
"success": 0,
"message": "No products found"
}

When products not found

Updating a Row in MySQL (Updating product details)


Create a php file named update_product.php to update product details. Each product is
identified by pid.
update_product.php
<?php

/*
* Following code will update a product information
* A product is identified by product id (pid)
*/

// array for JSON response


$response = array();

// check for required fields


if (isset($_POST['pid']) && isset($_POST['name']) &&
isset($_POST['price']) && isset($_POST['description'])) {

$pid = $_POST['pid'];
$name = $_POST['name'];
$price = $_POST['price'];
$description = $_POST['description'];

// include db connect class


require_once __DIR__ . '/db_connect.php';

// connecting to db
$db = new DB_CONNECT();

// mysql update row with matched pid


$result = mysql_query("UPDATE products SET name = '$name',
price = '$price', description = '$description' WHERE pid =
$pid");

// check if row inserted or not


if ($result) {
// successfully updated
$response["success"] = 1;
$response["message"] = "Product successfully
updated.";

// echoing JSON response


echo json_encode($response);
} else {

}
} else {
// required field is missing
$response["success"] = 0;
$response["message"] = "Required field(s) is missing";

// echoing JSON response


echo json_encode($response);
}
?>

The json reponse of above code, when product is updated successfully

{
"success": 1,
"message": "Product successfully updated."
}

Deleting a Row in MySQL (Deleting a product)


The last operation is deletion on database. Create a new php file called
delete_product.php and paste the following code. The main functionality of this file is to
delete a product from database.

delete_product.php
<?php

/*
* Following code will delete a product from table
* A product is identified by product id (pid)
*/

// array for JSON response


$response = array();

// check for required fields


if (isset($_POST['pid'])) {
$pid = $_POST['pid'];

// include db connect class


require_once __DIR__ . '/db_connect.php';

// connecting to db
$db = new DB_CONNECT();

// mysql update row with matched pid


$result = mysql_query("DELETE FROM products WHERE pid =
$pid");

// check if row deleted or not


if (mysql_affected_rows() > 0) {
// successfully updated
$response["success"] = 1;
$response["message"] = "Product successfully deleted";

// echoing JSON response


echo json_encode($response);
} else {
// no product found
$response["success"] = 0;
$response["message"] = "No product found";

// echo no users JSON


echo json_encode($response);
}
} else {
// required field is missing
$response["success"] = 0;
$response["message"] = "Required field(s) is missing";

// echoing JSON response


echo json_encode($response);
}
?>

And the JSON response for above code will be like

{
"success": 1,
"message": "Product successfully deleted"
}

When product successfully deleted

{
"success": 0,
"message": "No product found"
}

When product not found

Until now, we built a simple api for our products table. We are now done with the server
side coding (PHP) and its time to take a break and start our actual android application coding.

Creating Android Application


Create a new project in your Eclipse IDE by filling the required details.

Create new project in Eclipse IDE by going to File > New > Android Project
and name the Activity class name as MyCompany.
Open your AndroidManifest.xml file and add following code. First add all the
classes that will created in this project to manifest file. Also add a uses-permission item
i.e. INTERNET Connect permission.

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

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

<!-- Internet Permissions -->


<uses-permission
android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:configChanges="keyboardHidden|orientation"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity

android:name="fsktm.ws.android.mycompany.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>

<!-- All Product Activity -->


<activity
android:name=".AllProductsActivity"
android:label="All Products" >
</activity>

<!-- Add Product Activity -->


<activity
android:name=".NewProductActivity"
android:label="Add New Product" >
</activity>

<!-- Edit Product Activity -->


<activity
android:name=".EditProductActivity"
android:label="Edit Product" >
</activity>
</application>

</manifest>

Modify xml file res/values/strings.xml to the following code:

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

<string name="app_name">MyCompany</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="view_products">View Products</string>
<string name="add_new_product">Add New Products</string>
<string name="product_name">Product Name</string>
<string name="price">Price</string>
<string name="description">Description</string>
<string name="create_product">Create Product</string>
<string name="save_changes">Save Changes</string>
<string name="delete">Delete</string>

</resources>

Now create a new xml file under res > layout folder and name it as
main_screen.xml. This layout file contains two simple buttons to view all products and add
a new product.
main_screen.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"
android:gravity="center_horizontal">

<!-- Sample Dashboard screen with Two buttons -->


<!-- Button to view all products screen -->
<Button android:id="@+id/btnViewProducts"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="View Products"
android:onClick="ViewProducts"
android:layout_marginTop="25dp"/>

<!-- Button to create a new product screen -->


<Button android:id="@+id/btnCreateProduct"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Add New Products"
android:onClick="AddNewProduct"
android:layout_marginTop="25dip"/>

</LinearLayout>

Open you main activity class which is MainActivity.java and write click events
for two button which are mentioned in main_screen.xml layout.

package fsktm.ws.android.mycompany;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;

public class MainActivity extends Activity {

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

public void ViewProducts(View v) {


// Launching All products Activity
Intent i = new Intent(getApplicationContext(),
AllProductsActivity.class);
startActivity(i);
}

public void AddNewProduct(View v) {


// Launching create new product activity
Intent i = new Intent(getApplicationContext(),
NewProductActivity.class);
startActivity(i);
}
}

Figure 4.Main menu of MyCompany apps.

JSON Parser Class


This lesson used a JSON Parser class to get JSON from URL. This class supports two http
request methods GET and POST to get json from url. The complete code is as folllow:

JSONParser.java
package fsktm.ws.android.mycompany;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class JSONParser {

static InputStream is = null;


static JSONObject jObj = null;
static String json = "";

// constructor
public JSONParser() {

// function get json from url


// by making HTTP POST or GET mehtod
public JSONObject makeHttpRequest(String url, String
method,
List<NameValuePair> params) {

// Making HTTP request


try {

// check for request method


if(method == "POST"){
// request method is POST
// defaultHttpClient
DefaultHttpClient httpClient = new
DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new
UrlEncodedFormEntity(params));
HttpResponse httpResponse =
httpClient.execute(httpPost);
HttpEntity httpEntity =
httpResponse.getEntity();
is = httpEntity.getContent();

}else if(method == "GET"){


// request method is GET
DefaultHttpClient httpClient = new
DefaultHttpClient();
String paramString =
URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);

HttpResponse httpResponse =
httpClient.execute(httpGet);
HttpEntity httpEntity =
httpResponse.getEntity();
is = httpEntity.getContent();
}

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

try {
BufferedReader reader = new BufferedReader(new
InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " +
e.toString());
}

// try parse the string to a JSON object


try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " +
e.toString());
}

// return JSON String


return jObj;

}
}

Adding a New Product (Write)


Create a new view and acivity to add a new product into mysql database. Create a simple form
which contains EditText for product name, price and description. Create a new xml file
in res/layout folder and name it as add_product.xml and paste the following code to
create a simple form.

add_product.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" >

<!-- Name Label -->

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:text="@string/product_name"
android:textSize="17sp" />

<!-- Input Name -->

<EditText
android:id="@+id/inputName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_marginBottom="15dp"
android:inputType="text"
android:singleLine="true" />
<!-- Price Label -->

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:text="@string/price"
android:textSize="17sp" />

<!-- Input Price -->


<EditText android:id="@+id/inputPrice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_marginBottom="15dp"
android:singleLine="true"
android:inputType="numberDecimal"/>

<!-- Description Label -->

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:text="@string/description"
android:textSize="17sp" />

<!-- Input description -->

<EditText
android:id="@+id/inputDesc"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_marginBottom="15dp"
android:gravity="top"
android:inputType="text"
android:lines="4" />

<!-- Button Create Product -->

<Button
android:id="@+id/btnCreateProduct"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="AddProduct"
android:text="@string/create_product" />

</LinearLayout>

Now create new Activity to insert a new product into mysql database. Create a class file
and name it as NewProductActivity.java and type the following code. In the following
code:

1. First new product data is read from the EditText form and formatted into a basic params.
2. A request is made to create_product.php to create a new product through HTTP
post.
3. After getting json response from create_product.php, If success bit is 1 then list
view is refreshed with newly added product.

NewProductActivity.java
package fsktm.ws.android.mycompany;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;

public class NewProductActivity extends Activity {

// Progress Dialog
private ProgressDialog pDialog;

JSONParser jsonParser = new JSONParser();


EditText inputName;
EditText inputPrice;
EditText inputDesc;

// url to create new product


private static String url_create_product =
"http://10.0.2.2/mobile_services/create_product.php";
// JSON Node names
private static final String TAG_SUCCESS = "success";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_product);

if (android.os.Build.VERSION.SDK_INT > 8) {
StrictMode.ThreadPolicy th = new
StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(th);
}

// Edit Text
inputName = (EditText) findViewById(R.id.inputName);
inputPrice = (EditText) findViewById(R.id.inputPrice);
inputDesc = (EditText) findViewById(R.id.inputDesc);

public void AddProduct(View v){


new CreateNewProduct().execute();
}

/**
* Background Async Task to Create new product
* */
class CreateNewProduct extends AsyncTask<String, String,
String> {

/**
* Before starting background thread Show Progress
Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new
ProgressDialog(NewProductActivity.this);
pDialog.setMessage("Creating Product..");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}

/**
* Creating product
* */
protected String doInBackground(String... args) {
String name = inputName.getText().toString();
String price = inputPrice.getText().toString();
String description =
inputDesc.getText().toString();

// Building Parameters
List<NameValuePair> params = new
ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("name", name));
params.add(new BasicNameValuePair("price",
price));
params.add(new BasicNameValuePair("description",
description));

// getting JSON Object


// Note that create product url accepts POST
method
JSONObject json =
jsonParser.makeHttpRequest(url_create_product,
"POST", params);

// check log cat fro response


Log.d("Create Response", json.toString());

// check for success tag


try {
int success = json.getInt(TAG_SUCCESS);

if (success == 1) {
// successfully created product
Intent i = new
Intent(getApplicationContext(), AllProductsActivity.class);
startActivity(i);

// closing this screen


finish();
} else {
// failed to create product
}
} catch (JSONException e) {
e.printStackTrace();
}

return null;
}

/**
* After completing background task Dismiss the
progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once done
pDialog.dismiss();
}

}
}

Figure 5.Add new product.

Displaying All Products in ListView (Read)


Now we need an Activity display all the products in list view format. As we know list view needs
two xml files, one for listview and other is for single list row. Create two xml files under res >
layout folder and name it as all_products.xml and list_item.xml.
all_products.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">
<!-- Main ListView
Always give id value as list(@android:id/list)
-->
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>

</LinearLayout>

list_item.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="wrap_content"
android:orientation="vertical" >

<!-- Product id (pid) - will be HIDDEN - used to pass to


other activity -->
<TextView
android:id="@+id/pid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone" />

<!-- Name Label -->


<TextView
android:id="@+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="6dp"
android:paddingLeft="6dp"
android:textSize="17sp"
android:textStyle="bold" />

</LinearLayout>

Create a new class file and name it as AllProductsActivity.java. In the following


code:
1. First a request is send to get_all_products.php file using a Background Async task
thread.
2. After getting JSON from get_all_products.php, parsed it and displayed in a
listview.
3. If there are no products found AddNewProductAcivity is launched.

AllProductsActivity.java
package fsktm.ws.android.mycompany;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.NameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class AllProductsActivity extends ListActivity {

// Progress Dialog
private ProgressDialog pDialog;

// Creating JSON Parser object


JSONParser jParser = new JSONParser();

ArrayList<HashMap<String, String>> productsList;

// url to get all products list


private static String url_all_products =
"http://10.0.2.2/mobile_services/get_all_products.php";
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_PRODUCTS = "products";
private static final String TAG_PID = "pid";
private static final String TAG_NAME = "name";

// products JSONArray
JSONArray products = null;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.all_products);

// Hashmap for ListView


productsList = new ArrayList<HashMap<String,
String>>();

// Loading products in Background Thread


new LoadAllProducts().execute();

// Get listview
ListView lv = getListView();

// on seleting single product


// launching Edit Product Screen
lv.setOnItemClickListener(new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> parent,
View view,
int position, long id) {
// getting values from selected ListItem
String pid = ((TextView)
view.findViewById(R.id.pid)).getText()
.toString();

// Starting new intent


Intent in = new
Intent(getApplicationContext(),
EditProductActivity.class);
// sending pid to next activity
in.putExtra(TAG_PID, pid);

// starting new activity and expecting some


response back
startActivityForResult(in, 100);
}
});
}

// Response from Edit Product Activity


@Override
protected void onActivityResult(int requestCode, int
resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// if result code 100
if (resultCode == 100) {
// if result code 100 is received
// means user edited/deleted product
// reload this screen again
Intent intent = getIntent();
finish();
startActivity(intent);
}

/**
* Background Async Task to Load all product by making
HTTP Request
* */
class LoadAllProducts extends AsyncTask<String, String,
String> {

/**
* Before starting background thread Show Progress
Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new
ProgressDialog(AllProductsActivity.this);
pDialog.setMessage("Loading products. Please
wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}

/**
* getting All products from url
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new
ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json =
jParser.makeHttpRequest(url_all_products, "GET", params);

// Check your log cat for JSON reponse


Log.d("All Products: ", json.toString());

try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);

if (success == 1) {
// products found
// Getting Array of Products
products =
json.getJSONArray(TAG_PRODUCTS);

// looping through All Products


for (int i = 0; i < products.length();
i++) {
JSONObject c =
products.getJSONObject(i);

// Storing each json item in variable


String id = c.getString(TAG_PID);
String name = c.getString(TAG_NAME);

// creating new HashMap


HashMap<String, String> map = new
HashMap<String, String>();

// adding each child node to HashMap


key => value
map.put(TAG_PID, id);
map.put(TAG_NAME, name);

// adding HashList to ArrayList


productsList.add(map);
}
} else {
// no products found
// Launch Add New product Activity
Intent i = new
Intent(getApplicationContext(),
NewProductActivity.class);
// Closing all previous activities

i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
} catch (JSONException e) {
e.printStackTrace();
}

return null;
}

/**
* After completing background task Dismiss the
progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
AllProductsActivity.this,
productsList,
R.layout.list_item, new String[] {
TAG_PID,
TAG_NAME},
new int[] { R.id.pid, R.id.name
});
// updating listview
setListAdapter(adapter);
}
});

}
}
Figure 5.Add new product.

Reading, Updating and Deleting a Single Product


If you notice the AllProductsActivity.java, in listview, the code launching
EditProductAcivity.java once a single list item is selected. So create xml file
called edit_product.xml and create a form which is same as create_product.xml.

edit_product.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" >

<!-- Name Label -->


<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:text="@string/product_name"
android:textSize="17sp" />

<!-- Input Name -->

<EditText
android:id="@+id/inputName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_marginBottom="15dp"
android:inputType="text"
android:singleLine="true" />

<!-- Price Label -->

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:text="@string/price"
android:textSize="17sp" />

<!-- Input Price -->


<EditText android:id="@+id/inputPrice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_marginBottom="15dp"
android:singleLine="true"
android:inputType="numberDecimal"/>

<!-- Description Label -->

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="10dp"
android:text="@string/description"
android:textSize="17sp" />
<!-- Input description -->

<EditText
android:id="@+id/inputDesc"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_marginBottom="15dp"
android:gravity="top"
android:inputType="text"
android:lines="4" />

<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Button Create Product -->

<Button
android:id="@+id/btnSave"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="SaveProduct"
android:text="@string/save_changes" />

<!-- Button Create Product -->

<Button
android:id="@+id/btnDelete"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="DeleteProduct"
android:text="@string/delete" />

</LinearLayout>

</LinearLayout>

Create a class file for edit_product.xml and name it as


EditProductActivity.java and fill it with following code. In the following code:

1. First product id (pid) is read from the intent which is sent from listview.
2. A request is made to get_product_details.php and after getting product details in
json format, parsed the json and displayed in EditText.
3. After displaying product data in the form if user clicks on Save Changes Button, another
HTTP request is made to update_product.php to store updated product data.
4. If the user selected Delete Product Button, HTTP request is made to
delete_product.php and product is deleted from mysql database, and listview is
refreshed with new product list.

EditProductActivity.java
package fsktm.ws.android.mycompany;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class EditProductActivity extends Activity {

EditText txtName;
EditText txtPrice;
EditText txtDesc;
EditText txtCreatedAt;
Button btnSave;
Button btnDelete;

String pid;

// Progress Dialog
private ProgressDialog pDialog;

// JSON parser class


JSONParser jsonParser = new JSONParser();

// single product url


private static final String url_product_detials =
"http://10.0.2.2/mobile_services/get_product_details.php";

// url to update product


private static final String url_update_product =
"http://10.0.2.2/mobile_services/update_product.php";

// url to delete product


private static final String url_delete_product =
"http://10.0.2.2/mobile_services/delete_product.php";

// JSON Node names


private static final String TAG_SUCCESS = "success";
private static final String TAG_PRODUCT = "product";
private static final String TAG_PID = "pid";
private static final String TAG_NAME = "name";
private static final String TAG_PRICE = "price";
private static final String TAG_DESCRIPTION =
"description";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_product);

if (android.os.Build.VERSION.SDK_INT > 8) {
StrictMode.ThreadPolicy th = new
StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(th);
}

// getting product details from intent


Intent i = getIntent();

// getting product id (pid) from intent


pid = i.getStringExtra(TAG_PID);

// Getting complete product details in background


thread
new GetProductDetails().execute();

public void SaveProduct(View v){


// starting background task to update product
new SaveProductDetails().execute();
}

public void DeleteProduct(View v) {


// deleting product in background thread
new DeleteProduct().execute();
}

/**
* Background Async Task to Get complete product details
* */
class GetProductDetails extends AsyncTask<String, String,
String> {

/**
* Before starting background thread Show Progress
Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new
ProgressDialog(EditProductActivity.this);
pDialog.setMessage("Loading product details.
Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}

/**
* Getting product details in background thread
* */
protected String doInBackground(String... params) {

// updating UI from Background Thread


runOnUiThread(new Runnable() {
public void run() {
// Check for success tag
int success;
try {
// Building Parameters
List<NameValuePair> params = new
ArrayList<NameValuePair>();
params.add(new
BasicNameValuePair("pid", pid));

// getting product details by making


HTTP request
// Note that product details url will
use GET request
JSONObject json =
jsonParser.makeHttpRequest(
url_product_detials, "GET",
params);
// check your log for json response
Log.d("Single Product Details",
json.toString());

// json success tag


success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// successfully received product
details
JSONArray productObj = json

.getJSONArray(TAG_PRODUCT); // JSON Array

// get first product object from


JSON Array
JSONObject product =
productObj.getJSONObject(0);

// product with this pid found


// Edit Text
txtName = (EditText)
findViewById(R.id.inputName);
txtPrice = (EditText)
findViewById(R.id.inputPrice);
txtDesc = (EditText)
findViewById(R.id.inputDesc);

// display product data in


EditText

txtName.setText(product.getString(TAG_NAME));

txtPrice.setText(product.getString(TAG_PRICE));

txtDesc.setText(product.getString(TAG_DESCRIPTION));

}else{
// product with pid not found
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});

return null;
}

/**
* After completing background task Dismiss the
progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once got all details
pDialog.dismiss();
}
}

/**
* Background Async Task to Save product Details
* */
class SaveProductDetails extends AsyncTask<String, String,
String> {

/**
* Before starting background thread Show Progress
Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new
ProgressDialog(EditProductActivity.this);
pDialog.setMessage("Saving product ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}

/**
* Saving product
* */
protected String doInBackground(String... args) {

// getting updated data from EditTexts


String name = txtName.getText().toString();
String price = txtPrice.getText().toString();
String description = txtDesc.getText().toString();

// Building Parameters
List<NameValuePair> params = new
ArrayList<NameValuePair>();
params.add(new BasicNameValuePair(TAG_PID, pid));
params.add(new BasicNameValuePair(TAG_NAME,
name));
params.add(new BasicNameValuePair(TAG_PRICE,
price));
params.add(new BasicNameValuePair(TAG_DESCRIPTION,
description));
// sending modified data through http request
// Notice that update product url accepts POST
method
JSONObject json =
jsonParser.makeHttpRequest(url_update_product,
"POST", params);

// check json success tag


try {
int success = json.getInt(TAG_SUCCESS);

if (success == 1) {
// successfully updated
Intent i = getIntent();
// send result code 100 to notify about
product update
setResult(100, i);
finish();
} else {
// failed to update product
}
} catch (JSONException e) {
e.printStackTrace();
}

return null;
}

/**
* After completing background task Dismiss the
progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once product uupdated
pDialog.dismiss();
}
}

/*************************************************************
****
* Background Async Task to Delete Product
* */
class DeleteProduct extends AsyncTask<String, String,
String> {

/**
* Before starting background thread Show Progress
Dialog
* */
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new
ProgressDialog(EditProductActivity.this);
pDialog.setMessage("Deleting Product...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}

/**
* Deleting product
* */
protected String doInBackground(String... args) {

// Check for success tag


int success;
try {
// Building Parameters
List<NameValuePair> params = new
ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("pid",
pid));

// getting product details by making HTTP


request
JSONObject json = jsonParser.makeHttpRequest(
url_delete_product, "POST", params);

// check your log for json response


Log.d("Delete Product", json.toString());

// json success tag


success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// product successfully deleted
// notify previous activity by sending
code 100
Intent i = getIntent();
// send result code 100 to notify about
product deletion
setResult(100, i);
finish();
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}

/**
* After completing background task Dismiss the
progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once product deleted
pDialog.dismiss();

}
}

Login and Registration


This lesson will explain how to build complete login and registration system in android using
PHP, MySQL and SQLite. Also this lesson covers how to build simple API using PHP and
MySQL.

This lesson consists of:

1. Creating MySQL Database and Tables


2. Building PHP API classes
3. Create android project

Creating MySQL Database and Tables


In this lesson MySql database is used to maintain users and other related information. Open
your mysql consoleor phpmyadmin and run following query to create database and users
table.

create database android_api /** Creating Database **/


use android_api /** Selecting Database **/
create table users(
uid int(11) primary key auto_increment,
unique_id varchar(23) not null unique,
name varchar(50) not null,
email varchar(100) not null unique,
encrypted_password varchar(80) not null,
salt varchar(10) not null,
created_at datetime,
updated_at datetime null
); /** Creating Users Table **/

Building PHP API Classes


Following are the files are required to build API in php. You can find description of each file in the
below image.
Figure 1.Structure of PHP API files and directory.

config.php This file contains constant variables to connect to database.


<?php
/**
* Database config variables
*/
define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASSWORD", "");
define("DB_DATABASE", "android_api");
?>

DB_Connect.php This file is used to connect or disconnect to database.


<?php

class DB_Connect {

// constructor
function __construct() {

// destructor
function __destruct() {
// $this->close();
}

// Connecting to database
public function connect() {
require_once 'config.php';
// connecting to mysql
$con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
// selecting database
mysql_select_db(DB_DATABASE);

// return database handler


return $con;
}

// Closing database connection


public function close() {
mysql_close();
}

?>

DB_Functions.php This file contains functions to store user in database, get user from
database. You can also add methods like update user, delete user.

user unique id Here, unique user id is generate in php using uniqid(,


true) function. Sample user id will be like 4f074eca601fb8.88015924.

Encrypted Password This password is stored using base64_encode method. Each


password will need two columns to store in database. One is to store encrypted password and
second column is to store salt used to encrypt the password.

<?php

class DB_Functions {

private $db;

//put your code here


// constructor
function __construct() {
require_once 'DB_Connect.php';
// connecting to database
$this->db = new DB_Connect();
$this->db->connect();
}

// destructor
function __destruct() {

/**
* Storing new user
* returns user details
*/
public function storeUser($name, $email, $password) {
$uuid = uniqid('', true);
$hash = $this->hashSSHA($password);
$encrypted_password = $hash["encrypted"]; // encrypted
password
$salt = $hash["salt"]; // salt
$result = mysql_query("INSERT INTO users(unique_id,
name, email, encrypted_password, salt, created_at)
VALUES('$uuid', '$name', '$email', '$encrypted_password',
'$salt', NOW())");
// check for successful store
if ($result) {
// get user details
$uid = mysql_insert_id(); // last inserted id
$result = mysql_query("SELECT * FROM users WHERE
uid = $uid");
// return user details
return mysql_fetch_array($result);
} else {
return false;
}
}

/**
* Get user by email and password
*/
public function getUserByEmailAndPassword($email,
$password) {
$result = mysql_query("SELECT * FROM users WHERE email
= '$email'") or die(mysql_error());
// check for result
$no_of_rows = mysql_num_rows($result);
if ($no_of_rows > 0) {
$result = mysql_fetch_array($result);
$salt = $result['salt'];
$encrypted_password =
$result['encrypted_password'];
$hash = $this->checkhashSSHA($salt, $password);
// check for password equality
if ($encrypted_password == $hash) {
// user authentication details are correct
return $result;
}
} else {
// user not found
return false;
}
}

/**
* Check user is existed or not
*/
public function isUserExisted($email) {
$result = mysql_query("SELECT email from users WHERE
email = '$email'");
$no_of_rows = mysql_num_rows($result);
if ($no_of_rows > 0) {
// user existed
return true;
} else {
// user not existed
return false;
}
}

/**
* Encrypting password
* @param password
* returns salt and encrypted password
*/
public function hashSSHA($password) {

$salt = sha1(rand());
$salt = substr($salt, 0, 10);
$encrypted = base64_encode(sha1($password . $salt,
true) . $salt);
$hash = array("salt" => $salt, "encrypted" =>
$encrypted);
return $hash;
}

/**
* Decrypting password
* @param salt, password
* returns hash string
*/
public function checkhashSSHA($salt, $password) {
$hash = base64_encode(sha1($password . $salt, true) .
$salt);

return $hash;
}

?>

index.php This file plays role of accepting requests and giving response. This file accepts
all GET and POST requests. On each request it will talk to database and will give appropriate
response in JSON format.

<?php
/**
* File to handle all API requests
* Accepts GET and POST
*
* Each request will be identified by TAG
* Response will be JSON data

/**
* check for POST request
*/
if (isset($_POST['tag']) && $_POST['tag'] != '') {
// get tag
$tag = $_POST['tag'];

// include db handler
require_once 'include/DB_Functions.php';
$db = new DB_Functions();

// response Array
$response = array("tag" => $tag, "success" => 0, "error"
=> 0);

// check for tag type


if ($tag == 'login') {
// Request type is check Login
$email = $_POST['email'];
$password = $_POST['password'];

// check for user


$user = $db->getUserByEmailAndPassword($email,
$password);
if ($user != false) {
// user found
// echo json with success = 1
$response["success"] = 1;
$response["uid"] = $user["unique_id"];
$response["user"]["name"] = $user["name"];
$response["user"]["email"] = $user["email"];
$response["user"]["created_at"] =
$user["created_at"];
$response["user"]["updated_at"] =
$user["updated_at"];
echo json_encode($response);
} else {
// user not found
// echo json with error = 1
$response["error"] = 1;
$response["error_msg"] = "Incorrect email or
password!";
echo json_encode($response);
}
} else if ($tag == 'register') {
// Request type is Register new user
$name = $_POST['name'];
$email = $_POST['email'];
$password = $_POST['password'];

// check if user is already existed


if ($db->isUserExisted($email)) {
// user is already existed - error response
$response["error"] = 2;
$response["error_msg"] = "User already existed";
echo json_encode($response);
} else {
// store user
$user = $db->storeUser($name, $email, $password);
if ($user) {
// user stored successfully
$response["success"] = 1;
$response["uid"] = $user["unique_id"];
$response["user"]["name"] = $user["name"];
$response["user"]["email"] = $user["email"];
$response["user"]["created_at"] =
$user["created_at"];
$response["user"]["updated_at"] =
$user["updated_at"];
echo json_encode($response);
} else {
// user failed to store
$response["error"] = 1;
$response["error_msg"] = "Error occured in
Registartion";
echo json_encode($response);
}
}
} else {
echo "Invalid Request";
}
} else {
echo "Access Denied";
}
?>

Types of API JSON Responses


The following are the different types of JSON responses generated by API.

Registration Success Response Success Code = 1 (User Successfully


Stored)
{
"tag": "register",
"success": 1,
"error": 0,
"uid": "4f074ca1e3df49.06340261",
"user": {
"name": "Nama Anda",
"email": "na@gmail.com",
"created_at": "2012-01-07 01:03:53",
"updated_at": null
}
}

Registration Error Response Error Code = 1 (Error in storing)


{
"tag": "register",
"success": 0,
"error": 1,
"error_msg": "Error occured in Registartion"
}

Registration Error Response Error Code = 2 (User Already Existed)


{
"tag": "register",
"success": 0,
"error": 2,
"error_msg": "User already existed"
}
Login Success Response Success Code = 1 (User Logged in)
{
"tag": "login",
"success": 1,
"error": 0,
"uid": "4f074eca601fb8.88015924",
"user": {
"name": "Nama Anda",
"email": "na@gmail.com",
"created_at": "2012-01-07 01:03:53",
"updated_at": null
}
}

Login Error Response Error Code = 1 (Login Error Incorrect


username/password)
{
"tag": "login",
"success": 0,
"error": 1,
"error_msg": "Incorrect email or password!"
}

Starting Android Project


Until now we wrote server side programming to build simple api. Next thing is build android app
to interact with the API. In this lesson, the project is created as simple app which will have three
screens, i.e. Login Screen, Registration Screen and a welcome Dashboard
Screen. So lets get started by creating new project in you Eclipse IDE.

1. Create a new project by going to File > New Android Project. Fill all the details.
2. Next step is to create a new package to store all our library files. Right Click on >
src > New > Package and name it as fsktm.ws.android.library.
Figure 2.Create a new package.
Figure 3.The name of new package.

JSON Parser Class


Next we need parser class to parse api response JSON. So create a new class in your library
package name it as JSONParser.java and fill it with following code.

JSONParser.java
package fsktm.ws.andorid.library;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class JSONParser {

static InputStream is = null;


static JSONObject jObj = null;
static String json = "";

// constructor
public JSONParser() {

public JSONObject getJSONFromUrl(String url,


List<NameValuePair> params) {

// Making HTTP request


try {
// defaultHttpClient
DefaultHttpClient httpClient = new
DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new
UrlEncodedFormEntity(params));

HttpResponse httpResponse =
httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

try {
BufferedReader reader = new BufferedReader(new
InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "n");
}
is.close();
json = sb.toString();
Log.e("JSON", json);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " +
e.toString());
}

// try parse the string to a JSON object


try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " +
e.toString());
}

// return JSON String


return jObj;

}
}

SQLite Database Handler Class

Figure 4.The design of table in SQLite database.

In the application, SQLite Database is used to store user information. So create new class in you
library package folder and name it as DatabaseHandler.java and fill the class with
following code. This class file has functions to handle database operations like storing user and
getting user.
DatabaseHandler.java
package fsktm.ws.andorid.library;

import java.util.HashMap;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseHandler extends SQLiteOpenHelper {

// All Static variables


// Database Version
private static final int DATABASE_VERSION = 1;

// Database Name
private static final String DATABASE_NAME = "android_api";

// Login table name


private static final String TABLE_LOGIN = "login";

// Login Table Columns names


private static final String KEY_ID = "id";
private static final String KEY_NAME = "name";
private static final String KEY_EMAIL = "email";
private static final String KEY_UID = "uid";
private static final String KEY_CREATED_AT = "created_at";

public DatabaseHandler(Context context) {


super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

// Creating Tables
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_LOGIN_TABLE = "CREATE TABLE " +
TABLE_LOGIN + "("
+ KEY_ID + " INTEGER PRIMARY KEY,"
+ KEY_NAME + " TEXT,"
+ KEY_EMAIL + " TEXT UNIQUE,"
+ KEY_UID + " TEXT,"
+ KEY_CREATED_AT + " TEXT" + ")";
db.execSQL(CREATE_LOGIN_TABLE);
}

// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion,
int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_LOGIN);

// Create tables again


onCreate(db);
}

/**
* Storing user details in database
* */
public void addUser(String name, String email, String uid,
String created_at) {
SQLiteDatabase db = this.getWritableDatabase();

ContentValues values = new ContentValues();


values.put(KEY_NAME, name); // Name
values.put(KEY_EMAIL, email); // Email
values.put(KEY_UID, uid); // Email
values.put(KEY_CREATED_AT, created_at); // Created At

// Inserting Row
db.insert(TABLE_LOGIN, null, values);
db.close(); // Closing database connection
}

/**
* Getting user data from database
* */
public HashMap<String, String> getUserDetails(){
HashMap<String,String> user = new
HashMap<String,String>();
String selectQuery = "SELECT * FROM " + TABLE_LOGIN;

SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// Move to first row
cursor.moveToFirst();
if(cursor.getCount() > 0){
user.put("name", cursor.getString(1));
user.put("email", cursor.getString(2));
user.put("uid", cursor.getString(3));
user.put("created_at", cursor.getString(4));
}
cursor.close();
db.close();
// return user
return user;
}
/**
* Getting user login status
* return true if rows are there in table
* */
public int getRowCount() {
String countQuery = "SELECT * FROM " + TABLE_LOGIN;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int rowCount = cursor.getCount();
db.close();
cursor.close();

// return row count


return rowCount;
}

/**
* Re crate database
* Delete all tables and create them again
* */
public void resetTables(){
SQLiteDatabase db = this.getWritableDatabase();
// Delete All Rows
db.delete(TABLE_LOGIN, null, null);
db.close();
}

User Functions Class


Create a new class file under library package and name it as UserFunctions.java. This class will
have functions to handle all user events like

1. loginUser()
2. registerUser()
3. getLoginStatus()
4. logoutUser()
Figure 5.Testing andoird network application.

In this class all the functions will interact with JSONParser, DatabaseHandler classes.
Testing API in localhost using XAMPP software. Normally localhost will run on
address http://127.0.0.1 or http://localhost/. In AVD to connect to localhost
you need to use url http://10.0.2.2/ instead of http://localhost/. If you want
deploy your api on website the use the url http://yoursite.com/api/

UserFunctions.java
package fsktm.ws.andorid.library;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class JSONParser {

static InputStream is = null;


static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {

public JSONObject getJSONFromUrl(String url,


List<NameValuePair> params) {

// Making HTTP request


try {
// defaultHttpClient
DefaultHttpClient httpClient = new
DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new
UrlEncodedFormEntity(params));

HttpResponse httpResponse =
httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

try {
BufferedReader reader = new BufferedReader(new
InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "n");
}
is.close();
json = sb.toString();
Log.e("JSON", json);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " +
e.toString());
}

// try parse the string to a JSON object


try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " +
e.toString());
}

// return JSON String


return jObj;

}
}

Designing the Screens


Until now we have developed the library classes needed in this application. Next thing is build
screens. We need three screens Login Screen, Registration

Screen and Dashboard Screen. Create 3 xml files under res > layout

folder and name them as login.xml, register.xml and dashboard.xml

login.xml login screen design layout


<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#3b3b3b" >

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dip" >
<!-- View Title Label -->

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dip"
android:text="@string/login"
android:textSize="25sp"
android:textStyle="bold" />

<!-- Email Label -->

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/email" />

<!-- Email TextField -->

<EditText
android:id="@+id/loginEmail"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress" />

<!-- Password Label -->

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dip"
android:text="@string/password" />

<!-- Password TextField -->

<EditText
android:id="@+id/loginPassword"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword" />

<!-- Error message -->


<TextView android:id="@+id/login_error"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#e30000"
android:padding="10dip"
android:textStyle="bold"/>

<!-- Login Button -->

<Button
android:id="@+id/btnLogin"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:onClick="UserLogin"
android:text="@string/login" />

<!-- Link to Registration Screen -->

<Button
android:id="@+id/btnLinkToRegisterScreen"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dip"
android:background="@null"
android:text="@string/regnew"
android:onClick="Registration"
android:textColor="#21dbd4"
android:textStyle="bold" />

</LinearLayout>

</ScrollView>

Figure 6.Login screen.

register.xml registration screen design layout


<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp" >
<!-- View Title Label -->

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@string/register"
android:textSize="25sp"
android:textStyle="bold" />

<!-- Name Label -->

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/fullname" />

<!-- Name TextField -->

<EditText
android:id="@+id/registerName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text" />

<!-- Email Label -->

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/email" />

<!-- Email TextField -->

<EditText
android:id="@+id/registerEmail"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress" />

<!-- Password Label -->

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="@string/password" />

<!-- Password TextField -->

<EditText
android:id="@+id/registerPassword"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword" />

<!-- Error message -->


<TextView android:id="@+id/register_error"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#e30000"
android:padding="10dp"
android:textStyle="bold"/>

<!-- Login Button -->

<Button
android:id="@+id/btnRegister"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:onClick="Register"
android:text="@string/register" />

<!-- Link to Login Screen -->

<Button
android:id="@+id/btnLinkToLoginScreen"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:background="@null"
android:onClick="ToLogin"
android:text="@string/already_register"
android:textColor="#21dbd4"
android:textStyle="bold" />

</LinearLayout>

</ScrollView>
Figure 7.Register screen.

dashboard.xml dashboard screen design layout


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

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:gravity="center"
android:text="@string/welcome"
android:textSize="40sp" />

<Button
android:id="@+id/btnLogout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:background="@null"
android:onClick="Logout"
android:text="@string/logout"
android:textColor="#21dbd4"
android:textSize="20sp"
android:textStyle="bold" />

</LinearLayout>

Figure 8.Welcome screen.

Switching between Activites


Now the designing part of the app is done next thing is to create activities for each layout and
write functionality to achieve login and registration process. Create new
activities LoginActivity.java and RegisterActivity.java and fill them with
respective code below.
LoginActivity.java Activity to handle login event
package fsktm.ws.android.mylogin;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import fsktm.ws.andorid.library.*;

public class LoginActivity extends Activity {


EditText inputEmail;
EditText inputPassword;
TextView loginErrorMsg;

// JSON Response node names


private static String KEY_SUCCESS = "success";
//private static String KEY_ERROR = "error";
//private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_UID = "uid";
private static String KEY_NAME = "name";
private static String KEY_EMAIL = "email";
private static String KEY_CREATED_AT = "created_at";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);

// Importing all assets like buttons, text fields


inputEmail = (EditText) findViewById(R.id.loginEmail);
inputPassword = (EditText)
findViewById(R.id.loginPassword);
loginErrorMsg = (TextView)
findViewById(R.id.login_error);

public void UserLogin(View v) {


String email = inputEmail.getText().toString();
String password = inputPassword.getText().toString();
UserFunctions userFunction = new UserFunctions();
JSONObject json = userFunction.loginUser(email,
password);

// check for login response


try {
if (json.getString(KEY_SUCCESS) != null) {
loginErrorMsg.setText("");
String res = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res) == 1){
// user successfully logged in
// Store user details in SQLite Database
DatabaseHandler db = new
DatabaseHandler(getApplicationContext());
JSONObject json_user =
json.getJSONObject("user");

// Clear all previous data in database

userFunction.logoutUser(getApplicationContext());
db.addUser(json_user.getString(KEY_NAME),
json_user.getString(KEY_EMAIL), json.getString(KEY_UID),
json_user.getString(KEY_CREATED_AT));

// Launch Dashboard Screen


Intent dashboard = new
Intent(getApplicationContext(), MainActivity.class);

// Close all views before launching


Dashboard

dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(dashboard);

// Close Login Screen


finish();
}else{
// Error in login
loginErrorMsg.setText("Incorrect
username/password");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}

public void Registration(View v) {


Intent i = new Intent(getApplicationContext(),
RegisterActivity.class);
startActivity(i);
finish();
}

RegisterActivity.java Activity to handle registration event


package fsktm.ws.android.mylogin;

import org.json.JSONException;
import org.json.JSONObject;

import fsktm.ws.andorid.library.*;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class RegisterActivity extends Activity {

EditText inputFullName;
EditText inputEmail;
EditText inputPassword;
TextView registerErrorMsg;

// JSON Response node names


private static String KEY_SUCCESS = "success";
//private static String KEY_ERROR = "error";
//private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_UID = "uid";
private static String KEY_NAME = "name";
private static String KEY_EMAIL = "email";
private static String KEY_CREATED_AT = "created_at";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.register);

// Importing all assets like buttons, text fields


inputFullName = (EditText)
findViewById(R.id.registerName);
inputEmail = (EditText)
findViewById(R.id.registerEmail);
inputPassword = (EditText)
findViewById(R.id.registerPassword);
registerErrorMsg = (TextView)
findViewById(R.id.register_error);
}

public void Register(View v) {


String name = inputFullName.getText().toString();
String email = inputEmail.getText().toString();
String password =
inputPassword.getText().toString();
UserFunctions userFunction = new UserFunctions();
JSONObject json = userFunction.registerUser(name,
email, password);

// check for login response


try {
if (json.getString(KEY_SUCCESS) != null) {
registerErrorMsg.setText("");
String res = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res) == 1){
// user successfully registred
// Store user details in SQLite Database
DatabaseHandler db = new
DatabaseHandler(getApplicationContext());
JSONObject json_user =
json.getJSONObject("user");

// Clear all previous data in database

userFunction.logoutUser(getApplicationContext());

db.addUser(json_user.getString(KEY_NAME),
json_user.getString(KEY_EMAIL), json.getString(KEY_UID),
json_user.getString(KEY_CREATED_AT));
// Launch Dashboard Screen
Intent dashboard = new
Intent(getApplicationContext(), MainActivity.class);
// Close all views before launching
Dashboard

dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(dashboard);
// Close Registration Screen
finish();
}else{
// Error in registration
registerErrorMsg.setText("Error occured
in registration");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}

public void ToLogin(View v) {


Intent i = new Intent(getApplicationContext(),
LoginActivity.class);
startActivity(i);
// Close Registration View
finish();
}

MainActivity.java Activity to handle dashboard event


package fsktm.ws.android.mylogin;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import fsktm.ws.andorid.library.*;

public class MainActivity extends Activity {


UserFunctions userFunctions;

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

/**
* Dashboard Screen for the application
* */
// Check login status in database
userFunctions = new UserFunctions();
if
(userFunctions.isUserLoggedIn(getApplicationContext())) {
// user already logged in show databoard
setContentView(R.layout.dashboard);
} else {
// user is not logged in show login screen
Intent login = new
Intent(getApplicationContext(),
LoginActivity.class);

login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(login);
// Closing dashboard screen
finish();
}
}

public void Logout(View v) {


// TODO Auto-generated method stub

userFunctions.logoutUser(getApplicationContext());
Intent login = new
Intent(getApplicationContext(), LoginActivity.class);
login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(login);
// Closing dashboard screen
finish();
}
}

Finally Updating AndroidManifest.xml


Dont forget to update you AndroidManifest.xml file. Change following modifications
> Add Internet Persmissions > Add Entries of each Activity

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


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

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

<!-- Allow to connect with internet -->


<uses-permission
android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity

android:name="fsktm.ws.android.mylogin.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>
<!-- Login Activity -->
<activity
android:label="Login Account"
android:name=".LoginActivity"></activity>

<!-- Register Activity -->


<activity
android:label="Register New Account"
android:name=".RegisterActivity"></activity>
</application>

</manifest>

Das könnte Ihnen auch gefallen