Back to project page WorkOut.
The source code is released under:
Apache License
If you think the Android project WorkOut 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 org.damcode.workout; //from w w w .ja v a 2s . c om import android.app.Service; import android.content.Intent; import android.media.AudioManager; import android.media.SoundPool; import android.os.Bundle; import android.os.CountDownTimer; import android.os.Handler; import android.os.IBinder; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.util.Log; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.List; /** * Created by dm on 2/10/2014. */ public class WorkoutCountdownService extends Service { public static final int MSG_REGISTER_CLIENT = 1; public static final int MSG_UNREGISTER_CLIENT = 2; public static final int MSG_START_TIMER = 3; public static final int MSG_PAUSE_TIMER = 4; public static final int MSG_RESUME_TIMER = 5; public static final int MSG_CANCEL_TIMER = 6; public static final int MSG_TOGGLE_CONT = 7; public static final int MSG_TIMER_FINISHED = 8; public static final int MSG_TIME_REMAINING = 9; private List<Messenger> mClients = new ArrayList<Messenger>(); // Keeps track of all current registered clients. private CountDownTimer timer; private int totalTime = 0, remainingTime = 0; private int workoutId = -1; private ArrayDeque beepQueue, origQueue; private boolean continuous; private SoundPool soundPool; private int sndBeep, sndPause; public boolean isRunning = false; private final Messenger messenger = new Messenger(new IncomingMessageHandler()); @Override public IBinder onBind(Intent intent) { return messenger.getBinder(); } @Override public void onCreate() { Log.d("CountdownService", "onCreate"); soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0); sndBeep = soundPool.load(this, R.raw.beep, 1); sndPause = soundPool.load(this, R.raw.beeppause, 1); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d("CountdownService", "i got started!"); return START_STICKY; } void cancelTimer() { if (timer != null) { timer.cancel(); timer = null; } totalTime = 0; remainingTime = 0; continuous = false; isRunning = false; } @Override public void onDestroy() { super.onDestroy(); if (soundPool != null) { soundPool.release(); soundPool = null; } cancelTimer(); Log.d("CountdownService", "i got destroyed!"); } class IncomingMessageHandler extends Handler { @Override public void handleMessage(Message msg) { try { switch (msg.what) { case MSG_REGISTER_CLIENT: mClients.add(msg.replyTo); /* Log.e("Countdown handler: ", "number of clients : " + mClients.size() + ", is running: " + String.valueOf(isRunning)); */ if (isRunning) { if (workoutId != msg.getData().getInt("workoutid")) { Log.e("Countdown handler: ", "not same workout id in register"); cancelTimer(); } else { Log.e("Countdown handler: ", "sending resume to client!"); msg.replyTo.send(Message.obtain(null, MSG_RESUME_TIMER)); int cont = (continuous) ? 1 : 0; msg.replyTo.send(Message.obtain(null, MSG_TOGGLE_CONT, cont, 0)); } } workoutId = msg.getData().getInt("workoutid"); break; case MSG_UNREGISTER_CLIENT: mClients.remove(msg.replyTo); break; case MSG_START_TIMER: totalTime = msg.getData().getInt("time"); remainingTime = totalTime; beepQueue = (ArrayDeque) msg.getData().get("beepqueue"); origQueue = new ArrayDeque(beepQueue); startTimer(); break; case MSG_PAUSE_TIMER: timer.cancel(); timer = null; isRunning = false; break; case MSG_RESUME_TIMER: if (timer == null) startTimer(); break; case MSG_CANCEL_TIMER: cancelTimer(); break; case MSG_TOGGLE_CONT: continuous = msg.arg1 == 1; default: super.handleMessage(msg); } } catch (Exception e) { e.printStackTrace(); } } } private void sendMessage(Message message) { message.replyTo = messenger; for (int i = mClients.size() - 1; i >= 0; i--) { try { mClients.get(i).send(message); } catch (RemoteException e) { Log.e("Countdown service", "Exception !"); mClients.remove(i); } } } private void startTimer() { isRunning = true; timer = new CountDownTimer((remainingTime) * 1000, 1000) { public void onTick(long millisUntilFinished) { remainingTime = (int) (millisUntilFinished / 1000); Message msg = Message.obtain(null, MSG_TIME_REMAINING); Bundle b = new Bundle(); b.putInt("remaining", (int) remainingTime); msg.setData(b); sendMessage(msg); doBeep(remainingTime, totalTime); } public void onFinish() { timer = null; if (continuous) { doBeep(0, totalTime); remainingTime = totalTime; beepQueue = new ArrayDeque(origQueue); startTimer(); } else { soundPool.play(sndBeep, 1, 1, 0, 2, 1); cancelTimer(); sendMessage(Message.obtain(null, MSG_TIMER_FINISHED)); } } }.start(); } private void doBeep(int remainingTime, int totalTime) { int elapsedTime = totalTime - remainingTime; if (((int[]) beepQueue.peek())[0] == elapsedTime) { int beepType = ((int[]) beepQueue.peek())[1]; if(beepType == WorkoutSessionActivity.BEEP_TYPE_ACTION){ soundPool.play(sndBeep, 1, 1, 0, 1, 1); } else if(beepType == WorkoutSessionActivity.BEEP_TYPE_REST){ soundPool.play(sndPause, 1, 1, 0, 1, 2); } beepQueue.poll(); } } } //eof