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:
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
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.
After deployment of the web service application we can test it.
Invoking the operation findSpeedTrapsView:
Invoking the operation 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
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.
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.
Finally, I would like to thank my colleague Paco van der Linden for helping me setting up the web service interface in ADF 11g.