de.damdi.fitness.activity.start_training.RecoveryTimerManager.java Source code

Java tutorial

Introduction

Here is the source code for de.damdi.fitness.activity.start_training.RecoveryTimerManager.java

Source

/**
 * 
 * This is OpenTraining, an Android application for planning your your fitness training.
 * Copyright (C) 2012-2013 Christian Skubich
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package de.damdi.fitness.activity.start_training;

import java.util.Timer;
import java.util.TimerTask;

import android.app.NotificationManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import de.damdi.fitness.R;

/**
 * Singleton class for managing the recovery-time-notification.
 * Using the singleton pattern for making it easier to control the notification within the whole application.
 *
 */
public enum RecoveryTimerManager {
    INSTANCE;

    private static final String TAG = "RecoveryTimerManager";
    private static final int RECOVERY_TIMER_NOTIFICATION_ID = 0;

    private Context mContext;

    private NotificationCompat.Builder mNotificationBuilder;
    private NotificationManager mNotifyManager;
    private Timer mSetTimer = new Timer();;

    private boolean mVibrationEnabled = true;
    private boolean mNotificationSoundEnabled = true;

    private enum RecoveryTimerKind {
        SET_RECOVER_TIMER, EXERCISE_RECOVERY_TIMER;

        // not using getter/setter to avoid the boilerplate code
        // as this is a private enum this should not be a problem
        public int timerDurationInSec = 0;
        public String tickerRunning = "Erholungsphase ...";
        public String contentTitleRunning = "Erholungsphase ...";
        public String tickerFinished = "Ende Erholungsphase";
        public String contentTitleFinished = "Erholungsphase beendet";
    };

    /**
     * Starts the set recovery timer, the app will display a notification.
     * Deletes/stops already running recovery timers.
     * 
     * @param context Current application context.
     */
    public synchronized void startSetRecoveryTimer(Context context) {
        if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean("training_timer_enabled", true)) {
            Log.v(TAG, "Will not start training timer, as it has been disabled.");
            return;
        }

        setUp(context);

        // make sure to stop an already running recovery timer
        stopRecoveryTimer();
        startTimer(RecoveryTimerKind.SET_RECOVER_TIMER);
    }

    /**
     * Starts the exercise recovery timer, the app will display a notification.
     * Deletes/stops already running recovery timers.
     * 
     * @param context Current application context.
     */
    public synchronized void startExerciseRecoveryTimer(Context context) {
        if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean("training_timer_enabled", true)) {
            Log.v(TAG, "Will not start training timer, as it has been disabled.");
            return;
        }

        setUp(context);

        // make sure to stop an already running set timer
        stopRecoveryTimer();
        startTimer(RecoveryTimerKind.EXERCISE_RECOVERY_TIMER);

    }

    /** Updates context and user settings. */
    private void setUp(Context context) {
        mContext = context;
        mNotifyManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);

        // update user settings/preferences
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
        mVibrationEnabled = prefs.getBoolean("training_timer_vibration_enabled", true);
        mNotificationSoundEnabled = prefs.getBoolean("training_timer_sound_enabled", true);

        RecoveryTimerKind.EXERCISE_RECOVERY_TIMER.timerDurationInSec = Integer
                .valueOf(prefs.getString("training_timer_exercise_recovery_time", "180"));
        RecoveryTimerKind.EXERCISE_RECOVERY_TIMER.contentTitleFinished = mContext
                .getString(R.string.exercise_recover_timer_content_title_finished);
        RecoveryTimerKind.EXERCISE_RECOVERY_TIMER.contentTitleRunning = mContext
                .getString(R.string.exercise_recover_timer_content_title_running);
        RecoveryTimerKind.EXERCISE_RECOVERY_TIMER.tickerFinished = mContext
                .getString(R.string.exercise_recover_timer_ticker_finished);
        RecoveryTimerKind.EXERCISE_RECOVERY_TIMER.tickerRunning = mContext
                .getString(R.string.exercise_recover_timer_ticker_running);

        RecoveryTimerKind.SET_RECOVER_TIMER.timerDurationInSec = Integer
                .valueOf(prefs.getString("training_timer_set_recovery_time", "30"));
        RecoveryTimerKind.SET_RECOVER_TIMER.contentTitleFinished = mContext
                .getString(R.string.set_recover_timer_content_title_finished);
        RecoveryTimerKind.SET_RECOVER_TIMER.contentTitleRunning = mContext
                .getString(R.string.set_recover_timer_content_title_running);
        RecoveryTimerKind.SET_RECOVER_TIMER.tickerFinished = mContext
                .getString(R.string.set_recover_timer_ticker_finished);
        RecoveryTimerKind.SET_RECOVER_TIMER.tickerRunning = mContext
                .getString(R.string.set_recover_timer_ticker_running);
    }

    private synchronized void startTimer(final RecoveryTimerKind timerKind) {
        // create notification
        mNotificationBuilder = new NotificationCompat.Builder(mContext);
        mNotificationBuilder.setContentTitle(timerKind.contentTitleRunning)
                .setSmallIcon(R.drawable.icon_dumbbell_small)
                .setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.drawable.icon_dumbbell));

        final boolean doVibrate = mVibrationEnabled;
        final boolean doBeep = mNotificationSoundEnabled;
        int maxInSec = timerKind.timerDurationInSec;
        final int max = 10 * maxInSec;
        mSetTimer = new Timer();

        TimerTask task = new TimerTask() {
            private int counter = 0;

            @Override
            public void run() {
                // update progress if still running
                if (counter < max) {
                    mNotificationBuilder.setTicker(timerKind.tickerRunning);
                    mNotificationBuilder.setProgress(max, counter, false);
                    mNotificationBuilder.setUsesChronometer(true);
                    // Displays the progress bar for the first time.
                    mNotifyManager.notify(0, mNotificationBuilder.build());

                    counter++;
                } else {
                    mNotificationBuilder.setProgress(max, max, false);
                    //mNotificationBuilder.setNumber(max);

                    // change message if progress is finished
                    mNotificationBuilder.setContentTitle(timerKind.contentTitleFinished);
                    mNotificationBuilder.setTicker(timerKind.tickerFinished);

                    // let phone vibrate (unless user disabled this feature)
                    if (doVibrate) {
                        long[] vibrationPattern = { 0, 300 };
                        mNotificationBuilder.setVibrate(vibrationPattern);
                    }
                    // make a notification sound (unless user disabled this feature)
                    if (doBeep) {
                        Uri defaultSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                        mNotificationBuilder.setSound(defaultSound);
                    }
                    mNotificationBuilder.setAutoCancel(true);
                    mNotifyManager.notify(RECOVERY_TIMER_NOTIFICATION_ID, mNotificationBuilder.build());
                    mSetTimer.cancel();

                }

            }
        };

        long period = 100;
        long delay = 0;
        mSetTimer.scheduleAtFixedRate(task, delay, period);
    }

    /**
     * Stops an already running recovery timer (SET_RECOVER_TIMER,
     * as well as EXERCISE_RECOVERY_TIMER).
     * 
     * Will do nothing if there's no set recovery timer running.
     */
    public synchronized void stopRecoveryTimer(Context context) {
        setUp(context);
        stopRecoveryTimer();
    }

    /** @see #stopRecoveryTimer(Context) */
    private synchronized void stopRecoveryTimer() {
        mSetTimer.cancel();
        mNotifyManager.cancel(RECOVERY_TIMER_NOTIFICATION_ID);
    }

}