Sunday, March 6, 2011

Calling a Java SOAP Web-service from Android and iOS apps - Part 1

Objective of this series of tutorials is to:
  • Create a SOAP web-service to convert a temperature in Fahrenheit to Celsius in Java using Eclipse, Tomcat and Axis
  • Create and Android app that uses ksoap2 library to call the web-service and shows the result on screen.
  • Create and iPhone (iOS) app that calls the same web-service and shows the result on screen.
In this part I will show hot to build the web-service from ground up.

Pre-requisites:
3. Axis2 1.4.1 (I had trouble with the latest version)

Once both Tomcat and Axis2 have been configured in Eclipse Workspace, go ahead and create a Dynamic Web Project as follows:
























Add a new Class called Temperature to Java Resources of your project:

package org.ushasoft;
import java.text.DecimalFormat;
public class Temperature {
private static final DecimalFormat TWO_D_FORM = new DecimalFormat("#.#");
public String Convert(String fahrenheit) {
try {
double f = Double.parseDouble(fahrenheit);
//return Double.toString( TWO_D_FORM.format(((f - 32) * 5)/9));
return TWO_D_FORM.format(((f - 32) * 5)/9);
} catch (Exception e) {
return "Invalid";
}
}
}

Save the file, then select this newly created class and right click on it, Select "Web Services" from the context menu and then "Create Web Service" 



































Make sure all of the parameters are set accordingly and just go through the subsequent screens, selecting default values everywhere.






































Once the Web-service has been generated and deployed to Tomcat, Launch the Web Services Explorer (it's under "Run" menu when you're in Java EE perspective)

Select the Web Page option and paste the WSDL URL 
 http://localhost:8080/Temperature/services/Temperature?wsdl and hit Go

You should be able to test your Web-service with an input:
































So, we have our Service working. Let's get the Android app going.

First of, you will need the ksoap2 library for Android, download the latest jar from here.
I'm assuming you have Android SDK already installed for Eclipse.

Now switch over to Java perspective and create a new Android Project :










































Add INTERNET permission to your Android App Manifest, you will need that to make the Web-service call.

Update the main.xml in "res/layout" folder of your project as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:padding="30dip">
    <TableLayout android:stretchColumns="*" android:layout_width="fill_parent" android:layout_height="wrap_content">
     <TableRow android:layout_width="fill_parent" android:layout_height="wrap_content">
     <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" 
     android:textStyle="bold" android:text="@string/label_fahrenheit" android:padding="5dip"/>
     <EditText android:id="@+id/inputFahrenheit" android:layout_width="wrap_content" 
     android:layout_height="wrap_content" android:imeOptions="actionDone" android:inputType="number"/>
     </TableRow>
     <TableRow android:layout_width="fill_parent" android:layout_height="wrap_content">
     <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" 
     android:textStyle="bold" android:text="@string/label_celsius" android:padding="5dip"/>
     <EditText android:id="@+id/txtCelsius" android:layout_width="wrap_content" android:layout_height="wrap_content" 
     android:inputType="none" android:editable="false" />
     </TableRow>
     <TableRow android:layout_width="fill_parent" android:layout_height="wrap_content">
     <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text=""/>
     <Button android:id="@+id/btnConvert" android:text="Convert" 
     android:layout_width="wrap_content" android:layout_height="wrap_content"/>
     </TableRow>
    </TableLayout>
</LinearLayout>

And your Activity class should like the following:

package org.ushasoft.temperature;
import java.io.IOException;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class ConverterActivity extends Activity {
    /** Called when the activity is first created. */
TextView inputFahrenheit;
TextView txtCelsius;
Button btnConvert;
public final static String URL = "http://10.0.2.2:8080/Temperature/services/Temperature?wsdl";
public static final String NAMESPACE = "http://ushasoft.org";
public static final String SOAP_ACTION_PREFIX = "/";
private static final String METHOD = "Convert";
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        inputFahrenheit = (TextView) findViewById(R.id.inputFahrenheit);
        txtCelsius = (TextView) findViewById(R.id.txtCelsius);
        btnConvert = (Button) findViewById(R.id.btnConvert);
        
        btnConvert.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
doConvert();
}
});
    }
    private void doConvert() {
     if (inputFahrenheit.getText() == null || inputFahrenheit.getText().toString().length() == 0) {
     return;
     }
     SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
SoapObject request = new SoapObject(NAMESPACE, METHOD);
request.addProperty("fahrenheit", inputFahrenheit.getText().toString());
envelope.bodyOut = request;
HttpTransportSE transport = new HttpTransportSE(URL);
try {
transport.call(NAMESPACE + SOAP_ACTION_PREFIX + METHOD, envelope);
} catch (IOException e) {
e.printStackTrace();
System.out.println("SOAP Error : " + e.getMessage());
System.out.println("SOAP Response : " + transport.responseDump);
} catch (XmlPullParserException e) {
e.printStackTrace();
System.out.println("SOAP Error : " + e.getMessage());
System.out.println("SOAP Response : " + transport.responseDump);
}
if (envelope.bodyIn != null) {
SoapPrimitive resultSOAP = (SoapPrimitive)((SoapObject)envelope.bodyIn).getProperty(0);
txtCelsius.setText(resultSOAP.toString());
}
    }
}

That's pretty much it. Run the application and it should work as shown:































You can download the source code below:



Saturday, December 25, 2010

Trip Recorder for Android

Record, Map, Export & Email a Car Trips.

Requirements:
  • GPS must be enabled for Trip Routing, Recording Speed, distance etc.
  • An Existing Email account is required for Emailing Trip Route information.

Features:
  • Shows GPS preferences menu to enable GPS.
  • Show live Location updates with Time, Speed, accuracy etc.
  • Summary information for Saved Trips.
  • Map any of the existing Trips with start and end points with route overlays.
  • Option to delete old Trips.
  • Backup database to SD Card.
  • Shows GPS Preferences on Applicatin exit so that you can turn GPS off to save battery.
  • Export trip to CSV format and email for future reference.
Future Plans:
  • Have a cloud-based website where users can upload their trips right from their mobile devices and use web-based maps with enhanced overlays to analyze and print trip details in PDFs, Excel etc.
Version 1.04 Changes:
  • Added Options to maintain multiple Cars
  • Manage Trip Categories
  • Edit previously saved trips to add description, Category and Car
Version 1.05 Changes:
  • Added options to display in Metric units (Kilometers)
  • Option to Export trips in either CSV or KML formats
  • Preference screen
  • Option to use 24-hour time format
  • Option to print Tip description, Car details, category etc. in header rows for CSV email option.
Version 1.08 Changes:
* Added Odometer reading.
* Also, once you save Odometer reading, next time the application Defaults that to your last Saved Odometer reading + Length of the Trip.


Also, if you want to analyze the Trip Recorder database further, you should use the "Backup" option of the app. Download the file called "triprecorder.db" from you SDCARD and open the Database using the Trip Recorder Desktop application (Adobe AIR runtime) required.

The AIR Installer can be found below:
Screenshots:

Friday, October 22, 2010

Android App

Really liking my new Droid X.
Also, it really helps that I can connect my phone to my laptop via USB and start testing any apps I am writing using the Eclipse and Android SDK.
Like the fact that, I have real ownership of the device that I paid hundreds of dollars for, I don't have to register it with anybody to start using the device for developing apps.

Just released a Desi News reader app . Click on http://market.android.com/search?q=pname:org.ushasoft.news from your Android browser to access the Free app.

Feel free to send me links to the News sites you want added to the list of sites available thru the App.