33import android .graphics .Color ;
44import android .graphics .PorterDuff ;
55import android .graphics .drawable .ColorDrawable ;
6+ import android .media .MediaPlayer ;
67import android .os .Bundle ;
78import android .support .v7 .app .AppCompatActivity ;
89import android .view .Menu ;
1213import android .widget .RelativeLayout ;
1314import android .widget .TextView ;
1415
16+ import com .cleveroad .audiovisualization .DbmHandler ;
1517import com .cleveroad .audiovisualization .GLAudioVisualizationView ;
1618
1719import java .io .File ;
2325import omrecorder .PullTransport ;
2426import omrecorder .Recorder ;
2527
26- public class AudioRecorderActivity extends AppCompatActivity implements PullTransport .OnAudioChunkPulledListener {
28+ public class AudioRecorderActivity extends AppCompatActivity
29+ implements PullTransport .OnAudioChunkPulledListener ,
30+ MediaPlayer .OnCompletionListener , MediaPlayer .OnPreparedListener {
2731
32+ private MediaPlayer player ;
2833 private Recorder recorder ;
2934 private VisualizerHandler visualizerHandler ;
3035
31- private Timer timer ;
32- private MenuItem saveMenuItem ;
3336 private String filePath ;
3437 private int color ;
35- private int secondsRecorded ;
38+
39+ private Timer timer ;
40+ private MenuItem saveMenuItem ;
41+ private int secondsElapsed ;
3642 private boolean isRecording ;
3743
3844 private RelativeLayout contentLayout ;
39- private GLAudioVisualizationView audioVisualizationView ;
45+ private GLAudioVisualizationView visualizerView ;
46+ private TextView statusView ;
4047 private TextView timerView ;
4148 private ImageButton restartView ;
4249 private ImageButton recordView ;
@@ -47,8 +54,13 @@ protected void onCreate(Bundle savedInstanceState) {
4754 super .onCreate (savedInstanceState );
4855 setContentView (R .layout .activity_audio_recorder );
4956
50- filePath = getIntent ().getStringExtra (AndroidAudioRecorder .EXTRA_FILE_PATH );
51- color = getIntent ().getIntExtra (AndroidAudioRecorder .EXTRA_COLOR , Color .BLACK );
57+ if (savedInstanceState != null ) {
58+ filePath = savedInstanceState .getString (AndroidAudioRecorder .EXTRA_FILE_PATH );
59+ color = savedInstanceState .getInt (AndroidAudioRecorder .EXTRA_COLOR );
60+ } else {
61+ filePath = getIntent ().getStringExtra (AndroidAudioRecorder .EXTRA_FILE_PATH );
62+ color = getIntent ().getIntExtra (AndroidAudioRecorder .EXTRA_COLOR , Color .BLACK );
63+ }
5264
5365 if (getSupportActionBar () != null ) {
5466 getSupportActionBar ().setHomeButtonEnabled (true );
@@ -61,7 +73,7 @@ protected void onCreate(Bundle savedInstanceState) {
6173 getResources ().getDrawable (R .drawable .ic_clear ));
6274 }
6375
64- audioVisualizationView = new GLAudioVisualizationView .Builder (this )
76+ visualizerView = new GLAudioVisualizationView .Builder (this )
6577 .setLayersCount (1 )
6678 .setWavesCount (6 )
6779 .setWavesHeight (R .dimen .wave_height )
@@ -74,51 +86,63 @@ protected void onCreate(Bundle savedInstanceState) {
7486 .build ();
7587
7688 contentLayout = (RelativeLayout ) findViewById (R .id .content );
89+ statusView = (TextView ) findViewById (R .id .status );
7790 timerView = (TextView ) findViewById (R .id .timer );
7891 restartView = (ImageButton ) findViewById (R .id .restart );
7992 recordView = (ImageButton ) findViewById (R .id .record );
8093 playView = (ImageButton ) findViewById (R .id .play );
8194
8295 contentLayout .setBackgroundColor (Util .getDarkerColor (color ));
83- contentLayout .addView (audioVisualizationView , 0 );
96+ contentLayout .addView (visualizerView , 0 );
8497 restartView .setVisibility (View .INVISIBLE );
8598 playView .setVisibility (View .INVISIBLE );
8699
87- visualizerHandler = new VisualizerHandler ();
88- audioVisualizationView .linkTo (visualizerHandler );
89-
90100 if (Util .isBrightColor (color )) {
91- restartView .setColorFilter (Color .BLACK );
92- recordView .setColorFilter (Color .BLACK );
93- playView .setColorFilter (Color .BLACK );
94- timerView .setTextColor (Color .BLACK );
95101 getResources ().getDrawable (R .drawable .ic_clear )
96102 .setColorFilter (Color .BLACK , PorterDuff .Mode .SRC_ATOP );
97103 getResources ().getDrawable (R .drawable .ic_check )
98104 .setColorFilter (Color .BLACK , PorterDuff .Mode .SRC_ATOP );
105+ statusView .setTextColor (Color .BLACK );
106+ timerView .setTextColor (Color .BLACK );
107+ restartView .setColorFilter (Color .BLACK );
108+ recordView .setColorFilter (Color .BLACK );
109+ playView .setColorFilter (Color .BLACK );
99110 }
100111 }
101112
102113 @ Override
103114 public void onResume () {
104115 super .onResume ();
105- audioVisualizationView .onResume ();
116+ try {
117+ visualizerView .onResume ();
118+ } catch (Exception e ){ }
106119 }
107120
108121 @ Override
109122 protected void onPause () {
110123 stopRecording ();
111- audioVisualizationView .onPause ();
124+ try {
125+ visualizerView .onPause ();
126+ } catch (Exception e ){ }
112127 super .onPause ();
113128 }
114129
115130 @ Override
116131 protected void onDestroy () {
117132 setResult (RESULT_CANCELED );
118- audioVisualizationView .release ();
133+ try {
134+ visualizerView .release ();
135+ } catch (Exception e ){ }
119136 super .onDestroy ();
120137 }
121138
139+ @ Override
140+ protected void onSaveInstanceState (Bundle outState ) {
141+ outState .putString (AndroidAudioRecorder .EXTRA_FILE_PATH , filePath );
142+ outState .putInt (AndroidAudioRecorder .EXTRA_COLOR , color );
143+ super .onSaveInstanceState (outState );
144+ }
145+
122146 @ Override
123147 public boolean onCreateOptionsMenu (Menu menu ) {
124148 getMenuInflater ().inflate (R .menu .audio_recorder , menu );
@@ -144,64 +168,98 @@ public void onAudioChunkPulled(AudioChunk audioChunk) {
144168 visualizerHandler .onDataReceived (amplitude );
145169 }
146170
147- public void toggleRecording (View v ) {
148- if (isRecording ) {
149- stopRecording ();
150- } else {
151- startRecording ();
171+ @ Override
172+ public void onPrepared (final MediaPlayer mediaPlayer ) {
173+ if (mediaPlayer != null ){
174+
152175 }
153176 }
154177
178+ @ Override
179+ public void onCompletion (MediaPlayer mediaPlayer ) {
180+ stopPlaying ();
181+ }
182+
183+ private void selectAudio () {
184+ setResult (RESULT_OK );
185+ finish ();
186+ }
187+
188+ public void toggleRecording (View v ) {
189+ stopPlaying ();
190+ Util .wait (100 , new Runnable () {
191+ @ Override
192+ public void run () {
193+ if (isRecording ) {
194+ stopRecording ();
195+ } else {
196+ startRecording ();
197+ }
198+ }
199+ });
200+ }
201+
202+ public void togglePlaying (View v ){
203+ stopRecording ();
204+ Util .wait (100 , new Runnable () {
205+ @ Override
206+ public void run () {
207+ if (isPlaying ()){
208+ stopPlaying ();
209+ } else {
210+ startPlaying ();
211+ }
212+ }
213+ });
214+ }
215+
155216 public void restartRecording (View v ){
156217 stopRecording ();
218+ stopPlaying ();
157219 saveMenuItem .setVisible (false );
158220 restartView .setVisibility (View .INVISIBLE );
159221 playView .setVisibility (View .INVISIBLE );
160222 recordView .setImageResource (R .drawable .ic_rec );
161223 timerView .setText ("00:00:00" );
162- secondsRecorded = 0 ;
163- }
164-
165- public void playRecording (View v ){
166- // TODO play recorded audio
167- }
168-
169- private void selectAudio () {
170- setResult (RESULT_OK );
171- finish ();
224+ secondsElapsed = 0 ;
172225 }
173226
174227 private void startRecording () {
175228 isRecording = true ;
176229 saveMenuItem .setVisible (false );
230+ timerView .setText ("00:00:00" );
231+ statusView .setText (R .string .recording );
232+ statusView .setVisibility (View .VISIBLE );
177233 restartView .setVisibility (View .INVISIBLE );
178234 playView .setVisibility (View .INVISIBLE );
179235 recordView .setImageResource (R .drawable .ic_stop );
180- timerView .setText ("00:00:00" );
236+ playView .setImageResource (R .drawable .ic_play );
237+
238+ visualizerHandler = new VisualizerHandler ();
239+ visualizerView .linkTo (visualizerHandler );
181240
182241 recorder = OmRecorder .wav (
183- new PullTransport .Default (Util .getMic (), this ),
242+ new PullTransport .Default (Util .getMic (), AudioRecorderActivity . this ),
184243 new File (filePath ));
185244 recorder .startRecording ();
186245
187- secondsRecorded = 0 ;
188- timer = new Timer ();
189- timer .schedule (new TimerTask () {
190- @ Override
191- public void run () {
192- updateTimer ();
193- }
194- }, 0 , 1000 );
246+ startTimer ();
195247 }
196248
197249 private void stopRecording () {
198250 isRecording = false ;
199251 if (!isFinishing ()) {
200252 saveMenuItem .setVisible (true );
201253 }
254+ statusView .setText ("" );
255+ statusView .setVisibility (View .INVISIBLE );
256+ // TODO pause and restart recording before showing this button
202257// restartView.setVisibility(View.VISIBLE);
203- // playView.setVisibility(View.VISIBLE);
258+ playView .setVisibility (View .VISIBLE );
204259 recordView .setImageResource (R .drawable .ic_rec );
260+ playView .setImageResource (R .drawable .ic_play );
261+
262+ visualizerView .release ();
205263
206264 if (visualizerHandler != null ) {
207265 visualizerHandler .stop ();
@@ -212,18 +270,87 @@ private void stopRecording() {
212270 recorder = null ;
213271 }
214272
215- if (timer != null ) {
216- timer .cancel ();
273+ stopTimer ();
274+ }
275+
276+ private void startPlaying (){
277+ try {
278+ player = new MediaPlayer ();
279+ player .setDataSource (filePath );
280+ player .prepare ();
281+ player .start ();
282+
283+ visualizerView .linkTo (DbmHandler .Factory .newVisualizerHandler (this , player ));
284+ visualizerView .post (new Runnable () {
285+ @ Override
286+ public void run () {
287+ player .setOnCompletionListener (AudioRecorderActivity .this );
288+ }
289+ });
290+
291+ timerView .setText ("00:00:00" );
292+ statusView .setText (R .string .playing );
293+ statusView .setVisibility (View .VISIBLE );
294+ playView .setImageResource (R .drawable .ic_pause );
295+
296+ startTimer ();
297+ } catch (Exception e ){
298+ e .printStackTrace ();
217299 }
218300 }
219301
220- private void updateTimer () {
221- runOnUiThread (new Runnable () {
302+ private void stopPlaying (){
303+ statusView .setText ("" );
304+ statusView .setVisibility (View .INVISIBLE );
305+ playView .setImageResource (R .drawable .ic_play );
306+
307+ if (player != null ){
308+ try {
309+ player .stop ();
310+ player .reset ();
311+ player .release ();
312+ } catch (Exception e ){ }
313+ }
314+
315+ stopTimer ();
316+ }
317+
318+ private boolean isPlaying (){
319+ try {
320+ return player != null && player .isPlaying ();
321+ } catch (Exception e ){
322+ return false ;
323+ }
324+ }
325+
326+ private void startTimer (){
327+ stopTimer ();
328+ secondsElapsed = 0 ;
329+ timer = new Timer ();
330+ timer .scheduleAtFixedRate (new TimerTask () {
222331 @ Override
223332 public void run () {
224- secondsRecorded ++;
225- timerView .setText (Util .formatSeconds (secondsRecorded ));
333+ updateTimer ();
226334 }
227- });
335+ }, 0 , 1000 );
336+ }
337+
338+ private void stopTimer (){
339+ if (timer != null ) {
340+ timer .cancel ();
341+ timer .purge ();
342+ }
343+ }
344+
345+ private void updateTimer () {
346+ if (isRecording || isPlaying ()) {
347+ runOnUiThread (new Runnable () {
348+ @ Override
349+ public void run () {
350+ secondsElapsed ++;
351+ timerView .setText (Util .formatSeconds (secondsElapsed ));
352+ }
353+ });
354+ }
228355 }
229356}
0 commit comments