Android Sending and Receiving data from remote server using IntentService

September 26, 2013
By

In this article, we will see how to develop an Android application that sends and receives data from a web server using IntentService. IntentService provides a simple mechanism to execute long lasting operations ( eg : downloading data )  in a background thread.

In this application user is able to select a country from a spinner widget and on selecting the country, corresponding capital name will be fetched from an http web server using IntentService and displayed to the user.

Major steps involved in this application are as follows :

  • Populate Spinner widget with a String ArrayAdapter
  • Create an IntentService class ( CapitalService ), which will be invoked when user selects a country from the Spinner widget
  • Override the method “onHandleIntent()” of the IntentService class to fetch the capital of the selected country from a remote server
  • Define a BroadcastReceiver class ( CapitalReceiver) in MainActivity, to receive the broadcast message send from the IntentService class
  • Override the method “onReceive()” of the BroadcastReceiver class to receive data from service and set in TextView of the MainActivity
  • Register the broadcast receiver in MainActivity with Android’s LocalBroadcastManager

This application is developed in Eclipse 4.2.0 with Android SDK ( 22.2.1 ) and ADT plugin ( 22.2.1 )


1. Create an Android application project with the given below project details

  • Application Name : IntentServiceDemo
  • Project Name : IntentServiceDemo
  • Package Name : in.wptrafficanalyzer.intentservicedemo
  • Minimum Required SDK : API 8 : Android 2.2 ( Froyo )
  • Target SDK : API 18 : Android 4.3
  • Compile With : API 18 : Android 4.3
  • Theme : Holo Light with Dark Action Bar

2.  Update the layout file res/layout/activity_main.xml for the MainActivity


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Spinner
        android:id="@+id/spr_country"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true" />

    <TextView
        android:id="@+id/tv_capital"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/spr_country"
        android:layout_centerHorizontal="true" />

</RelativeLayout>


3. Creating a layout for the Spinner Items in the file res/layout/spinner_layout.xml

<?xml version="1.0" encoding="utf-8"?></pre>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/tv_item"
    android:padding="15dp"
    android:textColor="@android:color/black" >

</TextView>


4. Creating a class called Constants to define application constants in the file src/in/wptrafficanalyzer/intentservicedemo/Constants.java

package in.wptrafficanalyzer.intentservicedemo;

public final class Constants {

    // Action Name to IntentFilter
    public static final String BROADCAST_ACTION = "in.wptrafficanalyzer.intentservicedemo.BROADCAST";

    public static final String EXTRA_COUNTRY = "country";

    public static final String EXTRA_CAPITAL = "capital";

    // The url to the server where php script for capital is available
    public static final String SERVER_URL = "http://wptrafficanalyzer.in/p/intent_service_demo";

}


5. Creating an IntentService class called CapitalService in the file src/in/wptrafficanalyzer/intentservicedemo/CapitalService.java

package in.wptrafficanalyzer.intentservicedemo;

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

import android.app.IntentService;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

public class CapitalService extends IntentService{

    public CapitalService(){
        super("Empty Constructor");
    }

    public CapitalService(String name) {
        super(name);
        // TODO Auto-generated constructor stub
    }

    // This method is executed in background when this service is started
    @Override
    protected void onHandleIntent(Intent intent) {
        String country = "";
        String capital = "";
        String url = "";

        try {

            country = URLEncoder.encode(intent.getStringExtra(Constants.EXTRA_COUNTRY),"utf-8");

        } catch (UnsupportedEncodingException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        url = Constants.SERVER_URL + "/get_capital.php?country=" + country;

        try {
            // Retreiving capital from the url
            capital = downloadUrl(url);

            // Creating an intent for broadcastreceiver
            Intent broadcastIntent = new Intent(Constants.BROADCAST_ACTION);

            // Attaching data to the intent
            broadcastIntent.putExtra(Constants.EXTRA_CAPITAL, capital);

            // Sending the broadcast
            LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(broadcastIntent);

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /** A method to download data from url */
    private String downloadUrl(String strUrl) throws IOException{
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try{
            URL url = new URL(strUrl);
            // Creating an http connection to communicate with url
            urlConnection = (HttpURLConnection) url.openConnection();

            // Connecting to url
            urlConnection.connect();

            // Reading data from url
            iStream = urlConnection.getInputStream();

            bufferedReader br = new BufferedReader(new InputStreamReader(iStream));

            StringBuffer sb = new StringBuffer();

            String line = "";
            while( ( line = br.readLine()) != null){
                sb.append(line);
            }

            data = sb.toString();

            br.close();

        }catch(Exception e){
            Log.d("Exception while fetching data", e.toString());
        }finally{
            iStream.close();
            urlConnection.disconnect();
        }
        return data;
    }
}

6. Updating the class MainActivity in the file src/in/wptrafficanalyzer/intentservicedemo/MainActivity.java

package in.wptrafficanalyzer.intentservicedemo;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;

public class MainActivity extends Activity {

    // Array of countries
    String[] mCountry = new String[] {
            "India",
            "Pakistan",
            "Bangladesh",
            "Srilanka",
            "Nepal",
            "China",
            "Japan",
            "South Korea",
            "North Korea",
            "Afghanistan"
    };

    Spinner mSprCountry;
    TextView mTvCapital;
    ArrayAdapter<String> mAdapter;
    Intent mServiceIntent;
    CapitalReceiver mReceiver;
    IntentFilter mFilter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Adapter for Country Spinner
        mAdapter = new ArrayAdapter<String>(getApplicationContext(),R.layout.spinner_layout, mCountry);

        // Getting reference to TextView
        mTvCapital = (TextView) findViewById(R.id.tv_capital);

        // Getting reference to Country Spinner
        mSprCountry = (Spinner) findViewById(R.id.spr_country);

        // Setting adapter for the Country Spinner
        mSprCountry.setAdapter(mAdapter);

        // Creating an intent service
        mServiceIntent = new Intent(getApplicationContext(), CapitalService.class);

        mSprCountry.setOnItemSelectedListener(new OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1,
                int arg2, long arg3) {
                if(arg1!=null){
                    String country = ((TextView)arg1).getText().toString();
                    mServiceIntent.putExtra(Constants.EXTRA_COUNTRY, country);

                    // Starting the CapitalService to fetch the capital of the country
                    startService(mServiceIntent);
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub
            }
        });

        // Instantiating BroadcastReceiver
        mReceiver = new CapitalReceiver();

        // Creating an IntentFilter with action
        mFilter = new IntentFilter(Constants.BROADCAST_ACTION);

         // Registering BroadcastReceiver with this activity for the intent filter
         LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mReceiver, mFilter);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    // Defining a BroadcastReceiver
    private class CapitalReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            String capital = intent.getStringExtra(Constants.EXTRA_CAPITAL);
            mTvCapital.setText("Capital : " + capital);
        }
    }
}

7. Create a php script file namely “get_capital.php” in a web server having php support

<?php
    $country = "none";
    $capital = array(
        "India"=>"New Delhi",
        "Pakistan"=>"Islamabad",
        "Bangladesh"=>"Dhaka",
        "Srilanka"=>"Colombo",
        "Nepal"=>"Kathmandu",
        "China"=>"Beijing",
        "Japan"=>"Tokyo",
        "South Korea"=>"Seoul",
        "North Korea"=>"Pyongyang",
        "Afghanistan"=>"Kabul",
    );
    if(isset($_GET['country'])){
        $country = $_GET['country'];
    }

    if(array_key_exists($country,$capital))
        echo $capital[$country];
    else
        echo "Please pass a valid 'country' param from this list : " . implode(",",array_keys($capital));

Note : After creating this file, please ensure that, the variable SERVER_URL of the class Constants is updated with your server url.



8. Screenshot of the application

Selecting a country from the Spinner

Selecting a country from the Spinner


9. Download the source code of the application


How to hire me?

I am George Mathew, working as software architect and Android app developer at wptrafficanalyzer.in

You can hire me on hourly basis or on project basis for Android applications development.

For hiring me, please mail your requirements to info@wptrafficanalyzer.in.

My other blogs
store4js.blogspot.com


Android Knowledge Quiz

Ready to test your knowledge in Android? Take this quiz :



Tags: ,

5 Responses to Android Sending and Receiving data from remote server using IntentService

  1. PUNITH on February 12, 2014 at 4:12 pm

    Your blog is awesome for android programming learner. I recommend this for everyone.

  2. Chaitanya on February 15, 2014 at 8:35 pm

    Dear Mathew

    Thank for your good site.I should develop an application in which it should be controlled from a remote place. Controlled in the sense, suppose I want to change the font or text color, I should be able to change it from a remote web server or web page. In the webpage I will have an option of selecting different fonts, sizes, color and so on. When I select particular font, size, color and so on, it should reflect in the application that I develop.

    Could you please help me out in this case.

    Please consider my request favorably. Awaiting for a positive reply.

  3. Chandan on December 2, 2014 at 4:30 pm

    Dear Mathew,

    Your code fetch the value based on Country select and display the capital name.

    I want this in this way.
    i want the Country and Capital name from Android app using PHP

    Please help…
    Thank you.

  4. edosat on June 6, 2015 at 5:32 pm

    Question 1.
    SERVER_URL = “http://wptrafficanalyzer.in/p/intent_service_demo”;
    how and where i can get this path?
    Question 2.
    Where should i save “get_capital.php” how i save and use it?

  5. edosat on June 7, 2015 at 1:06 am

    what argument i give to SERVER_URL =”?”, where should i save php script file namely “get_capital.php” in a web server having php support

Leave a Reply

Your email address will not be published. Required fields are marked *

Be friend at g+

Subscribe for Lastest Updates

FBFPowered by ®Google Feedburner