In one of my applications, it was required to update a TextView every minute. The first approach that I could think of was to have an AsyncTask running a while loop till a minute (check for initial time+60,000 milliseconds in every iteration), but then I found out about ACTION_TIME_TICK broadcast action.
As per java docs:-
public static final String ACTION_TIME_TICK
Broadcast Action: The current time has changed. Sent every minute. You cannot receive this through components declared in manifests, only by explicitly registering for it with Context.registerReceiver().
This is a protected intent that can only be sent by the system.
Note: It is assumed that reader has knowledge of how to create and run a simple android application.
To learn how to use this broadcast action, I made a small program to display the current time (hours and minutes) in the form of a digital clock. The process is as follows:-
- Create a new Android project, with name DigiClock and package name com.cc.demo.digiClock
Open activity_main.xml and paste the following:
<?xml version="1.0" encoding="utf-8"?> | |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="wrap_content" | |
android:layout_height="fill_parent" | |
android:orientation="vertical"> | |
<!-- Text View to show hour--> | |
<TextView | |
android:id="@+id/hourText" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginRight="5dp" /> | |
<!-- Text View to show minute--> | |
<TextView | |
android:id="@+id/minuteText" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_toRightOf="@id/hourText" /> | |
</RelativeLayout> |
3. Open Activity class(create one if already not created) and paste the following:-
package com.cc.demo.digiClock; | |
import java.util.Calendar; | |
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.widget.TextView; | |
public class DigiClockActivity extends Activity { | |
private static BroadcastReceiver tickReceiver; | |
private TextView hourText; | |
private TextView minuteText; | |
/** Called when the activity is first created. */ | |
@Override | |
public void onCreate(Bundle savedInstanceState) | |
{ | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.main); | |
hourText=(TextView)findViewById(R.id.hourText); | |
minuteText=(TextView)findViewById(R.id.minuteText); | |
//Set the current time at startup | |
hourText.setText(String.valueOf(Calendar.getInstance().get(Calendar.HOUR_OF_DAY))); | |
minuteText.setText(String.valueOf(Calendar.getInstance().get(Calendar.MINUTE))); | |
//Create a broadcast receiver to handle change in time | |
tickReceiver=new BroadcastReceiver(){ | |
@Override | |
public void onReceive(Context context, Intent intent) { | |
if(intent.getAction().compareTo(Intent.ACTION_TIME_TICK)==0) | |
{ | |
hourText.setText(String.valueOf(Calendar.getInstance().get(Calendar.HOUR_OF_DAY))); | |
minuteText.setText(String.valueOf(Calendar.getInstance().get(Calendar.MINUTE))); | |
} | |
} | |
}; | |
//Register the broadcast receiver to receive TIME_TICK | |
registerReceiver(tickReceiver, new IntentFilter(Intent.ACTION_TIME_TICK)); | |
} | |
@Override | |
public void onStop() | |
{ | |
super.onStop(); | |
//unregister broadcast receiver. | |
if(tickReceiver!=null) | |
unregisterReceiver(tickReceiver); | |
} | |
} |
In the above code, we first create a broadcast receiver object, which will change the text of our TextView when the received action is ACTION_TIME_TICK. After that, we register this broadcast receiver via call to registerReceiver, which calls “tickReceiver” with any broadcast intents that matches “ACTION_TIME_TICK” i.e. the onReceive method of tickReceiver will be called every minute.
Note: Do remember to call the method “unregisterReceiver” or else your application will throw an exception like this:-
“Activity com.cc.demo.digiClock.DigiClockActivity has leaked IntentReceiver com.cc.demo.digiClock.DigiClockActivity$1@412bacb8 that was originally registered here. Are you missing a call to unregisterReceiver()?”
Happy Coding!!