ibm xforms
TRANSCRIPT
-
7/27/2019 IBM Xforms
1/42
Copyright IBM Corporation 2010 Trademarks
Build dynamic user interfaces with Android and XML Page 1 of 42
Build dynamic user interfaces with Android and
XML
Collect data using an Android forms engine
Frank Ableson
Entrepreneur
MSI Services, Inc.
Skill Level: Intermediate
Date: 07 Sep 2010
A number of websites cater to non-profits that provide easily set-up and used
forms for taking polls and collecting data. This tutorial introduces a simple
architecture for designing similar applications for Androiddynamic user
interfaces that allow non-programmers to collect data from mobile users. You will
create an example forms engine in this tutorial with both server and mobile sides.
Section 1. Before you start
You should be comfortable constructing Android applications with the Android SDK to
get the most from this tutorial. After completion, you will have learned how to perform
application-to-web server communications with HTTP(S) and how to parse XML with
the DOM parser. Along the way, you will create custom and dynamic user interface
layouts, multi-threaded communications, message handlers, and progress dialogs. To
a lesser degree, you will learn about AndroidManifest.xml and server side scripting.
About this tutorial
Frequently used acronyms
API: Application Programming Interface
DOM: Document Object Model
HTML: HyperText Markup Language
HTTP(S): Hypertext Transfer Protocol Secure
IDE: Integrated development environment
SAX: Simple API for XML
SDK: Software Development Kit
UI: User Interface
http://www.ibm.com/legal/copytrade.shtmlhttp://www.ibm.com/developerworks/ibm/trademarks/http://www.ibm.com/legal/copytrade.shtml -
7/27/2019 IBM Xforms
2/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 2 of 42
URL: Uniform Resource Locator
XML: Extensible Markup Language
This tutorial introduces an architecture for dynamic forms for mobile data collection
on Android devices. I will begin with a high level architecture and discussion of where
such an application fits in the larger context of data collection. A sneak peak at thecompleted project, including every source file, provides a road map to where the
tutorial is taking you. In cooking-show fashion, you build the application from the
ground up with each Java class carefully introduced and related to other aspects
of the application, most notably the data model upon which this forms engine is
constructed. To conclude, you save form data to the server and look briefly at the
server side of the application.
Prerequisites
Table 1 shows the tools required for this project.
Table 1. The necessary tools for the job
Tool Comment
Eclipse and ADT Primary code editor and Android Developer Tools Plugin.
Android SDK Android Software Developer Kit.
Web server Any variety that supports PHP. You can easily port the script
to another server environment.
I created the code samples for this tutorial on a MacBook with Eclipse 3.4.2 and
Android SDK version 8, which supports the Android release labeled 2.2. The tutorialcode is not leveraging any specific features of this SDK and the application should
run just fine in Android versions dating back as far as 1.5. See Resources for links to
all the tools.
Section 2. Data collection
Let's begin with a short discussion about data collection, and how it can be easy toimplement when using an Android mobile device.
An Android data collection framework
Collecting data is a task that pre-dates the computer era. Computers have become
a daily staple and have revolutionized the way you think about, find, and consume
information. Companies with billion dollar market-caps exist thanks to their
effectiveness in storing, retrieving, and managing vast amounts of information. The
-
7/27/2019 IBM Xforms
3/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 3 of 42
databases in use today are fed by systems of varying architectures including the
main frame, client server, web applications, and now mobile applications.
Physical inventory and cycle counting applications were some of the early practical
applications of mobile computing. These applications were often batch data
collection, where the hardware required a docking station to upload the collectedinformation.
The market for mobile applications has come a long way since those early days,
and wireless connectivity and devices are nearly ubiquitous in many cultures and
markets, invading virtually every aspect of daily life.
While the means of collecting data may have become more mobile, the core
aspect of data collection has not changed significantly. The user must be presented
a collection of questions and have a simple means of responding. This tutorial
demonstrates the construction of a simple data collection framework for Android-
powered mobile phones, leveraging a dynamic metadata structure enabled by XML.
Section 3. The application architecture
Before diving into the code, examine the application setting from a very high level.
Forms Engine at a glance
Take a walk through all of the aspects of the Forms Engine application. Figure 1
depicts the relation of the application to one or more servers that provide data entry
forms of varying content.
Figure 1. Application architecture
-
7/27/2019 IBM Xforms
4/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 4 of 42
In Figure 1, Form 1 provides registration for Robotics Competition and Form 2 asks
the user for information about his auto maintenance habit. Using HTTP(S), the forms
and Android application communicate to:
Download the form data.
Present form data to the user and optional collect device-specific data, such ascamera images, sound recordings, GPS location, or compass readings.
Collect user-supplied data.
Submit data to the appropriate server.
The server side of this tutorial is implemented as a pair of files: an XML document
describing the form and a PHP document responsible for recording the submission
of the form. The Android application is a native application written in Java code using
the Android SDK and coded in Eclipse.
Table 2 shows the application source files for the complete application. You candownload the zipped file containing all of these source files (see Downloads). You will
go through each of these files in detail in this tutorial.
Table 2. The required application source files
Filename Comment
XmlGui.java Entry point for Android Activity
XmlGuiForm.java High level data model and methods for a form
XmlGuiFormField.java Represents a form field and holds the metadata for each field
of a form
XmlGuiEditBox.java Implements a text box type user interface element
XmlGuiPickOne.java Implements a drop-down list type user interface element
RunForm.java Processes a form, using the above classes
main.xml Home page of application user interface
AndroidManifest.xml Deployment descriptor for the Android application
xmlgui1.xml Sample form for collecting Robotics competition registration
xmlgui1-post.php PHP script for processing form submissions
xmlgui2.xml Sample form for taking survey of automotive maintenance
habits
Figure 2 shows the project structure in Eclipse for the complete application as it will
look at the end of this tutorial. (View a text-only version of Figure 2.)
http://localhost/var/www/apps/conversion/tmp/scratch_1/sidefile-figure2.htmlhttp://localhost/var/www/apps/conversion/tmp/scratch_1/sidefile-figure2.html -
7/27/2019 IBM Xforms
5/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 5 of 42
Figure 2. Project in Eclipse
If you do not have a working Android development environment, now is a great
time to install the Android tools. For more information on how to setup an Android
development environment, look in Resources for links to both of the required tools,
plus some introductory articles and tutorials on developing applications for Android.
Having a familiarity with Android is helpful in understanding this tutorial.
Now that you have an overview of the architecture and the application, you can get
started!
Section 4. The project and data model
We are now ready to start the Android project in Eclipse, creating the data model
and the class that will allow you to store and manage metadata for the Forms Engine
application.
Creating the project
Creating Android applications starts in the familiar place: Open Eclipse and select
File > New as in Figure 3.
-
7/27/2019 IBM Xforms
6/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 6 of 42
Figure 3. Creating a new Android application
This step launches the Eclipse New project wizard. Select Android Project (the
specialized Java environment for Android). Be sure to give the project a valid
identifier (I used XMLGUI). To match the solution as described in this tutorial, under
Properties, specify XML GUI as the application name and com.msi.ibm as the
package name. Select the Create Activity check box and specify XmlGui for the
Activity name as in Figure 4.
-
7/27/2019 IBM Xforms
7/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 7 of 42
Figure 4. Setting up a new project
Once the project is created, it should look very similar to the image in Figure 5. (View
a text-only version of Figure 5.)
http://localhost/var/www/apps/conversion/tmp/scratch_1/sidefile-figure5.html -
7/27/2019 IBM Xforms
8/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 8 of 42
Figure 5. Android project directly upon completion of the new project wizard
With the project now created, it is good practice to ensure that the application builds
cleanly and runs in the Android Emulator. Note that sometimes the application does
not build until you edit and save the Java source file. This causes the Android SDK
tools to automatically generate the files in the gen folder. This causes the files in
the gen folder to be automatically generated by the Android SDK tools. You can test
the application if there are no entries showing up in the Problems tab of the Eclipse
environment.
To test the application, create a Run Configuration, as in Figure 6. In the Android
Application list, select XmlGui. Ensure the following values are present: XmlGui
in the Name field, XMLGUI in the Project field, and com.msi.ibm.XmlGui in theLaunch field. Click Run.
-
7/27/2019 IBM Xforms
9/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 9 of 42
Figure 6. Run Configuration setup
Now that the project is created, is configured, and starts properly in the Android
emulator, it is time to create the XML driven data collection tool for Android.
The data model
The nuts and bolts of this application require it to present input elements to a user,
collect data, validate the data, and then submit that data to a specified server
location. It is worth noting that this application is set up for new records only. There
are no provisions to look up an existing record for editing or deleting.
To provide enough direction to the application on how to present the data entry forms,
a set of information (commonly referred to as metadata) is required. Metadata is data
about data. In general terms, this application must understand a few data elements
including:
Form NameHuman readable name of the form
Form IdentifierUnique identifier for this metadata collection
Submission URLWhere to send the collected data
One or more fieldsThese can be text, numeric, or "choose from a list" kind of
fields
Virtually all kinds of questions map to one of these three types of user interface
elements. For example, you can implement a check box as a Yes or No choice field.
-
7/27/2019 IBM Xforms
10/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 10 of 42
You can implement multi-select as multiple choice fields. Of course, you can extend
the code shown in this tutorial as desired.
For your application, the usage scenario is as follows: You are at an event where you
can register for one or more activities. You could fill out a piece of paper, or you could
wait until you get home and hope that you remember to sign onto the organization'swebsite to register. In this case, you will assume that a user will fill out a simple
form on the spot from his phone by pulling up a dynamic form on an Android device,
providing the entrant's first name, last name, gender, and age.
Listing 1 shows the contents of xmlgui1.xml, which represents a registration form for
a Robotics club event.
Listing 1. xmlgui1.xml
Note the following things about this XML document:
The XML is very simple to parse thanks to extensive use of element attributes.
This approach is used because it makes extracting the data easier than
multiple child elements and tags. Using attributes in this manner also keeps thedownload size small and aids in keeping the parse time low.
The submitTo attribute tells the application where to send the data once it is
collected.
Each field element provides attributes for both a field name and a label. While
these values are related, you want to keep the value of each name attribute
unique from the other name attribute values so the receiving application can
properly parse and process them. You must also provide an informative label
value to the user as a cue to what kind of data should go into a particular field.
You can readily expand this approach to include default values for each field, a
regex expression for validation, or a link for more information about a particular
field.
The options field is used as a delimited list for the choice field.
With a basic familiarity with the data model, now look at the code responsible for
turning this XML data into a useful application.
Representing the dataParsing the data is a rather mechanical exercise shown later in this tutorial. Before
examining the parsing process, the application needs some place to store and
-
7/27/2019 IBM Xforms
11/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 11 of 42
manage the metadata in memory. For this purpose, you have two Java classes, one
for the form and one to represent the form field. Start by looking at XmlGuiForm.java
in Listing 2.
Listing 2. XmlGuiForm.java
package com.msi.ibm;import java.util.Vector;
import java.util.ListIterator;
import java.net.URLEncoder;
public class XmlGuiForm {
private String formNumber;
private String formName;
private String submitTo;
public Vector fields;
public XmlGuiForm()
{
this.fields = new Vector();
formNumber = "";
formName = "";
submitTo = "loopback"; // do nothing but display the results
}
// getters & setters
public String getFormNumber() {
return formNumber;
}
public void setFormNumber(String formNumber) {
this.formNumber = formNumber;
}
public String getFormName() {
return formName;}
public void setFormName(String formName) {
this.formName = formName;
}
public String getSubmitTo() {
return submitTo;
}
public void setSubmitTo(String submitTo) {
this.submitTo = submitTo;
}
public Vector getFields() {
return fields;}
public void setFields(Vector fields) {
this.fields = fields;
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("XmlGuiForm:\n");
sb.append("Form Number: " + this.formNumber + "\n");
sb.append("Form Name: " + this.formName + "\n");
sb.append("Submit To: " + this.submitTo + "\n");
-
7/27/2019 IBM Xforms
12/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 12 of 42
if (this.fields == null) return sb.toString();
ListIterator li = this.fields.listIterator();
while (li.hasNext()) {
sb.append(li.next().toString());
}
return sb.toString();
}
public String getFormattedResults()
{
StringBuilder sb = new StringBuilder();
sb.append("Results:\n");
if (this.fields == null) return sb.toString();
ListIterator li = this.fields.listIterator();
while (li.hasNext()) {
sb.append(li.next().getFormattedResult() + "\n");
}
return sb.toString();
}
public String getFormEncodedData()
{try {
int i = 0;
StringBuilder sb = new StringBuilder();
sb.append("Results:\n");
if (this.fields == null) return sb.toString();
ListIterator li = this.fields.listIterator();
while (li.hasNext()) {
if (i != 0) sb.append("&");
XmlGuiFormField thisField = li.next();
sb.append(thisField.name + "=");
String encstring = new String();
URLEncoder.encode((String) thisField.getData(),encstring);
sb.append(encstring);
}
return sb.toString();
}
catch (Exception e) {
return "ErrorEncoding";
}
}
}
Here are some important items to note about the XmlGuiForm class.
1. There are four member variables:
formNumber: This is the unique identifier for the server side form
distribution mechanism. formName: This becomes the title of the form, providing context and
confirmation for the user.
submitTo: This is the URL for the application to submit the data entered
(after validation). Alternatively this value can be a loopback. In the
loopback scenario, the data is displayed to the user rather than submitted
to the server. This is useful for testing purposes.
fields: This is a Vector class templated to hold the form's field data.
Listing 3 shows the details for XmlGuiFormField.java .
-
7/27/2019 IBM Xforms
13/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 13 of 42
2. A series of getters and setters for each of these variables.
3. The toString() and getFormattedResults()methods are responsible for
generating human readable summarizations of the XmlGuiForm class.
4. The getFormEncodedData() method is used when preparing data for submission
to the URL indicated in the submitTo attribute.
5. Rather than using strictly concatenated java.lang.String classes, the codeemploys a StringBuilder as a more memory efficient means of building the
desired data strings.
6. The URLEncoder class is leveraged to prepare data for submission to the server.
This makes the data look like it was actually created by a traditional HTML form.
7. Some potential expansions of this application include:
Local storage or caching of metadata to make repetitive tasks run more
quickly.
Local storage to record data over a period of time prior to submission.
GPS recordingstamp each record with location data.
Now look at the construction of the XmlGuiFormField class in Listing 3.
Listing 3. XmlGuiFormField.javapackage com.msi.ibm;
// class to handle each individual form
public class XmlGuiFormField {
String name;
String label;
String type;
boolean required;
String options;
Object obj; // holds the ui implementation
// or the EditText for example
// getters & setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getType() {
return type;}
public void setType(String type) {
this.type = type;
}
public boolean isRequired() {
return required;
}
public void setRequired(boolean required) {
this.required = required;
}
public String getOptions() {
return options;
}
-
7/27/2019 IBM Xforms
14/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 14 of 42
public void setOptions(String options) {
this.options = options;
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("Field Name: " + this.name + "\n");
sb.append("Field Label: " + this.label + "\n");sb.append("Field Type: " + this.type + "\n");
sb.append("Required? : " + this.required + "\n");
sb.append("Options : " + this.options + "\n");
sb.append("Value : " + (String) this.getData() + "\n");
return sb.toString();
}
public String getFormattedResult()
{
return this.name + "= [" + (String) this.getData() + "]";
}
public Object getData()
{if (type.equals("text") || type.equals("numeric"))
{
if (obj != null) {
XmlGuiEditBox b = (XmlGuiEditBox) obj;
return b.getValue();
}
}
if (type.equals("choice")) {
if (obj != null) {
XmlGuiPickOne po = (XmlGuiPickOne) obj;
return po.getValue();
}
}
// You could add logic for other UI elements here
return null;
}
}
Look more closely at the XmlGuiFormField class.
There are six class level members:
1. name holds the name of the fieldthis is the field name of the data value,
analogous to a form field name in HTML or a database column name.
2. label holds the description of the field or the value shown to the user.
3. type indicates the flavor of user interface field to construct. text means this is field is implemented with an EditText field for
alphanumeric entries. This is the most common value.
numeric is also an EditText, but it is constrained to a numeric entry
value.
choice makes the field a drop-down list.
4. required is a Boolean value marking the field as required or not. If the field
is required and not populated, an error message is displayed to the user
when the user attempts to submit the form.
-
7/27/2019 IBM Xforms
15/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 15 of 42
5. options is a string value used to convey the list of available selections for
a choice field. This field is available for other fields to be used as perhaps
a regex expression for validation or it can be overridden to specify a
default value.
6. obj represents the user interface widget. For example, this variable holds
an EditText for a text or numeric field. For a choice field, the obj membercontains a spinner widget. This approach is further explained later in this
tutorial.
As expected, these variables have a number of getters and setters.
The toString() and getFormattedResult() methods both leverage the
getData() method, explained next.
In the XmlGuiFormField class, you need to manage more than one type of data,
so the code needs to be explicit about how data is stored and accessed. The
getData() method examines the type field and performs a type-cast on the obj
field to properly interact with the stored object. If you wish to add new field types
to this framework, you can expand the getData() method to support the newfield type (see the comment near the end of Listing 3.
You now have a way to store and manage metadata. It is time to look at the
application in action and then tie the various pieces together.
Section 5. Assemble a user interface
Start by creating a form for a mobile user to enter data into.
Taking it from the top
The entry point of the application resides in XmlGui.java, as in Listing 4.
Listing 4. The application entry point: XmlGui
package com.msi.ibm;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Button;
import android.widget.TextView;
import android.content.Intent;import android.util.Log;
public class XmlGui extends Activity {
final String tag = XmlGui.class.getName();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnRunForm = (Button) this.findViewById(R.id.btnRunForm);
btnRunForm.setOnClickListener(new Button.OnClickListener()
{
public void onClick(View v)
-
7/27/2019 IBM Xforms
16/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 16 of 42
{
EditText formNumber = (EditText) findViewById(R.id.formNumber);
Log.i(tag,"Attempting to process Form #
[" + formNumber.getText().toString() + "]");
Intent newFormInfo = new Intent(XmlGui.this,RunForm.class);
newFormInfo.putExtra("formNumber",
formNumber.getText().toString());
startActivity(newFormInfo);
}});
}
}
The user interface for the main Activity is very simple, consisting of only:
A label (TextView)
An entry box (EditText)
A button (Button)
The code for XmlGui Activity is very standard in nature. You inflate a layout createdat design time and then define and create a button handler to implement the desired
functionality (which is explained further below).
You define the user interface in the file main.xml (found in the layout subfolder of the
res folder). Listing 5 shows main.xml.
Listing 5. main.xml
-
7/27/2019 IBM Xforms
17/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 17 of 42
As a reminder, you can modify layouts by editing the XML directly or by using the
Layout tool contained in the Android Developer Tools as in Figure 7.
Figure 7. Layout tool
To run the application, click on the home screen icon that launches the XmlGui
Activity seen in Figure 8.
-
7/27/2019 IBM Xforms
18/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 18 of 42
Figure 8. Application in action
When the user enters a form number and taps the Run Form button, a series of
events is kicked off. Let's go through the onClick() method, line by line. Recall that
the onClick() method is in the XmlGui class in Listing 4.
You get a reference to the EditText field named formNumber. The R.id.formNumber
enumeration is automatically generated by the Android build tools whenever the
main.xml file is saved:
EditText formNumber = (EditText) findViewById(R.id.formNumber);
Next, you put a line into the log. You can see the output of this log in the Dalvik
Debug Monitor Service (DDMS) perspective in Eclipse, provided by the Android
Developer Tools plugin:
Log.i(tag,"Attempting to process Form # [" + formNumber.getText().toString() + "]");
The actual implementation of the Form Engine is provided in the RunForm class, which
extends the Activity class. To launch this Activity, create an Intent, explicitly
identifying the RunForm class:
Intent newFormInfo = new Intent(XmlGui.this,RunForm.class);
-
7/27/2019 IBM Xforms
19/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 19 of 42
Not only do you want to launch the RunForm Activity, but you also want to specify
which form to display. To do this, add the form number to the Intent through the
putExtra method:
newFormInfo.putExtra("formNumber", formNumber.getText().toString());
This value is extracted by the RunForm class, shown later.
Now that you have set up the Intent, you launch the Activity with a call to
startActivity:
startActivity(newFormInfo);
With your application, the user enters the form number and clicks the Run Form
button. This triggers the events described above, causing the RunForm class to
process the request. Entering a form number is really just a test tool for the purposes
of this tutorial. There are other means by which this triggering event can take place.More practical examples include customized links from a web page, a message
pushed through Short Message Service (SMS), a location-based trigger based on
proximity, or even a scanned QR code (Quick Response code).
Running the form
The RunForm class is the choreographer for this application. It is launched with a form
number to process. Now examine the onCreate() method in Listing 6.
Listing 6. The onCreate() method
public class RunForm extends Activity {
/** Called when the activity is first created. */
String tag = RunForm.class.getName();
XmlGuiForm theForm;
ProgressDialog progressDialog;
Handler progressHandler;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String formNumber = "";
Intent startingIntent = getIntent();
if(startingIntent == null) {
Log.e(tag,"No Intent? We're not supposed to be here...");
finish();return;
}
formNumber = startingIntent.getStringExtra("formNumber");
Log.i(tag,"Running Form [" + formNumber + "]");
if (GetFormData(formNumber)) {
DisplayForm();
}
else
{
Log.e(tag,"Couldn't parse the Form.");
AlertDialog.Builder bd = new AlertDialog.Builder(this);
AlertDialog ad = bd.create();
ad.setTitle("Error");
-
7/27/2019 IBM Xforms
20/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 20 of 42
ad.setMessage("Could not parse the Form data");
ad.show();
}
}
// other methods omitted and shown later
}
As seen in the code in Listing 6, first you extract the formNumber from the Intent that
triggered the Activity. Without a form number to process, this Activity has nothing
to perform.
Once you extract the value, the next requirement is to connect to the server to
download the form specifications. (Note that an enhancement of this approach might
be to look for this form's metadata in a local cache prior to fetching the data.) Listing
7 shows the GetFormData() method.
Listing 7. The GetFormData() method
private boolean GetFormData(String formNumber) {
try {
Log.i(tag,"ProcessForm");
URL url = new URL("http://www.example.com/xmlgui" + formNumber + ".xml");
Log.i(tag,url.toString());
InputStream is = url.openConnection().getInputStream();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder db = factory.newDocumentBuilder();
Document dom = db.parse(is);
Element root = dom.getDocumentElement();
NodeList forms = root.getElementsByTagName("form");
if (forms.getLength() < 1) {
// nothing here??
Log.e(tag,"No form, let's bail");
return false;
}Node form = forms.item(0);
theForm = new XmlGuiForm();
// process form level
NamedNodeMap map = form.getAttributes();
theForm.setFormNumber(map.getNamedItem("id").getNodeValue());
theForm.setFormName(map.getNamedItem("name").getNodeValue());
if (map.getNamedItem("submitTo") != null)
theForm.setSubmitTo(map.getNamedItem("submitTo").getNodeValue());
else
theForm.setSubmitTo("loopback");
// now process the fields
NodeList fields = root.getElementsByTagName("field");
for (int i=0;i
-
7/27/2019 IBM Xforms
21/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 21 of 42
Log.i(tag,theForm.toString());
return true;
} catch (Exception e) {
Log.e(tag,"Error occurred in ProcessForm:" + e.getMessage());
e.printStackTrace();
return false;
}
}
This code is responsible for taking data from a metadata repository, in this case by
downloading an XML file from a Webserver:
URL url = new URL("http://10.211.55.2/~fableson/xmlgui" + formNumber + ".xml");
Manipulate the XML data through a DOM parser, to extract the form and field
elements plus attributes and store them in instances of the XmlGuiForm and
XmlGuiFormField classes respectively. The bulk of this method is dedicated to the
parsing and populating tasks.
Two main approaches to XML parsing are DOM and SAX. The DOM parser works
by parsing a document into memory and then the application walks a Document
Object Model tree to gain access to various elements of data contained in the XML.
You also could also use the SAX parser model here because you build your own
representation of the document by populating the two classes.
The advantage of the DOM approach for this application is that it is somewhat
procedural and easy to follow the code, whereas the SAX approach requires call-
back functions where only the desired data is stored. The complexity of the code
written by the developer to implement the SAX callback functions can be noticeablyhigher than the DOM approach in some instances. Because the XML data is fully
parsed in the DOM approach, it is a bit more memory intensive. For your purposes in
this application, the simplicity and easy-to-follow nature of DOM was a bigger driver
than memory management as the metadata form is quite small.
See Resources for an excellent reference on coding XML parsers in Android.
You have transformed the XML metadata form to Java class instances. It is now time
to display the form to gather data from the user.
Section 6. Gather user data
Now that you've created the main Activity screen layout, you can create user
interface forms for collecting data. Here you'll create a Robotics Club Registration
form and an Auto Maintenance survey form.
-
7/27/2019 IBM Xforms
22/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 22 of 42
Using the metadata
This application hinges upon the ability of Android programmers to dynamically
manipulate the user interface. Earlier in the tutorial, you examined the main.xml file,
the file that defines the screen layout of the XmlGui class (the main Activity). This
application would be virtually impossible in its current form if you had to always defineuser interface elements at design or compile time.
Thankfully, you are not constrained in that manner. The DisplayForm() method is
responsible for converting the metadata into user interface elements for the purposes
of collecting data. The code is essentially broken into two main functional areas: the
layout of the user interface elements and then the handling of the submit button.
First, examine the layout logic. This is the code that turns the XmlGuiForm object into
a real on-the-screen form. Listing 8 shows this code.
Listing 8. The layout logicprivate boolean DisplayForm()
{
try
{
ScrollView sv = new ScrollView(this);
final LinearLayout ll = new LinearLayout(this);
sv.addView(ll);
ll.setOrientation(android.widget.LinearLayout.VERTICAL);
// walk through the form elements and dynamically create them,
// leveraging the mini library of tools.
int i;
for (i=0;i
-
7/27/2019 IBM Xforms
23/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 23 of 42
ll.addView(btn);
btn.setText("Submit");
btn.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
// check if this form is Valid
if (!CheckForm())
{
AlertDialog.Builder bd = new AlertDialog.Builder(ll.getContext());AlertDialog ad = bd.create();
ad.setTitle("Error");
ad.setMessage("Please enter all required (*) fields");
ad.show();
return;
}
if (theForm.getSubmitTo().equals("loopback")) {
// just display the results to the screen
String formResults = theForm.getFormattedResults();
Log.i(tag,formResults);
AlertDialog.Builder bd = new AlertDialog.Builder(ll.getContext());
AlertDialog ad = bd.create();
ad.setTitle("Results");
ad.setMessage(formResults);ad.show();
return;
} else {
if (!SubmitForm()) {
AlertDialog.Builder bd = new AlertDialog.Builder(ll.getContext());
AlertDialog ad = bd.create();
ad.setTitle("Error");
ad.setMessage("Error submitting form");
ad.show();
return;
}
}
}
} );
setContentView(sv);
setTitle(theForm.getFormName());
return true;
} catch (Exception e) {
Log.e(tag,"Error Displaying Form");
return false;
}
}
You must anticipate the availability of more fields than can fit on a single screen, so
use a ScrollView as the parent view or container. Within that ScrollView you employa vertical LinearLayout to organize the various user interface widgets into a vertical
column.
The approach is pretty simple:
You enumerate through the list of XmlGuiFormField objects contained within the
fields member of the XmlGuiForm instance.
-
7/27/2019 IBM Xforms
24/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 24 of 42
Depending on the type of field requested, a different user interface element is
instantiated and added to the LinearLayout. You will examine the different UI
widgets momentarily.
Once the UI elements are created and added to the linear layout, you assign the
entireScrollView
instance to the content of this screen and assign the form name asthe title of the screen. Figure 9 shows a Robotics club registration screen ready for
user input. This form is the result of processing the XML data found back in Listing 1.
Figure 9. Robotics registration form in action
Let's have a look at the different custom user interface widgets created for this
application.
Recall that three types of data entry fields are defined for this application: text,
numeric, and choice. These three types are implemented through two different
custom widgets: XmlGuiEditBox and XmlGuiPickOne.
The text and numeric values are so similar you can leverage the same EditView
approach, but with different input filters to switch between alpha-numeric and numeric
only. Listing 9 shows the code for the XmlGuiEditBox class.
Listing 9. The XmlGuiEditBox class
package com.msi.ibm;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
-
7/27/2019 IBM Xforms
25/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 25 of 42
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.EditText;
import android.text.method.DigitsKeyListener;
public class XmlGuiEditBox extends LinearLayout {
TextView label;
EditText txtBox;
public XmlGuiEditBox(Context context,String labelText,String initialText) {
super(context);
label = new TextView(context);
label.setText(labelText);
txtBox = new EditText(context);
txtBox.setText(initialText);
txtBox.setLayoutParams(new LayoutParams(ViewGroup.LayoutParams
.FILL_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT));
this.addView(label);
this.addView(txtBox);
}
public XmlGuiEditBox(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub}
public void makeNumeric()
{
DigitsKeyListener dkl = new DigitsKeyListener(true,true);
txtBox.setKeyListener(dkl);
}
public String getValue()
{
return txtBox.getText().toString();
}
public void setValue(String v)
{
txtBox.setText(v);
}
}
The XmlGuiEditBox class extends the LinearLayout class and contains both a textual
label to describe the requested input and an EditText to actually collect the entered
data. All of the object initialization is done in the constructor. This may be considered
bad form, but this is an exercise left to you if you're uncomfortable with that approach.
There are three other methods to discuss. The getValue() and setValue() methods
do just what you would think. They are the getter and setter for interacting with the
EditText field.
The third method, makeNumeric() is only called when setting up a form field type of
numeric. An instance of the DigitsKeyListener is employed to filter out any non-
numeric keys. The other nice thing that you get for free is the proper keyboard is
shown depending on which type of XmlGuiEditBox is in usewith or without the
numeric setting.
Figure 10 shows the form in action with an alpha keyboard shown because the Last
Name field is set for alpha entry, in other words text.
-
7/27/2019 IBM Xforms
26/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 26 of 42
Figure 10. Alphanumeric key entry
Figure 11 shows the numeric keyboard in use because the age field is set for the
data type of numeric.
-
7/27/2019 IBM Xforms
27/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 27 of 42
Figure 11. Numeric keyboard
The choice field, implemented in the user interface through the XmlGuiPickOne
class, is a little different. The choice field is implemented as an Android Spinner
widget. This user interface element is analogous to a drop-down list box in other
programming environments, where the user must select from one of the existingchoices. Figure 12 shows three instances XmlGuiPickOne widget.
-
7/27/2019 IBM Xforms
28/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 28 of 42
Figure 12. Auto maintenance survey with three XmlGuiPickOne instances
In this example, the data being collected is for statistical purposes, so normalizing
the possible entries makes the data processing cleaner than dealing with free text
entry fields. Of course, you can define the State field as a choice field if you wanted
to constrain the survey to a particular geographical region.
Listing 10 shows the code for the XmlGuiPickOne class.
Listing 10. The XmlGuiPickOne class
package com.msi.ibm;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Spinner;
import android.widget.ArrayAdapter;
public class XmlGuiPickOne extends LinearLayout {String tag = XmlGuiPickOne.class.getName();
TextView label;
ArrayAdapter aa;
Spinner spinner;
public XmlGuiPickOne(Context context,String labelText,String options) {
super(context);
label = new TextView(context);
label.setText(labelText);
spinner = new Spinner(context);
String []opts = options.split("\\|");
aa = new ArrayAdapter( context,
android.R.layout.simple_spinner_item,opts);
-
7/27/2019 IBM Xforms
29/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 29 of 42
spinner.setAdapter(aa);
this.addView(label);
this.addView(spinner);
}
public XmlGuiPickOne(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public String getValue()
{
return (String) spinner.getSelectedItem().toString();
}
}
This class looks very similar to the XmlGuiEditBox class. The major difference is that
a Spinner control is employed rather than an EditText control. Also, note that this
class only implements the getValue() method. An obvious enhancement to this class
is permit the user to specify a default value.
Note the use of the options member to populate the list of choices. In this code,
the String containing the available choices is split into an array using a regex
expression and then passed to an instance of an ArrayAdapter. The constant
android.R.layout.simple_spinner_item is built-in to Android. It was not supplied in
the tutorial application code. Once the adapter is set up, you assign it to the Spinner.
Figure 13 shows the list of choices displayed on the screen, prompting the user for
the typical number of miles between oil changes.
-
7/27/2019 IBM Xforms
30/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 30 of 42
Figure 13. XmlGuiPickOne asking about oil changes
Now that the user can enter data into the form, it is time to validate and submit the
data.
Section 7. Save and submit data
You must now create a way for users to save the data by validating it and submitting
it to a server.
Saving dataIt is time to jump back into the DisplayForm() method of the RunForm class. Recall
that the first portion of this method is responsible for the drawing of the form. Next,
you will examine the onClick() handler of the submit button, in Listing 11.
Listing 11. The onClick() handlerbtn.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
// check if this form is Valid
if (!CheckForm())
{
AlertDialog.Builder bd = new AlertDialog.Builder(ll.getContext());
AlertDialog ad = bd.create();
ad.setTitle("Error");
ad.setMessage("Please enter all required (*) fields");
ad.show();
return;
-
7/27/2019 IBM Xforms
31/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 31 of 42
}
if (theForm.getSubmitTo().equals("loopback")) {
// just display the results to the screen
String formResults = theForm.getFormattedResults();
Log.i(tag,formResults);
AlertDialog.Builder bd = new AlertDialog.Builder(ll.getContext());
AlertDialog ad = bd.create();
ad.setTitle("Results");
ad.setMessage(formResults);ad.show();
return;
} else {
if (!SubmitForm()) {
AlertDialog.Builder bd = new AlertDialog.Builder(ll.getContext());
AlertDialog ad = bd.create();
ad.setTitle("Error");
ad.setMessage("Error submitting form");
ad.show();
return;
}
}
}
} );
When the submit button is selected by the user, the form entries are checked to
make sure that all of the required fields are populated. If not, an AlertDialog reminds
the user to populate all of the fields. Assuming the data has been entered in a
satisfactory manner, it is time to submit the data.
The process of submitting the data falls into one of two camps for this tutorial
application. If the submitTo field of the form has been set to the value of loopback,
the values are simply echoed to the screen. This is useful for testing purposes. Once
you are satisfied that the form tool is collecting data properly, it is time to point it to a
server page which is responsible for recording the entries.
Listing 12 shows the CheckForm() method. This code is rather straight-forward.
Each field is checked to see if it is required. If the field is required but the user has
not provided the information, a flag is set. You could enhance this to provide more
specific feedback to the user.
Listing 12. The CheckForm() method
private boolean CheckForm()
{
try {
int i;boolean good = true;
for (i=0;i
-
7/27/2019 IBM Xforms
32/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 32 of 42
good = false;
}
}
}
}
return good;
} catch(Exception e) {
Log.e(tag,"Error in CheckForm()::" + e.getMessage());e.printStackTrace();
return false;
}
}
Now it is time to submit the collected data to the server. Examine the SubmitForm()
method in Listing 13.
Listing 13. The SubmitForm() method
private boolean SubmitForm()
{
try {
boolean ok = true;
this.progressDialog = ProgressDialog.show(this,
theForm.getFormName(), "Saving Form Data", true,false);
this.progressHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
// process incoming messages here
switch (msg.what) {
case 0:
// update progress bar
progressDialog.setMessage("" + (String) msg.obj);
break;
case 1:
progressDialog.cancel();finish();
break;
case 2:
progressDialog.cancel();
break;
}
super.handleMessage(msg);
}
};
Thread workthread = new Thread(new TransmitFormData(theForm));
workthread.start();
return ok;
} catch (Exception e) {
Log.e(tag,"Error in SubmitForm()::" + e.getMessage());
e.printStackTrace();
// tell user that the submission failed....
Message msg = new Message();
msg.what = 1;
this.progressHandler.sendMessage(msg);
return false;
}
}
-
7/27/2019 IBM Xforms
33/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 33 of 42
First, you set up an instance of the android.os.Handler class. The Handler class
is helpful when an application needs to share data with different threads. Another
important item to note in the SubmitForm() method is the use of a ProgressDialog.
Note that the ProgressDialog and Handler are defined as class level variables in
Listing 14.
Listing 14. The ProgressDialog and Handler
public class RunForm extends Activity {
/** Called when the activity is first created. */
String tag = RunForm.class.getName();
XmlGuiForm theForm;
ProgressDialog progressDialog;
Handler progressHandler;
...
}
You don't want to unnecessarily block the application while communicating with the
server, so you employ a background Thread to communicate, but you rely on theHandler to receive notifications from the communications thread in order to provide
feedback to the user. Note that only the main thread is supposed to interact with the
user interface. An alternative to the separate thread approach is the AsyncTask class
found in the android.os package.
As the application connects to the server to transfer the data, it has the opportunity to
inform the user of the status of the operation, which is of course good practice. Figure
14 shows the ProgressDialog in action.
-
7/27/2019 IBM Xforms
34/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 34 of 42
Figure 14. The ProgressDialog
The actual server communications code is found in Listing 15, in the
TransmitFormData() class, which implements the Runnable interface.
Listing 15. The TransmitFormData class
private class TransmitFormData implements Runnable
{
XmlGuiForm _form;
Message msg;
TransmitFormData(XmlGuiForm form) {
this._form = form;
}
public void run() {
try {
msg = new Message();
msg.what = 0;
msg.obj = ("Connecting to Server");
progressHandler.sendMessage(msg);
URL url = new URL(_form.getSubmitTo());
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
BufferedOutputStream wr = new BufferedOutputStream
(conn.getOutputStream());
String data = _form.getFormEncodedData();
wr.write(data.getBytes());
wr.flush();
wr.close();
msg = new Message();
msg.what = 0;
-
7/27/2019 IBM Xforms
35/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 35 of 42
msg.obj = ("Data Sent");
progressHandler.sendMessage(msg);
// Get the response
BufferedReader rd = new BufferedReader(new
InputStreamReader(conn.getInputStream()));
String line = "";
Boolean bSuccess = false;
while ((line = rd.readLine()) != null) {if (line.indexOf("SUCCESS") != -1) {
bSuccess = true;
}
// Process line...
Log.v(tag, line);
}
wr.close();
rd.close();
if (bSuccess) {
msg = new Message();
msg.what = 0;
msg.obj = ("Form Submitted Successfully");
progressHandler.sendMessage(msg);
msg = new Message();
msg.what = 1;
progressHandler.sendMessage(msg);
return;
}
} catch (Exception e) {
Log.d(tag, "Failed to send form data: " + e.getMessage());
msg = new Message();
msg.what = 0;
msg.obj = ("Error Sending Form Data");
progressHandler.sendMessage(msg);
}
msg = new Message();
msg.what = 2;
progressHandler.sendMessage(msg);
}
}
The TransmitFormData class is responsible for connecting to the server listed in
the submitTo member of the XmlGuiForm instance (as taken from the metadata). It
periodically updates the main application thread by sending an instance of a Message
class to the handler through the sendMessage() method. Two members are populated
on the Message class:
The what value acts as a high-level switch informing the Handler what it shoulddo with the message.
The obj value specifies an optional java.lang.Object. In this case, a
java.lang.String instance is passed and used for displaying in the Progress
Dialog.
The schema used by any given application is arbitrary. This application uses the
values in Table 3.
-
7/27/2019 IBM Xforms
36/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 36 of 42
Table 3. The application values allowed for what
Value Comment
0 Obj contains a text string to display to the user.
1 Successful completion of transmission, you're done!
2 An error occurred. Tell the user that something is wrong and
don't throw away the data!
Figure 15 shows the final message in the ProgressDialog upon a successful
transmission of Form Data.
Figure 15. Form submission
Once the form has been successfully submitted, the application returns to the main
page. For a production-ready application, what takes place next is highly dependent
on the motives of the data gathering organization. The screen can simply reset to
take another entry, as in a physical inventory application. Or perhaps you can directthe user to some other screen.
For the application to run properly, the AndroidManifest.xml file must contain
references to all of the used Activity classes and must include the uses-permission
for Internet access. Listing 16 shows the AndroidManifest.xml file for the tutorial's
application.
-
7/27/2019 IBM Xforms
37/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 37 of 42
Listing 16. The AndroidManifest.xml file
Before wrapping up, take a brief look at the server side script.
Section 8. Provide a server side script
For the purposes of this tutorial, you will use a PHP script to gather the required data,
and append it to a text file.
On the server
Exactly what transpires on the server is dependent on the needs of the organization
collecting the data. A common approach for data collection is to store the form data in
a relational database such as DB2, MySQL, SQL Server, Oracle, and so on. Once
the data is in the database, it can be sliced, diced, and analyzed.
For this tutorial, the data is gathered by a PHP script and appended to a text file.
Listing 17 shows the PHP form associated with the Robotics registration form.
Listing 17. The Robotic's PHP form
-
7/27/2019 IBM Xforms
38/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 38 of 42
$f = fopen($filename,"a");
fprintf($f,"Data received @ ".date(DATE_RFC822));
fprintf($f,"\n");
fprintf($f,'First Name:['.$_POST['fname'].']');
fprintf($f,"\n");
fprintf($f,'Last Name:['.$_POST['lname'].']');
fprintf($f,"\n");
fprintf($f,'Gender:['.$_POST['gender'].']');
fprintf($f,"\n");fprintf($f,'Age:['.$_POST['age'].']');
fprintf($f,"\n");
fclose($f);
print "SUCCESS";
?>
If the script returns the string SUCCESS, the RunForm class will reset. Any other value
will cause an error message to be displayed to the user and permit them to correct
their entries or otherwise obtain help in submitting the form.
Section 9. Conclusion
This tutorial presented a framework for serving dynamic questions to an Android user
based on a native application approach utilizing the Android SDK. You saw dynamic
form presentation, validation and processing techniques, and application-to-web
server communications.
-
7/27/2019 IBM Xforms
39/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 39 of 42
Downloads
Description Name Size Download
method
Forms engine source code formsengine.zip 78KB HTTP
Information about download methods
http://www.ibm.com/developerworks/library/whichmethod.htmlhttp://www.ibm.com/developerworks/apps/download/index.jsp?contentid=516603&filename=formsengine.zip&method=http&locale= -
7/27/2019 IBM Xforms
40/42
developerWorks ibm.com/developerWorks/
Build dynamic user interfaces with Android and XML Page 40 of 42
Resources
Learn
Develop Android applications with Eclipse (Frank Ableson, developerWorks,
February 2008): The easiest way to develop Android applications is to useEclipse. Learn all about this in this developerWorks tutorial.
Networking with Android (Frank Ableson, developerWorks, June 2009): Explore
the networking capabilities of Android.
Working with XML on Android (Michael Galpin, developerWorks, June 2009):
Learn about the different options for working with XML on Android and how to
use them to build your own Android applications.
Unlocking Android, 2nd Edition (Frank Ableson, Robi Sen, and Chris King;
Manning Publications; December 2010): Cover all aspects of Android
development with concise, hands-on instruction for the Android operating
system and development tools. Mobile Design and Development(Brian Fling, O'Reilly Media, 2009): Read
about practical guidelines, standards, techniques, and best practices for
building mobile products in this book.
Android SDK documentation: Get the latest information in the Android API
reference.
The Open Handset Alliance: Visit Android's sponsor.
Introduction to Android Development (Frank Ableson, developerWorks, May
2009): Get an introduction to the Android platform and learn how to code a
basic Android application.
Under the Hood of Native Web Apps for Android: Learn about hybridapplications in Android.
More articles and tutorials by this author(Frank Ableson, developerWorks, April
2002-current): Read articles about Android, XML, Eclipse, GPS, BlackBerry
applications, and other technologies.
XML area on developerWorks: Get the resources you need to advance your
skills in the XML arena.
My developerWorks: Personalize your developerWorks experience.
IBM XML certification: Find out how you can become an IBM-Certified
Developer in XML and related technologies.
XML technical library: See the developerWorks XML Zone for a wide range of
technical articles and tips, tutorials, standards, and IBM Redbooks. Also, read
more XML tips.
developerWorks technical events and webcasts: Stay current with technology in
these sessions.
developerWorks on Twitter: Join today to follow developerWorks tweets.
developerWorks podcasts: Listen to interesting interviews and discussions for
software developers.
Get products and technologies
http://www.ibm.com/developerworks/podcast/http://www.ibm.com/developerworks/podcast/http://twitter.com/developerworks/http://www.ibm.com/developerworks/offers/techbriefings/http://www.ibm.com/developerworks/views/xml/libraryview.jsp?search_by=tip:http://www.ibm.com/developerworks/views/xml/library.jsphttp://www.ibm.com/certify/certs/01001503.shtmlhttp://www.ibm.com/developerworks/mydeveloperworkshttp://www.ibm.com/developerworks/mydeveloperworkshttp://www.ibm.com/developerworks/xmlhttp://www.ibm.com/developerworks/views/global/libraryview.jsp?site_id=1&contentarea_by=global&sort_by=Date&sort_order=2&start=1&end=39&topic_by=-1&product_by=-1&type_by=All%20Types&show_abstract=true&search_by=Frank+Ablesonhttp://www.ibm.com/developerworks/views/global/libraryview.jsp?site_id=1&contentarea_by=global&sort_by=Date&sort_order=2&start=1&end=39&topic_by=-1&product_by=-1&type_by=All%20Types&show_abstract=true&search_by=Frank+Ablesonhttp://www.linux-mag.com/id/7633http://www.ibm.com/developerworks/library/os-android-devel/http://www.openhandsetalliance.com/http://www.openhandsetalliance.com/http://developer.android.com/reference/packages.htmlhttp://oreilly.com/catalog/9780596155445/http://oreilly.com/catalog/9780596155445/http://manning.com/ableson2http://www.ibm.com/developerworks/library/x-android/http://www.ibm.com/developerworks/library/os-android-networking/http://www.ibm.com/developerworks/library/os-android-networking/http://www.ibm.com/developerworks/podcast/http://twitter.com/developerworks/http://www.ibm.com/developerworks/offers/techbriefings/http://www.ibm.com/developerworks/views/xml/libraryview.jsp?search_by=tip:http://www.ibm.com/developerworks/views/xml/library.jsphttp://www.ibm.com/certify/certs/01001503.shtmlhttp://www.ibm.com/developerworks/mydeveloperworkshttp://www.ibm.com/developerworks/xmlhttp://www.ibm.com/developerworks/views/global/libraryview.jsp?site_id=1&contentarea_by=global&sort_by=Date&sort_order=2&start=1&end=39&topic_by=-1&product_by=-1&type_by=All%20Types&show_abstract=true&search_by=Frank+Ablesonhttp://www.linux-mag.com/id/7633http://www.ibm.com/developerworks/library/os-android-devel/http://www.openhandsetalliance.com/http://developer.android.com/reference/packages.htmlhttp://oreilly.com/catalog/9780596155445/http://manning.com/ableson2http://www.ibm.com/developerworks/library/x-android/http://www.ibm.com/developerworks/library/os-android-networking/http://www.ibm.com/developerworks/edu/os-dw-os-eclipse-android.html -
7/27/2019 IBM Xforms
41/42
ibm.com/developerWorks/ developerWorks
Build dynamic user interfaces with Android and XML Page 41 of 42
Android SDK: Download the Android SDK, access the API reference, and get
the latest news on Android from the official Android developers' site. Version 1.5
and later will work for this article's exercise.
Eclipse: Obtain the latest Eclipse IDE.
Android Open Source Project: Android is open source, which means that you
can get the source code here. IBM product evaluation versions: Download or explore the online trials in
the IBM SOA Sandbox and get your hands on application development
tools and middleware products from DB2, Lotus, Rational, Tivoli, and
WebSphere.
Discuss
XML zone discussion forums: Participate in any of several XML-related
discussions.
developerWorks blogs: Check out these blogs and get involved.
http://www.ibm.com/developerworks/blogs/http://www.ibm.com/developerworks/forums/dw_xforums.jsphttp://www.ibm.com/developerworks/downloads/soasandbox/http://www.ibm.com/developerworks/downloads/soasandbox/http://www.ibm.com/developerworks/downloads/http://source.android.com/http://eclipse.org/downloads/http://developer.android.com/sdk/index.html -
7/27/2019 IBM Xforms
42/42
developerWorks ibm.com/developerWorks/
About the author
Frank Ableson
W. Frank Ableson is an entrepreneur living in northern New Jerseywith his wife Nikki and their children. His professional interests include
mobile software and embedded design. He is the author of Unlocking
Android(Manning Publications, 2010), and he is the mobile editor for
Linux Magazine.
Copyright IBM Corporation 2010
(www.ibm.com/legal/copytrade.shtml)
Trademarks
(www.ibm.com/developerworks/ibm/trademarks/)
http://www.ibm.com/developerworks/ibm/trademarks/http://www.ibm.com/legal/copytrade.shtmlhttp://linux-mag.com/blogs/fablesonhttp://manning.com/ableson2http://manning.com/ableson2