published today. refs #128

This commit is contained in:
warren powers
2011-03-05 20:01:04 +00:00
parent fca8c7f9c9
commit e7a5885e97
16 changed files with 425 additions and 149 deletions

View File

@@ -3,7 +3,7 @@
android:installLocation="auto" android:versionCode="5" android:versionName="0.0.5" package="com.TwentyCodes.android.SweetDreamsLib"> android:installLocation="auto" android:versionCode="5" android:versionName="0.0.5" package="com.TwentyCodes.android.SweetDreamsLib">
<application android:label="@string/app_name" android:icon="@drawable/playdisabled"> <application android:label="@string/app_name" android:icon="@drawable/playdisabled">
<activity android:name="SweetDreamsFull" <activity android:name="SweetDreamsMain"
android:label="@string/app_name" android:label="@string/app_name"
android:screenOrientation="portrait"> android:screenOrientation="portrait">
<intent-filter> <intent-filter>

View File

@@ -0,0 +1,8 @@
fixes #172
added a check in SweetDreamsMain to see if the timer is <= to 0. if so close application. This resulted in the application
closing if the exit on finish was selected because the timer is always 0 or less than if it isn't running.
modified line in Service for when timer is decreased to stop at 0.
in short. the issue was being that the timer only had two states. it was either -1 or above zero. if the timer was -1 it represented both the timer was complete
and that a timer never existed. thus the application would not close. modified the timer to be at 0 if the timer never existed and -1 if finished. above zero
represents still in play

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -5,6 +5,6 @@
<item>Beach</item> <item>Beach</item>
<item>Crickets</item> <item>Crickets</item>
<item>Water Falls</item> <item>Water Falls</item>
<item>Air Conditioner</item> <item>White Noise</item>
</string-array> </string-array>
</resources> </resources>

View File

@@ -0,0 +1,20 @@
/**
* Playback.aidl
* @date Feb 19, 2011
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.SweetDreamsLib;
interface Playback {
void play(int resId);
void stop();
boolean isPlaying();
long getTimeRemaining();
}

View File

@@ -0,0 +1,176 @@
/**
* PlaybackService.java
* @date Feb 19, 2011
* @author ricky barrette
* @author Twenty Codes, LLC
*/
package com.TwentyCodes.android.SweetDreamsLib;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.TwentyCodes.android.SweetDreamsLib.Playback.Stub;
/**
* This service will handle sound track play back to allow for seem-less play back while configuration changes happen
* @author ricky barrette
*/
public class PlaybackService extends Service implements Runnable{
private MediaPlayer mMediaPlayer;
private long mTimeRemaining = 0;
private Handler mHandler;
private final Stub mPlayback = new Playback.Stub(){
/**
* a convince method used to get the amount of time left
* (non-Javadoc)
* @see com.TwentyCodes.android.SweetDreamsLib.Playback#getTimeRemaining()
* @author ricky barrette
*/
@Override
public long getTimeRemaining() throws RemoteException {
return mTimeRemaining;
}
/**
* returns whether or not the media player is playing
* (non-Javadoc)
* @see com.TwentyCodes.android.SweetDreamsLib.Playback#isPlaying()
* @author ricky barrette
*/
@Override
public boolean isPlaying() throws RemoteException {
if(mMediaPlayer != null)
return mMediaPlayer.isPlaying();
else
return false;
}
/**
* plays the specified sound track, infinitely looping it
* (non-Javadoc)
* @see com.TwentyCodes.android.SweetDreamsLib.Playback#play(int)
* @author ricky barrette
*/
@Override
public void play(int resId) throws RemoteException {
stop();
mMediaPlayer = MediaPlayer.create(PlaybackService.this, resId);
mMediaPlayer.setLooping(true);
mMediaPlayer.start();
SharedPreferences settings = PlaybackService.this.getSharedPreferences(Settings.SETTINGS, Context.MODE_PRIVATE);
boolean timerEnabled = settings.getBoolean(Settings.TIMER_ENABLED, false);
if(SweetDreamsMain.isFUll == false)
timerEnabled = true;
if (timerEnabled){
mTimeRemaining = (settings.getInt("timer_length", 30) * 60000);
//start the timer
mHandler.postDelayed(PlaybackService.this, 1000l);
}
}
/**
* Stops the play back of the sound track
* (non-Javadoc)
* @see com.TwentyCodes.android.SweetDreamsLib.Playback#stop()
* @author ricky barrette
*/
@Override
public void stop() throws RemoteException {
try {
mMediaPlayer.stop();
} catch (Exception e) {
e.printStackTrace();
}
mHandler.removeCallbacks(PlaybackService.this);
}
};
/**
* (non-Javadoc)
* @see android.app.Service#onBind(android.content.Intent)
* @author ricky barrette
*/
@Override
public IBinder onBind(Intent intent) {
return mPlayback;
}
@Override
public void onCreate(){
Log.v(SweetDreamsMain.TAG, "PlaybackService.onCreate()");
super.onCreate();
mHandler = new Handler();
}
/**
* Called when the service is about to be destroyed.
* Here we release the media player
* (non-Javadoc)
* @see android.app.Service#onDestroy()
* @author ricky barrette
*/
@Override
public void onDestroy(){
Log.v(SweetDreamsMain.TAG, "PlaybackService.onDestroy()");
try {
mMediaPlayer.stop();
} catch (Exception e) {
e.printStackTrace();
}
try {
mMediaPlayer.release();
} catch (Exception e) {
e.printStackTrace();
}
mHandler.removeCallbacks(this);
mTimeRemaining = 0;
super.onDestroy();
}
@Override
public void run() {
Log.v(SweetDreamsMain.TAG, "Tick");
//stop the timer if there is nothing playing
if(mMediaPlayer != null) {
if(! mMediaPlayer.isPlaying())
mHandler.removeCallbacks(this);
}
else
mHandler.removeCallbacks(this);
mTimeRemaining = mTimeRemaining - 1000l;
if(mTimeRemaining <= 0) {
try {
mTimeRemaining = -1;
mPlayback.stop();
} catch (RemoteException e) {
e.printStackTrace();
}
this.stopSelf();
}
//que the next tick
mHandler.postDelayed(this, 1000l);
}
}

View File

@@ -26,7 +26,7 @@ public class Settings extends PreferenceActivity implements OnPreferenceChangeLi
protected static final String SOUND_BEACH = "Beach"; protected static final String SOUND_BEACH = "Beach";
protected static final String SOUND_CRICKETS = "Crickets"; protected static final String SOUND_CRICKETS = "Crickets";
protected static final String SOUND_FALLS = "Water Falls"; protected static final String SOUND_FALLS = "Water Falls";
protected static final String SOUND_AC = "Air Conditioner"; protected static final String SOUND_WN = "White Noise";
//the following strings are for saving volume level from the audiomanager.STREAM_MUSIC so we can restore them back when the app quits //the following strings are for saving volume level from the audiomanager.STREAM_MUSIC so we can restore them back when the app quits
protected static final String MUSIC_VOLUME = "music_volume"; protected static final String MUSIC_VOLUME = "music_volume";
@@ -47,7 +47,7 @@ public class Settings extends PreferenceActivity implements OnPreferenceChangeLi
getPreferenceManager().setSharedPreferencesName(SETTINGS); getPreferenceManager().setSharedPreferencesName(SETTINGS);
//load preferences xml //load preferences xml
this.addPreferencesFromResource( SweetDreamsFull.isFUll ? R.xml.settings : R.xml.settings_lite); this.addPreferencesFromResource( SweetDreamsMain.isFUll ? R.xml.settings : R.xml.settings_lite);
//get shared_prefs //get shared_prefs
SharedPreferences settings = getPreferenceManager().getSharedPreferences(); SharedPreferences settings = getPreferenceManager().getSharedPreferences();
@@ -69,7 +69,7 @@ public class Settings extends PreferenceActivity implements OnPreferenceChangeLi
Preference timerLength = findPreference(TIMER_LENGTH); Preference timerLength = findPreference(TIMER_LENGTH);
timerLength.setOnPreferenceChangeListener(this); timerLength.setOnPreferenceChangeListener(this);
try { try {
if(SweetDreamsFull.isFUll) if(SweetDreamsMain.isFUll)
timerLength.setSummary(settings.getInt(TIMER_LENGTH, 5)); timerLength.setSummary(settings.getInt(TIMER_LENGTH, 5));
else else
timerLength.setSummary(30); timerLength.setSummary(30);

View File

@@ -4,17 +4,20 @@
*/ */
package com.TwentyCodes.android.SweetDreamsLib; package com.TwentyCodes.android.SweetDreamsLib;
import com.TwentyCodes.android.exception.ExceptionHandler;
import android.app.Activity; import android.app.Activity;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.Editor;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle; import android.os.Bundle;
import android.os.CountDownTimer; import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
@@ -25,25 +28,65 @@ import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView; import android.widget.TextView;
import com.TwentyCodes.android.exception.ExceptionHandler;
/** /**
* this class is responsible for setting up the ui and handling ui events * this class is responsible for setting up the ui and handling ui events
* @author ricky * @author ricky
*/ */
public class SweetDreamsFull extends Activity implements OnClickListener, OnSeekBarChangeListener{ public class SweetDreamsMain extends Activity implements OnClickListener, OnSeekBarChangeListener, ServiceConnection, Runnable {
private boolean isPlaying; private boolean isPlaying;
private ImageButton mPlayPauseButton; private ImageButton mPlayPauseButton;
private AudioManager mAudioManager; private AudioManager mAudioManager;
private final int STREAM = AudioManager.STREAM_MUSIC; private final int STREAM = AudioManager.STREAM_MUSIC;
protected static MediaPlayer mMediaPlayer;
private ExceptionHandler mDamageReport; private ExceptionHandler mDamageReport;
private final int SETTINGS = Menu.FIRST; private final int SETTINGS = Menu.FIRST;
private final int QUIT = Menu.FIRST +1; private final int QUIT = Menu.FIRST +1;
private SharedPreferences mSettings; private SharedPreferences mSettings;
protected static final String TAG = "WhiteNoise"; protected static final String TAG = "SweetDreams";
private Timer mTimer; private Playback mService;
private Handler mHandler;
private SeekBar mVolume;
protected static TextView mTimeLeftTextView; protected static TextView mTimeLeftTextView;
protected static boolean isFUll = true; protected static boolean isFUll = true;
protected static final boolean DEBUG = true;
protected boolean inCall;
/**
* Call back class for PhoneStateListener to be used
* @author ricky barrette
*/
private class MyPhoneStateListener extends PhoneStateListener {
@Override
public void onCallStateChanged(int state,String incomingNumber){
Log.e(TAG, "PhoneCallStateNotified.Incoming");
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
if(isPlaying){
inCall = true;
stopPlaying();
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if(inCall){
inCall = false;
try {
loadSound();
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if(isPlaying){
inCall = true;
stopPlaying();
}
break;
}
}
}
/** /**
* adjusts the provided Stream volume to the provided level * adjusts the provided Stream volume to the provided level
@@ -52,7 +95,6 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
* @author ricky barrette * @author ricky barrette
*/ */
private void adjustVolume(int stream, int level) { private void adjustVolume(int stream, int level) {
/* /*
* if the seek bar is set to a value that is higher than what the the stream value is set for * if the seek bar is set to a value that is higher than what the the stream value is set for
* then subtract the seek bar's value from the current volume of the stream, and then * then subtract the seek bar's value from the current volume of the stream, and then
@@ -79,38 +121,38 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
} }
/** /**
* loads the sound from shared_prefs that the user wants, and set the mediaplayer to loop * loads the sound from shared_prefs that the user wants, and starts the playback service
* loads river sound track by default. * loads river sound track by default.
* *
* @author ricky barrette * @author ricky barrette
* @throws RemoteException
*/ */
private void loadSound(){ private void loadSound() throws RemoteException{
Log.i(TAG,"loadSound()"); if (DEBUG)
try { Log.i(TAG,"loadSound()");
mMediaPlayer.reset();
} catch (Exception e) { mPlayPauseButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.pause_button));
e.printStackTrace(); isPlaying = true;
}
String sound = mSettings.getString("sounds", Settings.SOUND_RIVER); String sound = mSettings.getString("sounds", Settings.SOUND_RIVER);
Log.v(TAG,"sound = "+ sound); if (DEBUG)
Log.v(TAG,"sound = "+ sound);
if (sound != null){ if (sound != null){
if (sound.equals(Settings.SOUND_BEACH)) if (mService != null) {
mMediaPlayer = MediaPlayer.create(this, R.raw.beach); if (sound.equals(Settings.SOUND_BEACH))
mService.play(R.raw.beach);
if (sound.equals(Settings.SOUND_WN))
mService.play(R.raw.wn);
if (sound.equals(Settings.SOUND_CRICKETS))
mService.play(R.raw.crickets);
if (sound.equals(Settings.SOUND_FALLS))
mService.play(R.raw.falls);
if (sound.equals(Settings.SOUND_RIVER))
mService.play(R.raw.river);
}
if (sound.equals(Settings.SOUND_AC))
mMediaPlayer = MediaPlayer.create(this, R.raw.ac);
if (sound.equals(Settings.SOUND_CRICKETS))
mMediaPlayer = MediaPlayer.create(this, R.raw.crickets);
if (sound.equals(Settings.SOUND_FALLS))
mMediaPlayer = MediaPlayer.create(this, R.raw.falls);
if (sound.equals(Settings.SOUND_RIVER))
mMediaPlayer = MediaPlayer.create(this, R.raw.river);
mMediaPlayer.setLooping(true);
} }
} }
/** /**
@@ -119,6 +161,8 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
*/ */
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (DEBUG)
Log.i(TAG, "onClick()");
/* /*
* if the sound track is no playing then * if the sound track is no playing then
* change the button background from a play symbol to a pause symbol, set isPlaying to true, load the user preferred sound track, and play it * change the button background from a play symbol to a pause symbol, set isPlaying to true, load the user preferred sound track, and play it
@@ -126,25 +170,17 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
* change the button background from a pause symbol to a play symbol, set isPlaying to false, and stop playing the sound track * change the button background from a pause symbol to a play symbol, set isPlaying to false, and stop playing the sound track
*/ */
if (!isPlaying){ if (!isPlaying){
mPlayPauseButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.pause_button)); try {
isPlaying = true; loadSound();
loadSound(); } catch (RemoteException e) {
mMediaPlayer.start(); e.printStackTrace();
boolean timerEnabled = mSettings.getBoolean(Settings.TIMER_ENABLED, false);
if(isFUll == false)
timerEnabled = true;
if (timerEnabled){
Log.v(TAG,"Starting timer");
long time = + (mSettings.getInt("timer_length", 30) * 60000);
Log.v(TAG,"time = " + time);
mTimer = new Timer(time);
mTimer.start();
} }
} else {
stopPlaying(); //if the timer is enabled, then start the ui updating handler
if(mSettings.getBoolean(Settings.TIMER_ENABLED, false) || ! isFUll)
mHandler.post(this);
} else {
stopPlaying();
} }
} }
@@ -158,8 +194,8 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// setContentView(R.layout.main); if (DEBUG)
Log.i(TAG,"onCreate()"); Log.i(TAG,"onCreate()");
// setup crash report handler // setup crash report handler
mDamageReport = new ExceptionHandler(this); mDamageReport = new ExceptionHandler(this);
@@ -174,17 +210,24 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
//initialize the volume seekbar and set //initialize the volume seekbar and set
SeekBar sbVolume = (SeekBar) findViewById(R.id.volume); mVolume = (SeekBar) findViewById(R.id.volume);
sbVolume.setOnSeekBarChangeListener(this); mVolume.setOnSeekBarChangeListener(this);
sbVolume.setMax(mAudioManager.getStreamMaxVolume(STREAM)); mVolume.setMax(mAudioManager.getStreamMaxVolume(STREAM));
sbVolume.setProgress(mAudioManager.getStreamVolume(STREAM)); mVolume.setProgress(mAudioManager.getStreamVolume(STREAM));
mTimeLeftTextView = (TextView) findViewById(R.id.time_left);
//load shared_prefs //load shared_prefs
mSettings = getSharedPreferences(Settings.SETTINGS, 0); mSettings = getSharedPreferences(Settings.SETTINGS, 0);
loadSound(); startService(new Intent(this, PlaybackService.class));
mHandler = new Handler();
saveStreamVolume(STREAM); saveStreamVolume(STREAM);
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
telephonyManager.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);
} }
/** /**
@@ -199,14 +242,22 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
} }
/** /**
* here we set the Stream volume back to what ever it was when the activity started
* (non-Javadoc) * (non-Javadoc)
* @see android.app.Activity#onDestroy() * @see android.app.Activity#onDestroy()
* @author ricky barrette * @author ricky barrette
*/ */
@Override @Override
public void onDestroy(){ public void onDestroy(){
adjustVolume(STREAM,mSettings.getInt(Settings.MUSIC_VOLUME, 0)); mHandler.removeCallbacks(this);
if(this.isPlaying && this.isFinishing() && mService != null)
stopPlaying();
this.unbindService(this);
if(this.isFinishing())
this.stopService(new Intent(this, PlaybackService.class));
super.onDestroy(); super.onDestroy();
} }
@@ -231,8 +282,18 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
return false; return false;
} }
/**
* called when the activity is being paused.
* here we cancel the timer if it exists to prevent any funky stuff from happening
* (non-Javadoc)
* @see android.app.Activity#onPause()
* @author ricky barrette
*/
@Override @Override
public void onPause(){ public void onPause(){
if (DEBUG)
Log.v(TAG, "onPause()");
mHandler.removeCallbacks(this);
super.onPause(); super.onPause();
} }
@@ -253,11 +314,6 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
} }
} }
@Override
public void onRestart(){
super.onRestart();
}
/** /**
* we load the track title textview in onResume so it will update every time the activity loads * we load the track title textview in onResume so it will update every time the activity loads
* (non-Javadoc) * (non-Javadoc)
@@ -266,20 +322,19 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
*/ */
@Override @Override
public void onResume(){ public void onResume(){
if (DEBUG)
Log.v(TAG,"onResume()");
super.onResume(); super.onResume();
this.bindService(new Intent(this, PlaybackService.class), this, Context.BIND_AUTO_CREATE);
TextView trackTitle = (TextView) findViewById(R.id.track_title); TextView trackTitle = (TextView) findViewById(R.id.track_title);
trackTitle.setText(mSettings.getString(Settings.SOUNDS,"Rainy River")); trackTitle.setText(mSettings.getString(Settings.SOUNDS,"Rainy River"));
} mHandler.post(this);
@Override
public void onStart(){
super.onStart();
} }
@Override @Override
public void onStartTrackingTouch(SeekBar seekBar) { public void onStartTrackingTouch(SeekBar seekBar) {
/* /*
* NOT YET IMPLEMENTED * NOT IMPLEMENTED
* needed for OnSeekBarChangeListener * needed for OnSeekBarChangeListener
*/ */
} }
@@ -292,19 +347,14 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
*/ */
@Override @Override
public void onStop(){ public void onStop(){
stopPlaying(); mHandler.removeCallbacks(this);
try {
mMediaPlayer.release();
} catch (Exception e) {
e.printStackTrace();
}
super.onStop(); super.onStop();
} }
@Override @Override
public void onStopTrackingTouch(SeekBar seekBar) { public void onStopTrackingTouch(SeekBar seekBar) {
/* /*
* NOT YET IMPLEMENTED * NOT IMPLEMENTED
* needed for OnSeekBarChangeListener * needed for OnSeekBarChangeListener
*/ */
} }
@@ -325,74 +375,101 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
* stops music from playing, sets the pay_pause button background to a play symbol, and if the time is enabled, cancels the timer * stops music from playing, sets the pay_pause button background to a play symbol, and if the time is enabled, cancels the timer
* *
* @author ricky barrette * @author ricky barrette
* @throws RemoteException
*/ */
private void stopPlaying(){ private void stopPlaying(){
if (DEBUG)
Log.i(TAG, "stopPlaying()");
mPlayPauseButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.play_button)); mPlayPauseButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.play_button));
isPlaying = false; isPlaying = false;
try { try {
mMediaPlayer.stop(); mService.stop();
} catch (IllegalStateException e) { } catch (RemoteException e) {
e.printStackTrace();
} catch (NullPointerException e){
e.printStackTrace(); e.printStackTrace();
Log.e(TAG,"failed to stop media player");
} }
if (mTimer != null) { mHandler.removeCallbacks(this);
mTimer.cancel(); mTimeLeftTextView.setText("");
mTimer = null; }
mTimeLeftTextView.setText("");
/**
* called when we get our connection to the playback service
* (non-Javadoc)
* @see android.content.ServiceConnection#onServiceConnected(android.content.ComponentName, android.os.IBinder)
* @author ricky barrette
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
if (DEBUG)
Log.v(TAG,"onServiceConnected()");
mService = Playback.Stub.asInterface(service);
try {
isPlaying = mService.isPlaying();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NullPointerException e){
e.printStackTrace();
}
if(isPlaying) {
mPlayPauseButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.pause_button));
mHandler.post(this);
} }
} }
/** /**
* this internal class will handle timing functions such as a timer that stops play back of a sound track & updates timeLeft textview every second * called when we disconnect from our service
* (non-Javadoc)
* @see android.content.ServiceConnection#onServiceDisconnected(android.content.ComponentName)
* @author ricky barrette * @author ricky barrette
*/ */
class Timer extends CountDownTimer { @Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
/** /**
* creates a new count down timer that stops play back of a sound track after specified time, and * convince method for formating the seconds string
* updates timeLeft textview every second * @param seconds
* @param millisInFuture * @return formated string
*/ * @author ricky barrette
public Timer(long millisInFuture) { */
super(millisInFuture, 1000l); private String padTime(int seconds){
Log.i(TAG,"Timer()"); if (seconds <= 9)
Log.v(TAG,"millisInFuture = "+ millisInFuture); return "0"+ seconds;
mTimeLeftTextView = (TextView) findViewById(R.id.time_left); return ""+ seconds;
int hours = (int) (millisInFuture / 3600000); }
millisInFuture = millisInFuture - (hours * 3600000);
int minutes = (int) ( millisInFuture / 60000); /**
int seconds = (int) (millisInFuture % 60000); * the run method of this runnable activity that is used to update the ui with the amount of time left
seconds = seconds / 1000; * (non-Javadoc)
mTimeLeftTextView.setText(hours +" : "+ padTime(minutes) +" : "+ padTime(seconds)); * @see java.lang.Runnable#run()
* @author ricky barrette
*/
@Override
public void run() {
boolean isTimerEnabled = mSettings.getBoolean("timer_enabled", false);
//if there is another instance in the que, remove it
mHandler.removeCallbacks(this);
//get the time remaining
long millisUntilFinished = 1;
try {
millisUntilFinished = mService.getTimeRemaining();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NullPointerException e){
e.printStackTrace();
} }
/** //update the UI
* stops the sound track being played by the media player if(millisUntilFinished == -1 && isTimerEnabled){
* (non-Javadoc) if (DEBUG)
* @see android.os.CountDownTimer#onFinish() Log.i(TAG, "run().timer is up");
* @author ricky barrette
*/
@Override
public void onFinish() {
Log.i(TAG,"onFinish()");
mTimeLeftTextView.setText("");
stopPlaying(); stopPlaying();
//if the user enables exit on finish, then kill the application } else {
if(mSettings.getBoolean(Settings.TIMER_EXIT_ON_FINISH, false)){
Log.v(TAG,"exit on finish enabled, calling finish()");
finish();
}
}
/**
* updates the timeLeft textView to display the current time left till sound stops
* @see android.os.CountDownTimer#onTick(long)
* @param millisUntilFinished
* @author ricky barrette
*/
@Override
public void onTick(long millisUntilFinished) {
Log.i(TAG,"onTick()");
int hours = (int) (millisUntilFinished / 3600000); int hours = (int) (millisUntilFinished / 3600000);
millisUntilFinished = millisUntilFinished - (hours * 3600000); millisUntilFinished = millisUntilFinished - (hours * 3600000);
int minutes = (int) ( millisUntilFinished / 60000); int minutes = (int) ( millisUntilFinished / 60000);
@@ -401,17 +478,12 @@ public class SweetDreamsFull extends Activity implements OnClickListener, OnSeek
mTimeLeftTextView.setText(hours +" : "+ padTime(minutes) +" : "+ padTime(seconds)); mTimeLeftTextView.setText(hours +" : "+ padTime(minutes) +" : "+ padTime(seconds));
} }
/** //if the time is 0 && if exit on finish is enabled, then exit else just stop playing then finish
* convince method for formating the seconds string if(millisUntilFinished == -1 && isTimerEnabled)
* @param seconds if(mSettings.getBoolean(Settings.TIMER_EXIT_ON_FINISH, false))
* @return formated string this.finish();
* @author ricky barrette
*/
private String padTime(int seconds){
if (seconds <= 9)
return "0"+ seconds;
return ""+ seconds;
}
//que another ui update
mHandler.postDelayed(this, 1000l);
} }
} }