Blog Archive

Android IntentService example using BroadcastReceiver and update Activity UI

IntentService is a a base class for Service that can be used to handle asynchronous work off the main thread by way of Intent requests on demand. Each intent is added to the IntentService’s queue and handled sequentially. Clients send requests through startService(Intent) calls; the service is started as needed, handles each Intent in turn using a worker thread, and stops itself when it runs out of work.

This "work queue processor" pattern is commonly used to offload tasks from an application's main thread. The IntentService class exists to simplify this pattern and take care of the mechanics. To use it, extend IntentService and implement onHandleIntent(Intent). IntentService will receive the Intents, launch a worker thread, and stop the service as appropriate.

All requests are handled on a single worker thread -- they may take as long as necessary (and will not block the application's main loop), but only one request will be processed at a time.

If you need parallel asynchronous processing then you need to look at the AsyncTask Tutorial. AsyncTask is limited to a single execution.

Android IntentService example using BroadcastReceiver

Android IntentService example using BroadcastReceiver



Steps involved in implementing an Android IntentService example using BroadcastReceiver


  1. Create a class file that extends the IntentService class and add stubs for the methods you need to implement. You should add a constructor with the name of your new service. You will need to implement just one other method called onHandleIntent().
  2. In your Activity start the Service with a call to startService() for an Intent instance. You can pass any data to the intent using the extras. The service takes over from here, catching each intent request, processing it, and shutting itself down when it’s all done. The main user interface remains responsive throughout the processing, allowing the user to continue to interact with the application.
  3. You need to send a broadcast from the onHandleIntent() method of the IntentService class after the processing is complete to let the BroadcastReceiver know results of the process.
  4. Define the BroadcastReceiver as subclass within the main activity and register the receiver.

In the example below, IntentService class has a delay of 10 seconds added to the processing which you must remove in you real application. This is there to simulate delay in processing heavy duty stuff that you may want to offload from the main activity and display the queue process as I fire three subsequent request. The program makes web requests and loads them in the main activity's WebView.

Source for AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.as400samplecode" android:versionCode="1"
    android:versionName="1.0">
    <uses-sdk android:minSdkVersion="13" />
    <uses-permission android:name="android.permission.INTERNET" />
   
    <application android:icon="@drawable/icon" android:label="@string/app_name"
        android:theme="@android:style/Theme.Holo.Light">
        <service android:name="MyWebRequestService"/>
        <activity android:name=".IntentServiceActivity"
            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>

Source for main.xml

<?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:paddingLeft="10dp">
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:text="IntentService and BroadcastReceiver Example"
        android:textSize="25sp" android:paddingTop="20dp" />
    <Button android:text="Send Request to The Service" android:id="@+id/sendRequest"
        android:layout_width="wrap_content" android:layout_height="wrap_content" />
    <LinearLayout android:layout_width="match_parent"
        android:id="@+id/linearLayout1" android:layout_height="wrap_content">
        <TextView android:text="Watch for Response from IntentService"
            android:layout_height="wrap_content" android:id="@+id/textView1"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:layout_width="wrap_content" android:paddingTop="25dp" />
        <TextView android:text="" android:layout_height="wrap_content"
            android:id="@+id/response" android:textAppearance="?android:attr/textAppearanceMedium"
            android:layout_width="wrap_content" android:layout_marginLeft="10dp" />
    </LinearLayout>
    <WebView android:layout_width="match_parent" android:id="@+id/myWebView"
        android:layout_height="match_parent" />
</LinearLayout>

Source for MyWebRequestService.java

package com.as400samplecode;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import com.as400samplecode.IntentServiceActivity.MyWebRequestReceiver;

import android.app.IntentService;
import android.content.Intent;
import android.os.SystemClock;
import android.text.format.DateFormat;
import android.util.Log;

public class MyWebRequestService  extends IntentService{

    public static final String REQUEST_STRING = "myRequest";
    public static final String RESPONSE_STRING = "myResponse";
    public static final String RESPONSE_MESSAGE = "myResponseMessage";

    private String URL = null;
    private static final int REGISTRATION_TIMEOUT = 3 * 1000;
    private static final int WAIT_TIMEOUT = 30 * 1000;

    public MyWebRequestService() {
        super("MyWebRequestService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        String requestString = intent.getStringExtra(REQUEST_STRING);
        String responseString = requestString + " " + DateFormat.format("MM/dd/yy h:mmaa", System.currentTimeMillis());
        String responseMessage = "";
        SystemClock.sleep(10000); // Wait 10 seconds
        Log.v("MyWebRequestService:",responseString );

        // Do some really cool here
        // I am making web request here as an example...
        try {

            URL = requestString;
            HttpClient httpclient = new DefaultHttpClient();
            HttpParams params = httpclient.getParams();

            HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT);
            HttpConnectionParams.setSoTimeout(params, WAIT_TIMEOUT);
            ConnManagerParams.setTimeout(params, WAIT_TIMEOUT);

            HttpGet httpGet = new HttpGet(URL);
            HttpResponse response = httpclient.execute(httpGet);

            StatusLine statusLine = response.getStatusLine();
            if(statusLine.getStatusCode() == HttpStatus.SC_OK){
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                response.getEntity().writeTo(out);
                out.close();
                responseMessage = out.toString();
            }

            else{
                //Closes the connection.
                Log.w("HTTP1:",statusLine.getReasonPhrase());
                response.getEntity().getContent().close();
                throw new IOException(statusLine.getReasonPhrase());
            }

        } catch (ClientProtocolException e) {
            Log.w("HTTP2:",e );
            responseMessage = e.getMessage();
        } catch (IOException e) {
            Log.w("HTTP3:",e );
            responseMessage = e.getMessage();
        }catch (Exception e) {
            Log.w("HTTP4:",e );
            responseMessage = e.getMessage();
        }


        Intent broadcastIntent = new Intent();
        broadcastIntent.setAction(MyWebRequestReceiver.PROCESS_RESPONSE);
        broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
        broadcastIntent.putExtra(RESPONSE_STRING, responseString);
        broadcastIntent.putExtra(RESPONSE_MESSAGE, responseMessage);
        sendBroadcast(broadcastIntent);

    }

}

Source for IntentServiceActivity.java

package com.as400samplecode;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

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.view.View;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.TextView;

public class IntentServiceActivity extends Activity {

    private MyWebRequestReceiver receiver;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        IntentFilter filter = new IntentFilter(MyWebRequestReceiver.PROCESS_RESPONSE);
        filter.addCategory(Intent.CATEGORY_DEFAULT);
        receiver = new MyWebRequestReceiver();
        registerReceiver(receiver, filter);

        Button addButton = (Button) findViewById(R.id.sendRequest);
        addButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {

                Intent msgIntent = new Intent(IntentServiceActivity.this, MyWebRequestService.class);
               
                msgIntent.putExtra(MyWebRequestService.REQUEST_STRING, "http://www.amazon.com");
                startService(msgIntent);
               
                msgIntent.putExtra(MyWebRequestService.REQUEST_STRING, "http://www.ebay.com");
                startService(msgIntent);
               
                msgIntent.putExtra(MyWebRequestService.REQUEST_STRING, "http://www.yahoo.com");
                startService(msgIntent);
            }
        });

    }

    @Override
    public void onDestroy() {
        this.unregisterReceiver(receiver);
        super.onDestroy();
    }

    public class MyWebRequestReceiver extends BroadcastReceiver{

        public static final String PROCESS_RESPONSE = "com.as400samplecode.intent.action.PROCESS_RESPONSE";

        @Override
        public void onReceive(Context context, Intent intent) {
            String responseString = intent.getStringExtra(MyWebRequestService.RESPONSE_STRING);
            String reponseMessage = intent.getStringExtra(MyWebRequestService.RESPONSE_MESSAGE);

            TextView myTextView = (TextView) findViewById(R.id.response);
            myTextView.setText(responseString);

            WebView myWebView = (WebView) findViewById(R.id.myWebView);
            myWebView.getSettings().setJavaScriptEnabled(true);
            try {
                myWebView.loadData(URLEncoder.encode(reponseMessage,"utf-8").replaceAll("\\+"," "), "text/html", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }


        }


    }

}

7 comments :

  1. Exactly the help I needed.

    Many Thanks!!

    ReplyDelete
  2. This is what I am looking for! It's great tutorial!

    Thanks!

    ReplyDelete
  3. Nice post.Give it up. Thanks for share this article. For more visit:android development

    ReplyDelete
  4. Awesome! Thanks man.

    works like a charm

    ReplyDelete
  5. Thanks!!! Good job!

    ReplyDelete
  6. Very Nice post and simple to use logic,
    Thanks

    ReplyDelete