Monday, 15 September 2014

Android App consuming oData v4 Service

This Android Application demonstrates


  1. how to consume oData V4 Service
  2. Periodically pull the data using timer from external oData Service
  3. Show data in multi-column list view
  4. Show different column list on portrait and landscape mode

oData is a industry standard protocol for consuming and producing data API built on HTTP and REST.
 Refer http://www.odata.org/ for details of oData.


I am using http://olingo.apache.org/ Apache olingo android client library for odata v4 support



http://odata4j.org/ does not support oData v4



 Apache olingo library's support for V4 is still under beta, one need to download the source from Apache olingo Source and build android library using Apache maven


For setting up oData V4 Server application using Microsoft Visual Studio 2013 refer to my blog

 Web API 2 Application using EntityFramework 6.0 supporting oData v4

This website is hosted in my PC with website name as Alerts

Pre-requisites
I have setup Android development environment . I am using Eclipse 
    Version: Juno Service Release 2
   Build id: 20130225-0426
and Android SDK upto date

  The Project consists of mainly MainActivity with a ListView to display Alerts list, A Custom Adapter (AlertsAdapter class) to feed data to the ListView, and a DataService class which pulls data from Server using oData protocol and pump it to Adapter class.
MainActivity uses a Timer task to pull data periodically from Server

1. Create Project 

Create Empty Android Project with MainActivity extending Activity
Add a ListView to activity_main.xml layout


2. Create Data Object class AlertsData


3. Create DataService class

Since DataService is going to use networking/Sockets underneath, we need to run it in non-UI thread, hence it is created as Async Task class , so extend this from AsyncTask<> class
Override doInBackground() and onPostExecute() methods

doInBackground

In this method connect to oData V4 data service, get Alerts entity set and store it in an array of custom data object (AlertData)

onPostExecute

In this method AlertsData is filled into ListView adapter object. Every time old data is cleared before new data is added

Since this class is going to use the oData classes copy the odata jar file (the version I built from source) 
olingo-client-android-4.0.0-beta-01-SNAPSHOT.jar into project's libs folder and add as External Jar to buildpath

Add following member variables to the class




Fill  the methods doInBackground and onPostExecute as shown below




4. Create Custom DataAdapter class


Create the layout xml for columns for the ListView row

alerts_listitem_row.xml



The LinearLayout is set with orientation Horizontal and each column is a TextView
The weights are adjusted according to column width requirement
This layout will be used in AlertsAdapter class by inflating thsi for each row data

Create AlertsAdapter derived from ArrayAdapter<AlertsData>
create a nested class alertHolder to hold textviews for all the columns of ListView row 

override getView() to custom display each row
Add helper functions FillHolder() and displayFromHolder() to get TextViews for each of the columns and display values for each row column values




5. Binding Together


Following two member variables are added to class MainActivity and the below code in onCreate() method -




6. Application Configuration Changes


We force the ListView display to landscape orientation by setting in AndroidManifest.xml Activity attribute as shown -

...
<activity
        android:name=".MainActivity"

android:screenOrientation="landscape"
...

Since we need to access network, INTERNET Access permission need to be requested in  in AndroidManifest.xml
...
<uses-permission android:name="android.permission.INTERNET"/>
...

7. Build & Run the Application

Application was run under these two Devices:

iBall Slide Phablet model 7236 2G dual core cortex A7 1.3 ghz
Android 4.2.2 SDK 17

Xolo X900 Intel Atom duel core 1.6 GHZ
Android 4.0.4 SDK 15

Screen snapshot on Xolo X900



You may download the project from AlertsAppV1.zip or
github AlertsAppv1

8. Using Timer to periodically pull data



Create an TimerTask extended class



Modify MainActivity class onCreate() method as follows


The dataService is created and executed in TimerTask instead of in onCreate()

Please note we need to create each time new instance of DataService, as one instance can execute only once


Build & Run

Application ran on iBall Slide as expected, executing getData every 10 sec

However on Xolo, throws 


java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()


It looks like problem is with older version of android (SDK 15) and seem to work on SDK 17

Anyway ensuring DataService task runs in UI thread, the problem gets solved as follows -


You may download this version from  AlertsAppV2.zip

9. Enhancing the application to show different column list on portrait and landscape mode

Need to do following changes

  • create a new list item row for portrait mode
  • create a new AlertsAdapter class to handle data display in ListView 
  • Override onConfigurationChanged to intercept orientation changes



Modify the Manifest  file as follows -

  • remove under activity the orientation   android:screenOrientation="landscape"
  • add  android:configChanges="orientation|keyboardHidden|screenSize"




alerts_listitem_min_row.xml



Modify AlertsAdapter class qualifying AlertsHolder class as protected
Create a class AlertsAdapterMini extending AlertsAdapter class and override FillHolder and displayFromHolder methods as follows -





override onConfigurationChanged to intercept orientation change in MainActivity class -



Next Modify the onCreate method of MainActivity class



Build and run the project

Screenshot when Landscape mode




Screenshot when Portrait mode





You may download this version from AlertsAppV3.zip




No comments:

Post a Comment