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 do is to create a string called BROADCAST_ACTION, this is simply a string that identifies what kind of action is taking place. Most of 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.
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.
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.
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.
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.
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.
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.
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.
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.
I’ve made the entire project available for download here on GitHub. You can either clone the project or download it with the Downloads button.
The first thing that needs to do is to create a string called BROADCAST_ACTION, this is simply a string that identifies what kind of action is taking place. Most of 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;
@Override public void onCreate() { super.onCreate(); intent = new Intent(BROADCAST_ACTION); }
@Override public void onStart(Intent intent, int startId) { handler.removeCallbacks(sendUpdatesToUI); handler.postDelayed(sendUpdatesToUI, 1000); // 1 second }
private Runnable sendUpdatesToUI = new Runnable() { public void run() { DisplayLoggingInfo(); handler.postDelayed(this, 5000); // 5 seconds } };
private void DisplayLoggingInfo() { Log.d(TAG, "entered DisplayLoggingInfo"); intent.putExtra("time", new Date().toLocaleString()); intent.putExtra("counter", String.valueOf(++counter)); sendBroadcast(intent); }
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); }
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { updateUI(intent); } };
@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); }
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); }
No comments:
Post a Comment
Thank You , For Immediate Assistance Plz Put Email Copy to Deviceporting@gmail.com