Android Open Source - WorkOut Workout Countdown Service






From Project

Back to project page WorkOut.

License

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.

Java Source Code

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





Java Source Code List

org.damcode.workout.ApplicationTest.java
org.damcode.workout.ListViewItemLongClickHandler.java
org.damcode.workout.MainActivity.java
org.damcode.workout.StaticUtils.java
org.damcode.workout.WorkoutCountdownService.java
org.damcode.workout.WorkoutDBAO.java
org.damcode.workout.WorkoutDataHelper.java
org.damcode.workout.WorkoutSessionActivity.java