A simple notification system with the IntentService Part I

One of the most occurring behaviors in an Android application is the use of a notification system based on the retrieval of “some” data from “some” external source. Most of the time a notification will be utilized to inform the user that something has changed in this external source. A prime example is how modern day Twitter clients inform users that they have been mentioned in a tweet.

In this 3-part series we’re going to walk through the steps on implementing such functionality. Our example is going to retrieve data through a background service and will then notify the user when this process is finished. For this to happen we will use two building blocks available in the Android framework:

  • The Intent Service;
  • The Broadcast receiver

The Intent Service

One of the core components in Android development are “Services”. Services can be used to execute a large or long-running operation that requires no user interaction. Most of these long-running operations (like playing music for example) need to spawn their own thread to keep the main thread from blocking. A service however does not automatically spawn a new thread to execute in, which means we have some work to do….

But wait… for the common use of running a single operation on a worker thread, the Android framework provides a specific implementation of a Service: the Intent Service.

The official Android development website describes the Intent Service as

a subclass of Service that uses a worker thread to handle all start requests, one at a time. This is the best option if you don’t require that your service handle multiple requests simultaneously. All you need to do is implement onHandleIntent(), which receives the intent for each start request so you can do the background work

Sounds good huh? This is exactly what we need. 🙂

Our Intent service is going to pull data from an external source in its own worker thread without interfering our user experience.

To create an Intent service we need to create a new class that extends IntentService:

public class SimpleIntentService extends IntentService
{
	private static final String DEBUG_TAG = "SimpleIntentService";

	public SimpleIntentService() {
		super(DEBUG_TAG);
	}

	@Override
	protected void onHandleIntent(Intent intent) {
	}
}

Now since all the functionality of creating the worker thread for our operation to run on is already implemented in the IntentService class, the only thing we need to do is implement a constructor and the onHandleIntent method.

public class SimpleIntentService extends IntentService
{
	private SomeDataProvider myDataProvider;
	private static final String DEBUG_TAG = "SimpleIntentService";

	public SimpleIntentService() {
		super(DEBUG_TAG);
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onHandleIntent(Intent intent) {

		// retrieve the url from the intent
		String url = intent.getStringExtra("url");

		// use our custom dataprovider to retrieve our data
		myDataProvider = new SomeDataProvider();

		ArrayList<SomeData> dataList = myDataProvider.getData(url);

		Log.d(DEBUG_TAG, "Data received");
	}
}

The Intent service executes the code in onHandleIntent after which it closes the worker thread again and stops itself. In the code above we use the Intent to retrieve the URL that defines the location of our data (an xml feed for example). Some custom data provider then uses this URL to retrieve the data and stores it in a typed ArrayList object. Finally, the Log is notified that we have received some data. Very straightforward right?

Defining the service in AndroidManifest.xml

For any service to be used it needs to be declared in the AndroidManifest.xml file

<application android:icon="@drawable/icon" android:label="@string/app_name">
    <service android:enabled="true" android:name="com.androidhotel.simplenotification.SimpleIntentService" android:label="Android Hotel simple Intent service 2000" android:exported="true" />
</application>

At this point we only need to start the service from an activity to get the work done. So:

public class SimpleNotificationActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

	Intent serviceIntent = new Intent(SimpleNotificationActivity.this,
                                 SimpleIntentService.class);
	serviceIntent.putExtra("url", "https://androidhotel.wordpress.com");
	startService(serviceIntent);
    }
}

Now when we run the application at this point the SimpleNotification Activity will start the service immediately when it’s created, resulting in a “Data received” message in the Log.

With the Intent service in place we are now ready to actually notify the user that new data has been retrieved. In the next part of this series we will dive into broadcasts to get the actual notification done.

Please feel free to comment on this article below and see you next time!

Tagged ,

Leave a comment