How to Update the UI in an Android Activity Using Data from a Background Service

Recently, I needed to update an activity in Android with data I gathered from a background Service. I couldn’t find any decent examples on the web or StackOverflow, so I decided to put one together. I really like when someone has a complete working sample, so I will provide that as well you can download the source code from Github at the end of this article. The Android project is very simple, with just two classes, the activity and the background service. We’ll take a look first at the background service to see how the data is generated.

The first thing that needs to be done is to create a string called BROADCAST_ACTION, this is simply a string that identifies what kind of action is taking place. Most of the time, it’s common to use the package name with the kind of action added to the end, so we’ll do that here. The next step is to create a handler that will be used to broadcast our data every 5 seconds. It’s better to use a Handler instead of Timer because a Timer creates a new thread.

public class BroadcastService  extends Service {
    private static final String TAG = "BroadcastService";
    public static final String BROADCAST_ACTION = "com.websmithing.broadcasttest.displayevent";
    private final Handler handler = new Handler();
    Intent intent;
    int counter = 0;

In onCreate, I’ve created a Intent and passed the BROADCAST_ACTION to the constructor of the intent. Notice that the Intent was defined as a global variable above. The intent will be called repeatedly in the Handler below and there is no reason to create a new intent every 5 seconds, so I’ll create it once here.

    @Override
    public void onCreate() {
        super.onCreate();
    	intent = new Intent(BROADCAST_ACTION);	
    }

In onStart, first we call removeCallbacks to remove any existing callbacks to the handler and make sure we don’t get more callbacks than we want. Then we call our handler with a one second delay. This will start our runnable object below.

    @Override
    public void onStart(Intent intent, int startId) {
        handler.removeCallbacks(sendUpdatesToUI);
        handler.postDelayed(sendUpdatesToUI, 1000); // 1 second   
    }

Our runnable object creates a new thread, performs whatever code is in the run method and then shuts down. In the run method, we do two things call the DisplayLoggingInfo method and then calls handler.postDelayed again but this time with a 5 second delay. This is how the repeating timer is created. One of the things that is nice about doing it this way, is that you can put a variable in place of 5000 and that way you can externally control the interval between call to the runnable object.

    private Runnable sendUpdatesToUI = new Runnable() {
    	public void run() {
    	    DisplayLoggingInfo();    		
    	    handler.postDelayed(this, 5000); // 5 seconds
    	}
    };  

In the following method, we add some data to our intent that was created above. I’m just adding the date and a simple counter that increments itself. Then we call sendBroadcast with that intent which sends a message and whoever is registered to receive that message will then get it.

    private void DisplayLoggingInfo() {
    	Log.d(TAG, "entered DisplayLoggingInfo");

    	intent.putExtra("time", new Date().toLocaleString());
    	intent.putExtra("counter", String.valueOf(++counter));
    	sendBroadcast(intent);
    }

At this point, the Service is completed and now it’s time to take a look at our Activity and see how we consume and display our data. The first thing we’ll do is create an intent with the name of the Service class. This will be passed to startService and stopService.

public class BroadcastTest extends Activity {
	private static final String TAG = "BroadcastTest";
	private Intent intent;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        intent = new Intent(this, BroadcastService.class);
    }

Now, we’ll create a BroadcastReceiver to receive the message that is going to be broadcast from the Service above. The BroadcastReceiver has one method, onReceive, it gets called and then the BroadcastReceiver object is destroyed. In the onReceive method, we call updateUI passing in our intent which is holding the data to display.

    private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
        	updateUI(intent);       
        }
    };    

In onResume and onPause, we start and stop our Service. This happens when the screen (Activity) displays and goes away. We also register our BroadcastReceiver by passing in an IntentFilter. Do you see that the IntentFilter is using the same static string, BROADCAST_ACTION, that we created in the Service above. This is how we identify the message that is broadcast. in onPause, we also make sure that we call unregisterReceiver to stop listening for broadcasts.

	@Override
	public void onResume() {
		super.onResume();		
		startService(intent);
		registerReceiver(broadcastReceiver, new IntentFilter(BroadcastService.BROADCAST_ACTION));
	}
	
	@Override
	public void onPause() {
		super.onPause();
		unregisterReceiver(broadcastReceiver);
		stopService(intent); 		
	}

This last bit of code is pretty straight forward. We get our data out of the intent and set our two TextViews with the data. They will be updated every 5 seconds.

    private void updateUI(Intent intent) {
    	String counter = intent.getStringExtra("counter"); 
    	String time = intent.getStringExtra("time");
    	Log.d(TAG, counter);
    	Log.d(TAG, time);
    	
    	TextView txtDateTime = (TextView) findViewById(R.id.txtDateTime);  	
    	TextView txtCounter = (TextView) findViewById(R.id.txtCounter);
    	txtDateTime.setText(time);
    	txtCounter.setText(counter);
    }

I’ve made the entire project available for download here on GitHub.

99 thoughts on “How to Update the UI in an Android Activity Using Data from a Background Service

  1. Bob

    Like the nature of android os, I guess android documentation for developers heavily depends on many. Your complete working example saves me a lot of time, Thank you.

    Reply
  2. DrT

    You made a real difference… because you can communicate with words, and write code. Thanks for taking the time to post and clarify this stuff for me!

    Reply
  3. Pingback: Using Android Preferences in a background service « JTeam Blog / JTeam: Enterprise Java, Open Source, software solutions, Amsterdam

  4. Ryan

    Great demonstration, just one thing to note. Complete newbies might be completely confused as to why nothing is invoked once the code above is complete. Well I didn’t understand the service architecture. I needed to add

    to the AndroidManifest. I used the log to determine the intent was not being found and pulled this entry out of the xml in your source but it would be nice to mention that this is the last piece.

    All in all this is an amazing walkthrough! Thanks!

    Reply
  5. Josan

    Hi Nick, great code and great explain.
    Your code run very well, but when the activity is sleeping the broadcastReceiver, in the onReceive, don’t wake up the activity and the main activity don’t receive any info.
    How to repair this?
    I was a lot of hours investigating and anything…
    I need help whith this.

    thanks and sorry by my english.

    Reply
  6. tuk

    Thank you very much. I’m the kind of guy that understands things watching it working.

    That complete working example was just perfect!

    Reply
  7. Shushu

    Thanks for your documentation, it was great to find it, and it was simple to implement in my alread developed service.

    People who write like you write don’t do it for money, I am sure, but I think I owe you some, so I am glad to see the “donate” button 🙂

    Reply
  8. Laura

    It’s misleading to call this a background service. The sendUpdatesToUI runnable doesn’t create a new thread – it just adds the runnable to the main thread’s message queue. If you were doing something more involved in DisplayLoggingInfo, you would probably see an ANR.

    Creating a worker thread in the activity that updates the TextViews through a UI thread Handler or using an IntentService if multiple activities need to receive the broadcast would be better approaches.

    Reply
  9. Chris

    Very straightforward and complete example which is often hard to find in the sea of useless “To Do” articles online. Please consider writing more articles as you seem to have a natural knack for it. Thank you for taking the time.

    Reply
  10. Abhishek Verma

    Thank You Nick,

    It helped me to clear out my doubts
    and refine my concepts towards UI Thread

    : ))))

    Regards:
    abhi

    Reply
  11. Mack

    This was exactly what I needed! I think I understand Laura’s comment above, but for straight UI updates this works well for my purposes. You can also mod this to just have the service update the UI activity when it needs to.

    Thanks so much!

    Reply
  12. Roy Bakker

    Thanks for the example, helped me out a lot writing an Android application which periodically calls an API to listen for updates on which location to navigate to. (Building a location based game).

    Reply
  13. Eric

    Can someone explain this bit of Java to me?

    [CODE]
    private Runnable sendUpdatesToUI = new Runnable() {
    public void run() {
    DisplayLoggingInfo();
    handler.postDelayed(this, 10000); // 10 seconds
    }
    };
    [/CODE]
    What are you doing there exactly? I understand what you’re doing with regards to services and all that, but from a language standpoint, I’m confused; what is this? It looks like you’re making a new runnable (in the class definition, instead of inside a function, which I thought you weren’t allowed to do), but then you’ve suddenly got braces right afterwards, and another function definition within it. I’m confused on so many levels! Java has always looked nearly identical to C++ until now.

    Reply
  14. Liam

    Nick, Thanks for this – just what I needed!

    Eric, All that does is makes a runnable – its basically a class where you implement a method run() which gets run usually after a period.
    You can put code inside the run method to do whatever.

    Then pass the runnable to a handler (usually using postdelayed(), with a delayed time to run it after).

    Reply
  15. Eric

    How do I register the service in the manifest file?
    I did it like this:

    ….

    I must be doing it wrong, because its not running the service.

    Reply
  16. Eric

    Oops, I don’t know why the site replaced my XML stuff with …, here’s what I did:
    (replaced ‘<' with ')', since I think the site might be processing tags a little differently)

    (application
    …..
    (activity
    …..
    (/activity)
    (service android:name=".ClockService" /)
    (/application)

    Reply
  17. amit

    invoking any application from this service is that doable???
    so probably prompting user by saying that this service wants to run this application and when the user allows it will invoke the application???

    Reply
  18. Paul

    AWESOME tutorial!!!

    struggled with this for a while and couldn’t get descent tutorials.

    Used this to broadcast data between the Android IOIO as a service and the rest of my application. excellent tutorial!

    Reply
  19. Chitra

    Grt tutorial.. Thank you..
    Actually I need to udpate list view on data from background service from a web service call. On onReceive
    I have updatedUI. Problem is every time list view is updated with new data,it focuses on first item. What I want is to set the position of item to last element in a list before the broadcast.Can you give me any suggestions on this.

    Reply

Leave a Reply

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


This site uses Akismet to reduce spam. Learn how your comment data is processed.