Workshop Android Programming
Workshop Android Programming
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.
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 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
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
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.
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:
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.
Android SDK
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.
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
With a single download, the ADT Bundle (file size around 500MB) includes everything
you need to begin developing apps:
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.
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).
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
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.
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:
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.
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.
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.
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.
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;
@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;
}
}
<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>
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:
<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:
package com.example.helloworld;
<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>
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 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.
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.
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"
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.
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.
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" />
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.
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.
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.
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:
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.
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.
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:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send"
android:onClick="sendMessage" />
import android.view.View;
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.
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.
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)
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:
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:
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.
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:
Now you need to create the DisplayMessageActivity class in order for this to work.
Click Finish.
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:
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
@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.
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:
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>
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.
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.
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);
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.
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;
@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.
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.
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;
@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);
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.
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;
@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);
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();
Now in new activity we need to display the received from listview activity.
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;
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.
<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.
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.
db_config.php
<?php
/*
* All database connection variables
*/
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';
// Selecing database
$db = mysql_select_db(DB_DATABASE) or
die(mysql_error()) or die(mysql_error());
/**
* 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
/*
* Following code will create a new product row
* All product details are read from HTTP Post Request
*/
$name = $_POST['name'];
$price = $_POST['price'];
$description = $_POST['description'];
// connecting to db
$db = new DB_CONNECT();
{
"success": 0,
"message": "Required field(s) is missing"
}
{
"success": 1,
"message": "Product successfully created."
}
{
"success": 0,
"message": "Oops! An error occurred."
}
get_product_details.php
<?php
/*
* Following code will get single product details
* A product is identified by product id (pid)
*/
// connecting to db
$db = new DB_CONNECT();
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);
{
"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"
}
]
}
{
"success": 0,
"message": "No product found"
}
get_all_products.php
<?php
/*
* Following code will list all the products
*/
// connecting to db
$db = new DB_CONNECT();
{
"success": 0,
"message": "No products found"
}
/*
* Following code will update a product information
* A product is identified by product id (pid)
*/
$pid = $_POST['pid'];
$name = $_POST['name'];
$price = $_POST['price'];
$description = $_POST['description'];
// connecting to db
$db = new DB_CONNECT();
}
} else {
// required field is missing
$response["success"] = 0;
$response["message"] = "Required field(s) is missing";
{
"success": 1,
"message": "Product successfully updated."
}
delete_product.php
<?php
/*
* Following code will delete a product from table
* A product is identified by product id (pid)
*/
// connecting to db
$db = new DB_CONNECT();
{
"success": 1,
"message": "Product successfully deleted"
}
{
"success": 0,
"message": "No product 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.
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" />
<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>
</manifest>
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">
</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;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
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;
// constructor
public JSONParser() {
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());
}
}
}
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" >
<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" />
<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" />
<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" />
<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
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;
// Progress Dialog
private ProgressDialog pDialog;
@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);
/**
* 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));
if (success == 1) {
// successfully created product
Intent i = new
Intent(getApplicationContext(), AllProductsActivity.class);
startActivity(i);
return null;
}
/**
* After completing background task Dismiss the
progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once done
pDialog.dismiss();
}
}
}
</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" >
</LinearLayout>
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;
// Progress Dialog
private ProgressDialog pDialog;
// products JSONArray
JSONArray products = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.all_products);
// Get listview
ListView lv = getListView();
@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();
/**
* 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);
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);
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.
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" >
<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" />
<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" />
<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
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>
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;
EditText txtName;
EditText txtPrice;
EditText txtDesc;
EditText txtCreatedAt;
Button btnSave;
Button btnDelete;
String pid;
// Progress Dialog
private ProgressDialog pDialog;
@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);
}
/**
* 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) {
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) {
// 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);
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) {
/**
* After completing background task Dismiss the
progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog once product deleted
pDialog.dismiss();
}
}
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);
?>
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.
<?php
class DB_Functions {
private $db;
// 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);
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.
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;
// constructor
public JSONParser() {
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());
}
}
}
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;
// Database Name
private static final String DATABASE_NAME = "android_api";
// 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);
/**
* Storing user details in database
* */
public void addUser(String name, String email, String uid,
String created_at) {
SQLiteDatabase db = this.getWritableDatabase();
// 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();
/**
* 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();
}
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;
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());
}
}
}
Screen and Dashboard Screen. Create 3 xml files under res > layout
<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" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/email" />
<EditText
android:id="@+id/loginEmail"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dip"
android:text="@string/password" />
<EditText
android:id="@+id/loginPassword"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword" />
<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" />
<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>
<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" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/fullname" />
<EditText
android:id="@+id/registerName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/email" />
<EditText
android:id="@+id/registerEmail"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="@string/password" />
<EditText
android:id="@+id/registerPassword"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="textPassword" />
<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" />
<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.
<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>
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.*;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
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));
dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(dashboard);
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;
EditText inputFullName;
EditText inputEmail;
EditText inputPassword;
TextView registerErrorMsg;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.register);
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();
}
}
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import fsktm.ws.andorid.library.*;
@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();
}
}
userFunctions.logoutUser(getApplicationContext());
Intent login = new
Intent(getApplicationContext(), LoginActivity.class);
login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(login);
// Closing dashboard screen
finish();
}
}
<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.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>
</manifest>