HTTP post from an android application using URLConnection



A simple android application which makes a HTTP POST request to a servlet.

The comments in the source are quite self explanatory. Leave a feedback for any clarifications.


SDK version used : 2.3.3

The project structure :







1. AndroidManifest.xml





<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.httpapp"

    android:versionCode="1"

    android:versionName="1.0" >



    <uses-sdk android:minSdkVersion="10" />

    <uses-permission android:name="android.permission.INTERNET"/>



    <application

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name" >

        <activity

            android:name=".HttpAppActivity"

            android:label="@string/app_name" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />



                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>



</manifest>





We have to add the permission for internet access.


2. main.xml


This is your layout for your main activity



<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:orientation="vertical" >





    <TextView

        android:id="@+id/textView1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="@string/firstname"

        android:textAppearance="?android:attr/textAppearanceLarge" />







    <EditText

        android:id="@+id/fnameID"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:ems="10" />





    <TextView

        android:id="@+id/textView4"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="@string/lastname"

        android:textAppearance="?android:attr/textAppearanceLarge" />





    <EditText

        android:id="@+id/lnameID"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:ems="10" >



        <requestFocus />

    </EditText>



    <Button

        android:id="@+id/submitID"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="@string/submit" />







    <TextView

        android:id="@+id/resultID"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_weight="0.41" />



</LinearLayout>




3. strings.xml


<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="hello">Hello World</string>
    <string name="app_name">HTTP app</string>
    <string name="submit">submit</string>
    <string name="firstname">First name</string>
    <string name="lastname">Last name</string>

</resources>



4. HttpAppActivity.java






package com.httpapp;

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

public class HttpAppActivity extends Activity {
    
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        // Get the submit button and attach a listener to its click event
        Button submitBtn = (Button)findViewById(R.id.submitID);
        submitBtn.setOnClickListener(new Button.OnClickListener(){

            public void onClick(View v)
            {
           
            EditText fnameText = (EditText)findViewById(R.id.fnameID); // Get a handle to the input box for first name
            EditText lnameText = (EditText)findViewById(R.id.lnameID); // Get a handle to the input box for last name
           
           
           
            //Make a call to our helper class
            String result = ServletInterface.executeHttpRequest(fnameText.getText().toString(), lnameText.getText().toString());
           
           
           
            TextView resultView = (TextView) findViewById(R.id.resultID); // Get the textView where we will display the result
            resultView.setText(result); //set the returned result to the view
            }
        });
            
    }

}




5. ServletInterface.java







package com.httpapp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;

import android.util.Log;

/**
*  This class is the interface for making calls to a Servlet in a remote server
*
*/
public class ServletInterface 
{
public static final String SERVER_URL = "http://10.0.2.2:8080"; // The server(Servlet) which will process the request. Note 10.0.2.2 is the localhost IP for emulator
    public static final String CHAR_SET = "UTF-8"; // Encoding used for the parameters

  
    
    public static String executeHttpRequest(String fname, String lname) 
    {
   
    OutputStream output = null;
    String response = ""; 
   
    try 
    {
    Log.i("HTTP :", "Preparing data");
    // ------------------------------------------------------START: PREPARE CONNETION AND REQUEST ------------------------------- //
   
    // Prepare the data string  [ firstName=JOHN&lastName=SMITH ]
String data = URLEncoder.encode("firstName", CHAR_SET) + "=" + URLEncoder.encode(fname, CHAR_SET);
data += "&" + URLEncoder.encode("lastName", CHAR_SET) + "=" + URLEncoder.encode(lname, CHAR_SET);
URLConnection connection = new URL(SERVER_URL).openConnection(); // Create a connection to server using URL
connection.setDoOutput(true); // This means POST method to be used
connection.setRequestProperty("Accept-Charset", CHAR_SET); //For servers to know what encoding is used for the parameters
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + CHAR_SET);
output = null; 
output = connection.getOutputStream(); //open a Output stream from the connection for posting data
   output.write(data.getBytes(CHAR_SET)); //Post data
   
   //------------------------------------------------------ END: PREPARE CONNETION AND REQUEST --------------------------------- //
   
   
   Log.i("HTTP :", "sending data");
   InputStream responseStream = connection.getInputStream(); //This is when the request is actually fired
   
   
   
 //------------------------------------------------------ START: READ RESPONSE ------------------------------------------------ //
   
   Log.i("HTTP :", "Reading response");
            BufferedReader rd = new BufferedReader(new InputStreamReader(responseStream,CHAR_SET)); // Connect a BufferReader to the inputStream
            String line = null;
            
            while ((line = rd.readLine()) != null) // Read the response line-by-line from the bufferedReader
            {
               response += line;
            }
   
 //------------------------------------------------------ END: READ RESPONSE ------------------------------------------------- //
   
   

}
    catch (UnsupportedEncodingException e) 
    {
e.printStackTrace();
}
    catch(IOException io)
    {
    //Log and check exp
    }
    finally
    {
    if (output != null) try { output.close(); } catch (IOException ignoreIO) {}
    }
   
   
return response;
   
    }
}




= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =


At the servlet end you can read the parameters using :



String fname = (String) request.getParameter("firstName");

String lname = (String) request.getParameter("lastName");

       







Android's strings.xml







It is located at res/values/strings.xml


A common place for strings constants. The purpose of this file is to move the string values out of the xml files. 






<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="hello">Hello World</string>
    <string name="app_name">My app name</string>
    <string name="Name">name</string>
    <string name="submit">submit</string>

</resources>









Example 1: manifest.xml



<application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >



The @string/app_name is the application name which is coming from the strings.xml



Example 2: main.xml (layouts)


<TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/Name" />

The @string/Name value at this TextView component is coming from the strings.xml




Run application in phone instead of emulator - android


  •  When I run the application from eclipse, it runs in emulator instead of the phone?




  1. Connect your phone and make sure you have enabled the USB debugging in your phone. Setting > Application > Development > USB debugging.
  2. Check if your phone is shown connected by running abd devices in the command prompt (find abd under tools folder)
  3. If your phone is still not shown in the list of devices by the abd command , then your phone drivers are missing. If not sure about which driver, you can download the google USB driver from the SDK manager (usually works for most phones)


First android program

Lets start by developing a simple Android application called "Print name".

The application will have the following features:

  1. A text box to enter name
  2. Button to submit the entered name
  3. The application will read the entered name and print "Hello" followed by the name as output.

( I assume your system is set with the android sdk environment and eclipse with the ADT.
else follow these links Installing the SDK and Eclipse with ADT installation )

Note: I am using Android SDK 2.3.3 with Java 1.6 in my windows Vista.

=============================================================


1. Create an android project in eclipse :




Create project named PrintName



Android 2.3.3 used in this tutorial


PrintNameActivity is the main/default activity of the app




2. Project structure created by the eclipse plugin:

default files and folders created by the ADT plugin


  • src - Contains your source code. You can see the main activity PrintNameActivity.java created here.
  • res - Resouce folder which will contain your layout xmls , string constants xmls, icons, images etc
  • gen - It contains the R.java . DO NOT ALTER THIS FILE. R.java is generated by the android plugin and used by android to link your java source with the xmls defined by you. Will see later in the tutorial.
  • AndroidManifest.xml - Your application's deployment descriptor. Here you define the intentFilters, receivers and more.

3. Edit the UI file main.xml

Open main.xml and then select its Graphical layout (bottom of your eclipse)

graphical layout of main.xml

  • We can drag and drop components from the left menu which contains palette, Text fields, Laoyouts and more.
  • First we will remove the TextView which says "HelloWorld, PrintNameActivity". Right click it and select delete.
  • Now add a new EditText. From left columns select Text Fields > Plain text and drag it onto the top of the layout. Right click and give it an ID like inputText
  • Now add a button . Form Widgets > Button . Place it below the EditText field.  Right click and give it an ID like submitBtn
  • Place a TextView below the Button. Form Widgets >  TextView.  Right click and give it an ID like output. Also, clear the default text present.
  • When ever you give an ID to a UI component, a corresponding value is added in R.java  . You are not suppose to alter R.java . We only use R.java in the activity class to get a link on the UI components, constants etc. 

The final main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <EditText
        android:id="@+id/inputText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" >
    EditText>

    <Button
        android:id="@+id/submitBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="278dp"
        android:layout_height="wrap_content" />

LinearLayout>



4. Edit PrintNameActivity.java





 1

 2

 3

 4

 5

 6

 7

 8

 9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52
package com.myapp.printname;



import android.app.Activity;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.TextView;



public class PrintNameActivity extends Activity

{

 

 // We create a final static tag for helping us in logging

 private static final String tag = "PrintName";

 

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState)

    {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

       

        // Get the handle on the UI components 

        // Notice how we use the static values from R.java to get a link to the UI components 

        final EditText inputText = (EditText) findViewById(R.id.inputText);

        final TextView outputResult = (TextView) findViewById(R.id.output);

        final Button button = (Button) findViewById(R.id.submitBtn);

       

        // We need a know when a user clicks the button so attach a listener

        button.setOnClickListener(new Button.OnClickListener()

        {

         public void onClick(View v)

         {

          try

          {

           

           // Get the name

           String name = inputText.getText().toString();

           Log.i(tag,"Named entered is :" + name);

           

           //Set the name to the output text field

           outputResult.setText("Hello "+name);

          }

          catch (Exception e)

          {

     Log.e(tag, "Error in processing name");

    }

         }

        });

    }

}






The comments are self explanatory.


5. AndroidManifest.xml

Nothing much to edit here as we just made a simple one activity application



 1

 2

 3

 4

 5

 6

 7

 8

 9

10

11

12

13

14

15

16

17

18

19

20

21

22

23
<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.myapp.printname"

    android:versionCode="1"

    android:versionName="1.0" >



    <uses-sdk android:minSdkVersion="10" />



    <application

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name" >

        <activity

            android:name=".PrintNameActivity"

            android:label="@string/app_name" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />



                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>



</manifest>




  •  - It means the min version of android needed for this app
  • Note that our activity is defined in AndroidManifest.xml with the name ".PrintNameActivity" (Notice the period before the name. It is required in android)
  • android:label="@string/app_name" - @string means the value will be substituted. The application name is fetched from strings.xml.
  • One intent-filter defined. 
  • android.intent.action.MAIN means this is the entry point to the application. Like main() in a Java program.
  • android.intent.category.LAUNCHER means that the application will be set to the home launcher screen i.e. added to the list of apps in the phone/emulator


6. Start the emulator and wait for it to load the home screen. Then run the application.

App running in the emulator



Android components

Understand these basics before moving forward

1. Intent : In android an intent describes what you want to do. Like opening a web page or access a contact record. It facilitates navigation in an Android system.


An Intent is a declaration of need. It’s made up of a number of pieces of information that describe the desired action or service.

 2. IntentFilter :They are the declaration of capabilities, They are defined in   AndroidManifest.xml. When an intent is created, its appropriate IntentFilter is searched for in the AndroidManifest.xml and hence navigation forwarded to that IntentFilter.
An IntentFilter is a declaration of capability and interest in offering assistance to those in need. It can be generic or specific with respect to which Intents it offers to service.

3. Activity : Directly related to the UI.It is the class that handles events/requests from UI. If your application has a UI, it’ll have at least one Activity. It is like the controller in the MVC pattern.

4. Service : Long running operations are placed into services. Nothing to do with UI. Ex: running some background processing of data etc. 

5. BroadcastReceiver : They receive global events like phone ringing or incoming SMSes. Like services they do not have UIs. They are not suppose to be heavy or long running code like in services.

6. ContentProvider : If an application needs to expose some data from a backend, it needs to use the ContentProvider. 
ContentProvider is the interface for the underlying data. Data can be in the form of a file or stored in a backend database.

7. AndroidManifest.xml : It is the deployment descriptor of the applications.

Layers of Android




    1. A Linux kernel that provides a foundational hardware abstraction layer, as well as core services such as process, memory, and filesystem management.
    2. Prominent code libraries, like Browser technology, Database support ,Advanced graphics support,Audio and video media support, SSL
    3. An array of managers that provide services for Activities and views,Windows, Location-based services, Telephony, Resources
    4. The Android runtime : Core Java packages and Dalvik VM.


What is Android?


Android is misunderstood. Some call it OS, some are mislead and call it application etc
It is a platform, more precise an open source software platform for mobile devices

But android is more than all of this , it is a stack that leverages the functionality of today’s mobile devices

Android is a software environment for mobile devices.

  • Android has a built in Linux kernel which helps to leverage the hardwares of a mobile device. Making it independent of hardware.
  • Android has a Dalvik virtual machine, which runs the applications written in Java. This makes development easy and independent from the low level complexity of a mobile device.