I am a begineer in android app development, i have stoptimertask function in my mainactivity, and a button stop in another activity. What i want to do is when i press this stop button from my 2nd activity(which is maps.class), i want the stoptimertask to stop i.e. stop the tasks. However the app crashes.
Here is my code of mainactivity.java
public class MainActivity extends FragmentActivity{
protected static final int CONTACT_PICKER_RESULT = 0;
int count=0;
Timer timer;
TimerTask timerTask;
final Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
startTimer();
sendSMSMessage();
Intent toAnotherActivity = new Intent(MainActivity.this, maps.class);
startActivityForResult(toAnotherActivity, 0);
}
});
}
public void startTimer() {
timer = new Timer();
initializeTimerTask();
if(radioBtnten.isChecked()==true)
timer.schedule(timerTask, 5000, 10000);
// if(radioBtn2.isSelected()==true)
else if(radioBtnone.isChecked()==true)
timer.schedule(timerTask, 5000, 1000);
}
public void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "your message has been sent, the message(s) sent are:-"+count++,Toast.LENGTH_LONG).show();
sendSMSMessage();
}
});
}
};
}
public void stoptimertask(View v)
{
//stop the timer, if it's not already null
Toast.makeText(getApplicationContext(), "Stop button pressed",Toast.LENGTH_LONG).show();
if (timer != null)
{
timer.cancel();
timer = null;
count = 0;
}
MainActivity.this.finish();
}
}
Here is the maps.java(2nd activity)
public class maps extends FragmentActivity implements LocationListener {
MainActivity call=new MainActivity();
GoogleMap googleMap;
Button stop;
Timer timer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//show error dialog if GoolglePlayServices not available
if (!isGooglePlayServicesAvailable()) {
finish();
}
setContentView(R.layout.maps);
stop = (Button)findViewById(R.id.stop);
stop.setOnClickListener(new View.OnClickListener()
{
public void onClick(View aView)
{
Intent toAnotherActivity = new Intent(aView.getContext(), MainActivity.class);
startActivityForResult(toAnotherActivity, 0);
Toast.makeText(getApplicationContext(), "Stop button pressed",Toast.LENGTH_LONG).show();
maps.this.finish();
call.stoptimertask(aView);
}
});
here is the logcat
FATAL EXCEPTION: main
Process: com.example.textmessage, PID: 19869
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:105)
at com.example.textmessage.MainActivity.stoptimertask(MainActivity.java:167)
at com.example.textmessage.maps$1.onClick(maps.java:49)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Best use for this kind of scenario is Singleton pattern.
MainActivity.java
public class MainActivity extends FragmentActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeTools();
// Find reference of "sendBtn" with "findViewById" or other stuff
sendBtn.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
startTimer();
}
});
// Rest of your code
}
private void initializeTools()
{
// Give context to Timers instance
Timers.getInstance().giveContext(this);
}
private void startTimer()
{
// Starts the timer when you click on "sendBtn"
Timers.getInstance().startTimers();
}
}
Timers.java
public class Timers
{
private final ScheduledExecutorService scheduledExecutorService;
private final Runnable myTask;
private ScheduledFuture<?> futureTask;
private int count = 0;
private Context _context;
private static volatile Timers _timers;
private Timers()
{
super();
// Your "futureTask manager"
scheduledExecutorService = Executors.newScheduledThreadPool(5);
// Good use is to instanciate task since it won't change on runtime
myTask = new Runnable()
{
#Override
public void run()
{
// Your code to run after the delay has expired
Toast.makeText(_context, "your message has been sent, the message(s) sent are:-" + count++, Toast.LENGTH_LONG).show();
// Same as the whole example, you should use the Singleton pattern to handle communications thanks to the Singleton class "Communicator"
Communicator.getInstance().sendSMSMessage();
}
};
}
// Allow only one instance of the class running. Anyone can get reference of the class with the static function Timers.getInstance();
public static Timers getInstance()
{
if (Timers._timers == null)
{
synchronized (Timers.class)
{
if (Timers._timers == null)
{
Timers._timers = new Timers();
}
}
}
return Timers._timers;
}
// For Toasts and other useful stuff
public void giveContext(Context context)
{
this._context = context;
}
// Stop the timer
public void stopTimer()
{
if (futureTask != null)
{
futureTask.cancel(true);
}
}
// Starts the task to happen in 10 seconds
public void startTimers()
{
futureTask = scheduledExecutorService.schedule(myTask, 10, TimeUnit.SECONDS);
}
}
And inside any class of your application, use Timers.getInstance().stopTimer(); to stop the timer and Timers.getInstance().startTimer(); to start it again.
Did you try?
mTimer = new Runnable() {
#Override
public void run() {
**return;**
Related
This below code to start activity "welcome1" and execute Thread() Then start another activity called "gps"
but when it executes the gps activity running without running activity welcome1
how can to start welcome1 and wait some time then start activity gps
Code
public class welcome1 extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads().detectDiskWrites().detectNetwork()
.penaltyLog().build());
super.onCreate(savedInstanceState);
setContentView(R.layout.welcome1);
final TextView welcome = (TextView) findViewById(R.id.textView7);
final TextView person = (TextView) findViewById(R.id.textView9);
final Intent v = getIntent();
final String abt = v.getStringExtra("frist_name");
Runnable myRun=new Runnable() {
#Override
public void run() {
for (int s=0;s<2;s++){
final int finalI =s;
runOnUiThread(new Runnable() {
#Override
public void run() {
if (finalI==0)
{
welcome.setText(welcome2);
person.setText(abt);
}
if (finalI==1)
welcome.setText(steps);
}
});
synchronized (this) {
try {
wait(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
};
Thread T=new Thread(myRun);
T.start();
String number = v.getStringExtra("mobile_number");
String pwd = v.getStringExtra("pass");
Intent d = new Intent(getBaseContext(),gps.class);
d.putExtra("mobile_number",number);
d.putExtra("pass", pwd);
startActivity(d);
}
Have you tried with a Handler?
Just create a Runnable which starts the next activity and run like this:
new Handler().postDelayed(yourRunnable,timeinmillis)
startActivity(Intent) is called right after the Thread T starts. Thus it ignores the Thread T you created and just runs in the UI thread.
Correct code to do what you want is this:
public class welcome1 extends Activity {
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads().detectDiskWrites().detectNetwork()
.penaltyLog().build());
super.onCreate(savedInstanceState);
setContentView(R.layout.welcome1);
final TextView welcome = (TextView) findViewById(R.id.textView7);
final TextView person = (TextView) findViewById(R.id.textView9);
final Intent v = getIntent(); final String abt = v.getStringExtra("frist_name");
Runnable myRun=new Runnable() {
#Override
public void run() {
for (int s=0;s<2;s++){
final int finalI =s;
runOnUiThread(new Runnable() {
#Override
public void run() {
if (finalI==0)
{
welcome.setText(welcome2);
person.setText(abt);
}
if (finalI==1)
welcome.setText(steps);
}
});
try {
wait(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
String number = v.getStringExtra("mobile_number");
String pwd = v.getStringExtra("pass");
Intent d = new Intent(getBaseContext(),gps.class);
d.putExtra("mobile_number",number);
d.putExtra("pass", pwd);
startActivity(d);
}
});
}
}
};
Thread T=new Thread(myRun);
T.start();
}
Copy and paste this code into your oncreate() method:
//This will wait for 10secs before launching the gps activity
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
startActivity(new Intent(welcome1.this, Gps.class));
}
}, 10000);
Then run your code, it should work now.
I am creating a BLE app that needs to continuously start and stop scanning for predefined intervals. The way I have implemented it is with two runnables that call each other as follows:
private Runnable scan = new Runnable() {
#Override
public void run() {
scanHandler.postDelayed(stopScan, SCAN_PERIOD);
mLEScanner.startScan(filters, settings, mScanCallback);
Log.e("BLE_Scanner", "Start Scan");
}
};
private Runnable stopScan = new Runnable() {
#Override
public void run() {
mLEScanner.stopScan(mScanCallback);
scanHandler.postDelayed(scan, STOP_PERIOD);
Log.e("BLE_Scanner", "Stop Scan");
}
};
I am attempting to start the continuous scan and pause on a button click. The start button starts the process fine but I am having trouble with stopping the scanning.
//scan button functionality
scanButton=(Button)findViewById(R.id.scan_button);
scanButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
spinner.setVisibility(View.VISIBLE);
scan.run();
}
});
//stop scan button functionality
stopButton=(Button)findViewById(R.id.stop_button);
stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
spinner.setVisibility(View.INVISIBLE);
scanHandler.removeCallbacks(scan);
scanHandler.removeCallbacks(stopScan);
}
});
If I press the stop button during the stop interval the scan will stop. However, if I press the stop button while the scan runnable is running it appears to remove the callbacks for the stopScan runnable while leaving the scan runnable continuously running. What I need is for both of the runnables to stop on the button press. To provide more detail, my entire code is provided below. Thanks for the help.
public class MainActivity extends Activity {
private BluetoothAdapter mBluetoothAdapter;
private int REQUEST_ENABLE_BT = 1;
private static final long SCAN_PERIOD = 5000;
private static final long STOP_PERIOD = 1000;
private BluetoothLeScanner mLEScanner;
private ScanSettings settings;
private List<ScanFilter> filters;
private BluetoothGatt mGatt;
private Button scanButton;
private Button stopButton;
//private String proximityUUID = "0000180f-0000-1000-8000-00805f9b34fb";
private ProgressBar spinner;
private Handler scanHandler;
private String[] filterList = {
"D9:ED:5F:FA:0E:02",
"FF:37:3A:25:56:C7",
"F4:57:89:69:93:91"
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scanHandler = new Handler();
//determine if device supports BLE
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "BLE Not Supported",
Toast.LENGTH_SHORT).show();
finish();
}
//set up bluetooth manager
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
//scan progress bar
spinner=(ProgressBar)findViewById(R.id.progressBar);
spinner.setVisibility(View.GONE);
//scan button functionality
scanButton=(Button)findViewById(R.id.scan_button);
scanButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
spinner.setVisibility(View.VISIBLE);
scan.run();
}
});
//stop scan button functionality
stopButton=(Button)findViewById(R.id.stop_button);
stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
spinner.setVisibility(View.INVISIBLE);
scanHandler.removeCallbacks(scan);
scanHandler.removeCallbacks(stopScan);
}
});
}
#Override
protected void onResume() {
super.onResume();
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
} else {
mLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
//scan settings
settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
//scan filter
//populate the filter list
filters = new ArrayList<ScanFilter>();
for (int i=0; i< filterList.length ; i++) {
ScanFilter filter = new ScanFilter.Builder().setDeviceAddress(filterList[i]).build();
filters.add(filter);
}
}
}
#Override
protected void onPause() {
super.onPause();
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
}
}
#Override
protected void onDestroy() {
if (mGatt == null) {
return;
}
mGatt.close();
mGatt = null;
super.onDestroy();
}
//start scan
private Runnable scan = new Runnable() {
#Override
public void run() {
scanHandler.postDelayed(stopScan, SCAN_PERIOD);
mLEScanner.startScan(filters, settings, mScanCallback);
Log.e("BLE_Scanner", "Start Scan");
}
};
private ScanCallback mScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
Log.i("callbackType", String.valueOf(callbackType));
Log.i("result", result.toString());
BluetoothDevice device = result.getDevice();
int mRSSI = result.getRssi();
}
#Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult sr : results) {
Log.i("ScanResult - Results", sr.toString());
}
}
#Override
public void onScanFailed(int errorCode) {
Log.e("Scan Failed", "Error Code: " + errorCode);
}
};
//stop scan
private Runnable stopScan = new Runnable() {
#Override
public void run() {
mLEScanner.stopScan(mScanCallback);
scanHandler.postDelayed(scan, STOP_PERIOD);
Log.e("BLE_Scanner", "Stop Scan");
}
};
private static double calculateAccuracy(int txPower, double rssi) {
if (rssi == 0) {
return -1.0; // if we cannot determine accuracy, return -1.
}
double ratio = -rssi*1.0/txPower;
if (ratio < 1.0) {
return Math.pow(ratio,10);
}
else {
double accuracy = (0.89976)*Math.pow(ratio,7.7095) + 0.111;
return accuracy;
}
}
}
I imagine you just want to call startScan immediately on start button press (not in a Runnable, not scheduled through a Handler). The call is asynchronous, so nothing will block, and Android will do all the scanning in another thread. If you then want to schedule a call to stop in the future, then you use the Handler to post a Runnable that calls stopScan at the delay you need.
The button for stopping the scan can also just directly call stopScan() if know that a scan was previously in progress. You might want to use a boolean to gate the call to stopScan only if there was a previous call to startScan().
So, I ended up finding a way to get it to work as intended. I don't know if the way I'm doing things is best practice as I'm new to Android and Java, but this is what worked for me. All I did was call the stopScan method in the stop button after removing the handler callbacks.
//stop scan button functionality
stopButton=(Button)findViewById(R.id.stop_button);
stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
spinner.setVisibility(View.INVISIBLE);
scanHandler.removeCallbacksAndMessages(null);
mLEScanner.stopScan(mScanCallback);
}
});
I have an activity (not my main activity) that plays some sounds and draw some graphics in a runnable thread. There is an imagebutton with which I'm supposed to suspend and resume the thread. But whatever I try the thread just runs on. I'm totally stuck! Please help.
public class PlayInterval extends Activity {
private Handler customHandler;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_playinterval);
final ImageButton playPauseButton = (ImageButton) findViewById(R.id.playPauseButton);//Play/Pause
playPauseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onPlayPauseClicked(playPauseButton,(String)playPauseButton.getTag());
}
});
customHandler = new Handler();
new Thread(new Task()).start();
}
#Override
public void onBackPressed() {
customHandler.removeCallbacksAndMessages(null);
finish();
}
class Task implements Runnable {
#Override
public void run() {
// Do really cool stuff
// and even cooler stuff
customHandler.postDelayed(this, 100);
}
}
private void onPlayPauseClicked(ImageButton playPauseButton, String status) {
if (status == "playing") {
playPauseButton.setTag("paused");
customHandler.removeCallbacksAndMessages(null); //TODO suspend here not working!
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
playPauseButton.setImageResource(getResources().getIdentifier("pause_image", "drawable", getPackageName()));
} else {
playPauseButton.setImageDrawable(getDrawable(getResources().getIdentifier("pause_image", "drawable", getPackageName())));
}
} else {
playPauseButton.setTag("playing");
customHandler.postDelayed(this, 100); //TODO resume here not working!
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
playPauseButton.setImageResource(getResources().getIdentifier("play_image", "drawable", getPackageName()));
} else {
playPauseButton.setImageDrawable(getDrawable(getResources().getIdentifier("play_image", "drawable", getPackageName())));
}
}
}
}
I never did get an answer so after trial and error I came up with this. I've red quite alot here on StackOverflow and what I understand this is NOT the way it is supposed to be done. But it is working very well, so if anyone could explain why one shouldn't use syncronized methods like this and provide a better answer I would be thankful.
Cheers
public class PlayInterval extends Activity {
private Handler customHandler;
Boolean isRunning;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_playinterval);
final ImageButton playPauseButton = (ImageButton)findViewById(R.id.playPauseButton);//Play/Pause
playPauseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
onPlayPauseClicked(playPauseButton);
}
});
customHandler = new Handler();
isRunning=true;
new Thread(new Task()).start();
}
#Override
public void onBackPressed() {
customHandler.removeCallbacksAndMessages(null);
finish();
}
class Task implements Runnable {
#Override
public void run() {
if (isRunning == true){
// Do really cool stuff
// and even cooler stuff
} else {
// it is paused
}
customHandler.postDelayed(this, 100);
}
private syncronized void onPlayPauseClicked(ImageButton playPauseButton) {
if (isRunning==true) {
isRunning=false;
playPauseButton.setImageResource(getResources().getIdentifier("play_image", "drawable", getPackageName()));
} else {
isRunning=true;
playPauseButton.setImageResource(getResources().getIdentifier("pause_image", "drawable", getPackageName()));
}
}
}
I am trying to create a service that will show a toast every second with the most recent running application. Every time I start the service, I get a NullPointerException. What can I do to avoid this?
public class CheckRunningActivity extends Service {
private static final String TAG = "CheckRunningActivity";
boolean checkApps;
private Timer mTimer = null;
private Handler mHandler = new Handler();
private ActivityManager am;
public static final long NOTIFY_INTERVAL = 1000; // 1 second
#Override
public void onDestroy() {
mTimer.cancel();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
Log.d(TAG, "I created it");
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
// cancel if already existed
if(mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
Log.d(TAG, "Its running");
String packageName = am.getRunningTasks(1).get(0).topActivity
.getPackageName();
Toast.makeText(getBaseContext(), packageName, Toast.LENGTH_LONG).show();
Log.d(TAG, "Make Toast");
}
});
}
}
}
you can't directly call toast from service . you need a handler for this. see answer here.
after looking at the code again, I realized that I had not properly initialized the Activity Manager.
Here is the corrected code...
public class CheckRunningActivity extends Service {
private static final String TAG = "CheckRunningActivity";
boolean checkApps;
private Timer mTimer = null;
private Handler mHandler = new Handler();
private ActivityManager am;
public static final long NOTIFY_INTERVAL = 1000; // 1 second
#Override
public void onDestroy() {
mTimer.cancel();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
Log.d(TAG, "I created it");
// cancel if already existed
if(mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
Log.d(TAG, "Its running");
String packageName = am.getRunningTasks(1).get(0).topActivity.getPackageName();
Toast.makeText(getBaseContext(), packageName, Toast.LENGTH_LONG).show();
Log.d(TAG, "Make Toast");
}
});
}
}
}
I'm trying to update my digital clock using timertask. I have created a function called updateClock() which sets the hours and minutes to the current time but I haven't been able to get it to run periodically. From what I've read in other answers one of the best options is to use timertask however I haven't been able to make any example I found online work inside an Android activity.
This is what I've written so far:
public class MainActivity extends Activity {
TextView hours;
TextView minutes;
Calendar c;
int cur_hours;
int cur_minutes;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.clock_home);
hours = (TextView) findViewById(R.id.hours);
minutes = (TextView) findViewById(R.id.minutes);
updateClock();
}
public void updateClock() {
c = Calendar.getInstance();
hours.setText("" + c.get(Calendar.HOUR));
minutes.setText("" + c.get(Calendar.MINUTE));
}
public static void init() throws Exception {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
updateClock(); // ERROR
}
}, 0, 1 * 5000);
}
}
How can I make it work?
Use runOnUiThread for updating Ui from Timer Thread
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
MainActivity.this.runOnUiThread (new Runnable() {
public void run() {
updateClock(); // call UI update method here
}
}));
}
}, 0, 1 * 5000);
}
if you just need updates every minute, you can also listen to the ACTION_TIME_TICK broadcast event.
private boolean timeReceiverAttached;
private final BroadcastReceiver timeReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateClock();
}
};
private Handler handler = new Handler();
#Override
protected void onResume() {
super.onResume();
updateClock();
if (!timeReceiverAttached) {
timeReceiverAttached = true;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_TIME_TICK);
filter.addAction(Intent.ACTION_TIME_CHANGED);
filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
registerReceiver(timeReceiver, filter, null, handler);
}
}
#Override
protected void onPause() {
super.onPause();
if (timeReceiverAttached) {
unregisterReceiver(timeReceiver);
timeReceiverAttached = false;
}
}
OR, periodically post the Runnable to the Handler of UI thread. Also, pause and resume tasks to save battery.
public class MyActivity extends Activity {
private final Handler mHandler = new Handler();
private final Timer mTimer = new Timer();
#Override
protected void onResume() {
super.onResume();
mTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
mHandler.post(new Runnable() {
#Override
public void run() {
//---update UI---
}
});
}
},0,5000);
}
#Override
protected void onPause() {
super.onPause();
mTimer.cancel();
}
}