Creating a Twitter Client for Android: Retrieving Updates Using a Service

In this series we are building a Twitter client for the Android platform using the Twitter4J library. This tutorial will focus on implementing a Service to continually fetch new tweets for the user's home timeline. We will also use a Broadcast Receiver to update the app interface when new tweets become available for display.


Also available in this series:

  1. Creating a Twitter Client for Android: Setup & Overview
  2. Creating a Twitter Client for Android: Building the Interface
  3. Creating a Twitter Client for Android: Creating a Timeline Database
  4. Creating a Twitter Client for Android: Retrieving Updates Using a Service
  5. Creating a Twitter Client for Android: Tweeting, Retweeting, and Replying

Step 1: Create a Service Class

So that the user's home timeline tweets will automatically be displayed when they become available, we are going to use a Service to retrieve them at set intervals. This Service will run at a frequency of your choice, writing to the database and sending Broadcasts when new tweets have been retrieved and stored. The app's main Activity class will receive the Broadcasts and requery the database, updating the timeline interface to display the new data.

Create a new class in your project, naming it "TimelineService" and altering the opening class declaration line as follows:

You will need the following import:

Add the following instance variables to your class, for interacting with Twitter:

Alter the key and secret variables to suit your own, as used in the previous tutorials. Add the following variables for database handling:

Finally, add the following for generic use within the class:

The Handler object is for scheduling updates at set frequencies. The "mins" variable and "FETCH_DELAY" constant let you set the frequency at which the app will fetch new updates from the user's home timeline. Alter the "mins" variable to reflect however many minutes you want the app to wait between updates. The updates will only be fetched at this frequency while the app is running. When the user exits the app and it is destroyed, it will stop the Service from continually running. The next time the user runs the app, it will fetch new updates by restarting the Service.

At the top of your class file, add the following imports for the Twitter4J library:

With the following list for Android resources:

And finally the following for the Java List class:

To implement our Service class we are going to provide the "onCreate" and "onStartCommand" methods for when the class is instantiated and the Service started, the "onDestroy" method for when it finishes, and the "onBind" method, which is required although we will not be using it. We are also going to create an inner class, in which we will retrieve the updates from Twitter at set intervals.

First, let's implement the "onCreate" method:

Inside the method, we will instantiate some of our instance variables:

Let's also create an instance of the Twitter4J object so that we can fetch tweets:

We need to implement the "onBind" method although we do not actually use it, so add it as follows:


Step 2: Create a Runnable Class

When the Service starts, the "onStartCommand" method will execute, and when it is destroyed, the "onDestroy" method will fire. We will implement both of these methods soon, but first we will create an inner class to handle retrieving the updates at fixed periods. Inside your "TimelineService" class declaration, add the following class outline:

Inside this class we will retrieve the user's home timeline, write them to the database and send a Broadcast to the main Activity when there are new tweets to display. This is all going to happen in the "run" method, so add it to your new inner class as follows:

We are only going to send the Broadcast to the main Activity when there are new tweets, so to keep track we create a boolean variable inside the "run" method:

Next we are going to attempt to fetch data from the Internet, so we need try and catch blocks:

Inside the try block, fetch the user timeline as a List object:

The retrieved timeline is a List of Status objects. Each Status object contains the data for a single tweet update. Now we need to loop through the new tweets and insert them into the database:

Notice that we are calling the "getValues" method of the NiceDataHelper class, which is static. The "getValues" method takes Twitter Status objects and retrieves the relevant data for our database, i.e. the tweet ID, text, screen-name, time and profile image URL, all of which are contained within each Status instance. The method returns these as sets of values that can be inserted into the database, which we do here. Since there are new tweets, we set the "statusChanges" flag to true.

After the catch block, we send a Broadcast to the main Activity only if there are new tweets to display:

We will handle receipt of this in the main Activity class later. Finally, after this if statement and still inside the "run" method, instruct Android to call the "run" method again after your chosen delay:

At the top of your TimelineService class, add another instance variable for this new class:


Step 3: Start the Runnable Object

Now we can handle the "TimelineService" method for when the Service starts. Back in the Service class (outside the new Runnable class), add the "onStartCommand" method:

Here we call the method of the superclass and return a standard integer value. We also instantiate the Handler and new Runnable class. The Handler adds the Runnable to the process queue so that its "run" method will execute.

Now all we need to finish the Service class is to implement the destroy method:


Step 4: Receive Broadcasts

Back in the app's main Activity class, we can now start the Service and receive the resulting Broadcasts. Add the following instance variable at the top of your "TwitNiceActivity" class:

You will need the following import statement:

Add a new inner class to your main Activity class to receive Broadcasts, making sure you add it outside any of the methods but still inside the Activity class declaration:

This class is going to do one thing: receive Broadcasts - so implement the "onReceive" method inside it:

Inside the method, we are going to minimize the size of the database by deleting some of the records whenever new tweets become available:

In this case we are limiting the table to 100 rows, but you can of course change this to a number of your choice. The query deletes all but the 100 newest records in the table.

Add the following import to the class:

Now we need to query the database and update the user interface Views using the Adapter:

Notice that we use a similar process to what happens in the "setupTimeline" method. When the user has already run the app at least once, on launching it they will see the existing data while new data is being fetched. As soon as the new data is available, the Views will be updated to display it. Naturally the speed at which this happens will depend on the user's network connectivity.


Step 5: Start the Service

Let's complete the "setupTimeline" method. After the line in which you instantiated the UpdateAdapter class last time, before the try block ends, add the following to set the Adapter to the timeline:

Next create an instance of your Broadcast Receiver class and register it to receive updates from the Service class:

Notice that the String we provide to the IntentFilter constructor here matches the String we use when sending the Broadcast within the TimelineService Runnable class.

You will need the following import:

Finally, start the Service, passing the class name:

Before we finish, let's implement the destroy method for the main Activity class since it concerns objects we have used here:

Whenever you handle databases and Services it's important not to waste resources by leaving them running when the app is not actually executing. Here we are stopping the Service, unregistering the receiver we have been listening for and closing the database. When the app is launched again these will all be restarted.


Next

We have now implemented displaying the user's home timeline tweets, fetching them at fixed intervals through a Service and detecting their retrieval using Broadcasts. In the final tutorial we will implement tweeting, retweeting and replying. This will involve implementing a new Tweet Activity and the retweet/ reply buttons within each update in the main timeline.

Tags:

Comments

Related Articles