Android puts Oracle on the (Google) map

For a couple of months I have been discovering the Android platform. As an original Oracle developer I was wondering how an Android app can be connected to an Oracle database.
For this purpose I developed an Android app that stores speed traps that users may hit while driving, into an Oracle database. The app also retrieves these speed traps from the database and draws them onto a Google map:

Fig. 1 After pressing the Android device’s menu button, two menu options ‘Retrieve’ and ‘Report’ (speed traps) appear.

Fig. 1 After pressing the Android device’s menu button, two menu options ‘Retrieve’ and ‘Report’ (speed traps) appear.

Fig. 2 After pressing the ‘Retrieve’ option all speed traps already stored in the database appear as markers on the map.

Fig. 2 After pressing the ‘Retrieve’ option all speed traps already stored in the database appear as markers on the map.

Fig. 3 When tapping on a marker a dialog appears with date and address information related to this specific speed trap.

Fig. 3 When tapping on a marker a dialog appears with date and address information related to this specific speed trap.

Fig. 4 After spotting a speed trap and pressing the ‘Report’ option, your current location (the speed trap) will be stored in the database.

Fig. 4 After spotting a speed trap and pressing the ‘Report’ option, your current location (the speed trap) will be stored into the database.

SPEED_TRAPS table
In order to achieve all this I first created a database table SPEED_TRAPS:
CREATE TABLE SPEED_TRAPS
(
ID NUMBER(6) NOT NULL,
LATITUDE NUMBER(11,8) NOT NULL,
LONGITUDE NUMBER(11,8) NOT NULL,
CREATION_DATE DATE NOT NULL,
CONSTRAINT SPS_PK PRIMARY KEY
(
ID
)
ENABLE
)
/

A before-row-insert trigger on this table will fill the creation_date column with sysdate (today’s date) and the id column with a sequence (sequential number). The latitude and longitude columns will be filled by the Android app (of course).

Creating the web service interface
ADF Business Components can easily be exposed through a web service interface. I refer to a blog post of Lucas Jellema: Quickly creating, deploying and testing a WebService interface for ADF Business Components. After creating the ADF BC Project, an Entity Object on the SPEED_TRAPS table, its corresponding Updateable View Object and an Application Module, we can add a Service Interface to this Application Module as described in forementioned blog post.

By the way I marked the Entity Object attributes Id and CreationDate as not mandatory; values for these attributes are not generated by the app, but by the database (before-row-insert trigger on the table) at the end of the process. So not-null-validation by the ADF Business Components layer will not occur for these attributes when reporting a new speed trap, which is the correct behavior.
To the Service Interface I included the single view instance SpeedTrapsView1 as ViewObject and specified Create (report a speed trap) and Find (retrieve all speed traps) as CRUD operations to be supported on it (see fig. 5). The method names findSpeedTrapsView and createSpeedTrapsView will become the operation names in the WSDL for the web service.

Fig. 5 Including a View Object instance and its operations to a Service Interface.

Fig. 5 Including a View Object instance and its operations to a Service Interface.

After deployment of the web service application we can test it.
Invoking the operation findSpeedTrapsView:

Fig. 6 Invoking the SOAP request findSpeedTrapsView.

Fig. 6 Invoking the SOAP request findSpeedTrapsView.

Results in:

Fig. 7 Getting the SOAP response of findSpeedTrapsView.

Fig. 7 Getting the SOAP response of findSpeedTrapsView.

Invoking the operation createSpeedTrapsView:

Fig. 8 Invoking the SOAP request createSpeedTrapsView.

Fig. 8 Invoking the SOAP request createSpeedTrapsView.

Results in:

Fig. 9 Getting the SOAP response of createSpeedTrapsView.

Fig. 9 Getting the SOAP response of createSpeedTrapsView.

SOAP web service call by Android
The Android SDK does not contain any framework or library for making SOAP calls. The ksoap2-android open source project provides a lightweight and efficient SOAP library for the Android platform that handles the XML and HTTP work. You have to add it as an External Library to your project (in a non-Maven project). You can download this library at http://code.google.com/p/ksoap2-android/wiki/HowToUse?tm=2

retrieveSpeedTraps()
When tapping the ‘Retrieve’ menu option in the Android app, the method retrieveSpeedTraps() of activity class SpeedTraps (fig. 10) is called. This method executes the findSpeedTrapsView SOAP call from fig. 6 after this request is composed. The values of the local variables SOAP_ACTION, NAMESPACE and METHOD_NAME of retrieveSpeedTraps() are marked in yellow in this figure.

reportSpeedTrap()
When tapping the ‘Report’ menu option in the Android app, the method reportSpeedTrap() of activity class SpeedTraps (fig. 10) is called. This method executes the createSpeedTrapsView SOAP call from fig. 8 after this request is composed. The values of the local variables SOAP_ACTION, NAMESPACE _1, NAMESPACE _2, METHOD_NAME_1 and METHOD_NAME_2 of reportSpeedTrap() are marked in yellow in this figure. The challenge here was to compose the request in the correct format, because of the two (yellow marked) namespaces in it. The ksoap2-android library takes only account of one when creating a new SoapObject, so I did some fiddling by introducing the setProperty() method. Running the app in debug mode, setting the mHttpTransportSE debug field to true and then analyzing its requestDump field (the string representation of the SOAP call) has helped me a lot to get this done.

Fig. 10 SpeedTraps class

Fig. 10 SpeedTraps class

Fig. 11 MarkerLayer class

Fig. 11 MarkerLayer class

Fig. 12 MyLocation class

Fig. 12 MyLocation class

Finally, I would like to thank my colleague Paco van der Linden for helping me setting up the web service interface in ADF 11g.

Resources
Download the JDeveloper 11g web service project: SpeedTrapsWS
Download the Eclipse Android project: SpeedTraps