Back to project page ArcTimer.
The source code is released under:
GNU General Public License
If you think the Android project ArcTimer listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.taavo.arctimer; //from w w w .j a v a2 s.c om import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.PreferenceManager; import android.view.Menu; import android.view.View; import android.view.Window; import android.view.WindowManager; import java.util.ArrayList; import java.util.List; public class ArcTimerActivity extends Activity implements Runnable, View.OnClickListener, View.OnLongClickListener { private ArcTimerView cv = null; private Thread t = null; private boolean run_thread = false; private int run_thread_fps = 50; // Max 1000 private IntervalSession is; private final int MENU_PREFERENCES = 15; //@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); is = new IntervalSession(); restorePreferences(); cv = new ArcTimerView(this, is); cv.setOnClickListener(this); cv.setOnLongClickListener(this); restoreRunningState(getLastNonConfigurationInstance()); setContentView(cv); } @Override public boolean onPrepareOptionsMenu(Menu menu) { super.onPrepareOptionsMenu(menu); startActivityForResult(new Intent(this, Prefs.class), MENU_PREFERENCES); return true; } protected void onActivityResult(int req, int result, Intent data) { switch( req ) { case MENU_PREFERENCES: restorePreferences(); is.stopSession(); cv.updateClocks(); break; default: super.onActivityResult(req, result, data); break; } } private void restorePreferences() { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); is.totalWorkCycles = Integer.valueOf(prefs.getString("cycles", "8")); is.workCycleTime = 1000*Long.valueOf(prefs.getString("workTime", "20")); is.restCycleTime = 1000*Long.valueOf(prefs.getString("restTime", "10")); is.currentCycleTime = is.workCycleTime; } public void onClick(View view) { System.out.println("short press released!"); if (is.running) { // PAUSE is.pauseSession(); is.running = false; } else { if (is.startTime == 0) { // START is.startSession(); } else { // RESUME is.resumeSession(); } is.running = true; } } public boolean onLongClick(View view) { if (is.startTime > 0) { resetDialog(); } return true; } private void updateGfx() { is.updateSession(); cv.updateClocks(); } @Override public Object onRetainNonConfigurationInstance() { return storeRunningState(); } private void restoreRunningState(Object o) { if(o != null) { @SuppressWarnings("unchecked") ArrayList<Object> cfgList = (ArrayList<Object>)o; run_thread = (Boolean) cfgList.get(0); is.running = (Boolean) cfgList.get(1); is.startTime = (Long) cfgList.get(2); is.elapsedTime = (Long) cfgList.get(3); is.pausedTime = (Long) cfgList.get(4); is.currentCycleType = (Integer) cfgList.get(5); is.currentCycle = (Integer) cfgList.get(6); is.startCycleTime = (Long) cfgList.get(7); is.elapsedCycleTime = (Long) cfgList.get(8); is.running = (Boolean) cfgList.get(9); cv.sem.release((Integer) cfgList.get(10)); cv.run_thread = (Boolean) cfgList.get(11); } } private Object storeRunningState() { List<Object> cfgList = new ArrayList<Object>(); cfgList.add(Boolean.valueOf(run_thread)); cfgList.add(Boolean.valueOf(is.running)); cfgList.add(Long.valueOf(is.startTime)); cfgList.add(Long.valueOf(is.elapsedTime)); cfgList.add(Long.valueOf(is.pausedTime)); cfgList.add(Integer.valueOf(is.currentCycleType)); cfgList.add(Integer.valueOf(is.currentCycle)); cfgList.add(Long.valueOf(is.startCycleTime)); cfgList.add(Long.valueOf(is.elapsedCycleTime)); cfgList.add(Boolean.valueOf(is.running)); cfgList.add(Integer.valueOf(cv.sem.availablePermits())); cfgList.add(Boolean.valueOf(cv.run_thread)); return cfgList; } @Override protected void onPause() { super.onPause(); run_thread = false; while(true) { try{ t.join(); break; } catch (InterruptedException e) { e.printStackTrace(); } } t = null; } @Override protected void onResume() { super.onResume(); t = new Thread(this); run_thread = true; t.start(); } /** * Main timer thread. As long as an IntervalSession is running, * call session & view to update. */ public void run() { while(run_thread) { if(is.running) { updateGfx(); } try { Thread.sleep(1000/run_thread_fps); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * Displays an alertbox asking you to reset the timer. * If positive it will stop the timer and reset the clocks. * If negative it will instantly resume the countdown. */ protected void resetDialog() { is.pauseSession(); is.running = false; new AlertDialog.Builder(this) .setMessage(com.taavo.arctimer.R.string.resetDialog_msg) .setTitle(com.taavo.arctimer.R.string.resetDialog_title) .setCancelable(true) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { is.stopSession(); cv.updateClocks(); } }) .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); is.resumeSession(); is.running = true; } }) .show(); } }