Skip to content

Commit 4324f66

Browse files
Making the soundrecorder nicer
1 parent 988b12d commit 4324f66

20 files changed

Lines changed: 229 additions & 453 deletions

app/src/main/java/org/open311/android/MainActivity.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,22 @@ private void setupViewPager(ViewPager viewPager) {
186186
adapter.addFragment(new ProfileFragment());
187187
adapter.addFragment(new PolicyFragment());
188188
viewPager.setAdapter(adapter);
189+
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener(){
190+
@Override
191+
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
192+
193+
}
194+
195+
@Override
196+
public void onPageSelected(int position) {
197+
hideKeyBoard(MainActivity.this);
198+
}
199+
200+
@Override
201+
public void onPageScrollStateChanged(int state) {
202+
203+
}
204+
});
189205
}
190206

191207
@Override

app/src/main/java/org/open311/android/SoundRecorderActivity.java

Lines changed: 34 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
import android.media.MediaRecorder;
66
import android.net.Uri;
77
import android.os.Bundle;
8+
import android.os.SystemClock;
9+
import android.support.design.widget.FloatingActionButton;
10+
import android.support.v4.content.ContextCompat;
11+
import android.text.format.DateFormat;
812
import android.util.Log;
913
import android.view.View;
10-
import android.widget.Button;
11-
import android.widget.ImageButton;
14+
import android.widget.Chronometer;
1215
import android.widget.LinearLayout;
1316
import android.widget.ProgressBar;
14-
import android.widget.SeekBar;
1517
import android.widget.TextView;
1618

1719
import java.io.FileDescriptor;
@@ -30,21 +32,14 @@ public class SoundRecorderActivity extends Activity {
3032
Uri mOutputUri;
3133
FileDescriptor mOutputFileDescriptor;
3234

33-
LinearLayout mSoundRecorderLayout;
34-
3535
// Views for recording
3636
ProgressBar mRecordAudioProgressBar;
37-
ImageButton mPlaybackPlayPauseButton;
38-
3937
// Views for playback
40-
SeekBar mAudioSeekBar;
41-
Button mRecordAudioCancelButton;
42-
ImageButton mRecordAudioPlayButton;
38+
Chronometer mAudioSeekBar;
4339

4440
// Views for both
45-
Button mRecordAudioControlButton;
46-
TextView mCurrentRecordTimeCurrentTextView;
47-
TextView mCurrentRecordTimeMaxTextView;
41+
FloatingActionButton mRecordAudioControlButton;
42+
TextView mRecordingStatus;
4843
Timer mProgressTimer;
4944

5045
// Recorder stuff
@@ -114,16 +109,12 @@ private void setup() {
114109

115110
private void setupViews() {
116111
Log.d(LOG_TAG, "setupViews");
117-
mSoundRecorderLayout = (LinearLayout) findViewById(R.id.sound_recorder_layout);
118112

119113
mRecordAudioProgressBar = (ProgressBar) findViewById(R.id.record_audio_progress);
120-
mAudioSeekBar = (SeekBar) findViewById(R.id.audio_seekbar);
121-
122-
mRecordAudioControlButton = (Button) findViewById(R.id.record_audio_control_button);
123-
mRecordAudioCancelButton = (Button) findViewById(R.id.record_audio_cancel_button);
124-
125-
mCurrentRecordTimeCurrentTextView = (TextView) findViewById(R.id.record_audio_time_current);
126-
mCurrentRecordTimeMaxTextView = (TextView) findViewById(R.id.record_audio_time_max);
114+
mRecordAudioProgressBar.setMax(MAX_DURATION_MS);
115+
mAudioSeekBar = (Chronometer) findViewById(R.id.record_audio_seekbar);
116+
mRecordAudioControlButton = (FloatingActionButton) findViewById(R.id.record_audio_control_button);
117+
mRecordingStatus = (TextView) findViewById((R.id.recording_status_text));
127118

128119
mOnClickListener = new View.OnClickListener() {
129120
@Override
@@ -138,101 +129,30 @@ public void onClick(View v) {
138129
tearDownRecording(false);
139130
break;
140131
case STOPPED:
132+
setupRecorder();
133+
startRecording();
134+
break;
135+
default:
141136
completeRecording();
142137
break;
143138
}
144139
break;
145-
146-
case R.id.record_audio_cancel_button:
147-
onCancel();
148-
break;
149140
}
150141
}
151142
};
152143

153144
mRecordAudioControlButton.setOnClickListener(mOnClickListener);
154-
mRecordAudioCancelButton.setOnClickListener(mOnClickListener);
155-
156-
mAudioSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
157-
@Override
158-
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
159-
mCurrentRecordTimeCurrentTextView.setText(getTimeString(progress));
160-
}
161-
162-
@Override
163-
public void onStartTrackingTouch(SeekBar seekBar) {
164-
165-
}
166145

146+
mAudioSeekBar.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
167147
@Override
168-
public void onStopTrackingTouch(SeekBar seekBar) {
148+
public void onChronometerTick(Chronometer chronometer) {
149+
long t = SystemClock.elapsedRealtime() - chronometer.getBase();
169150

151+
mRecordAudioProgressBar.setProgress((int) t);
152+
chronometer.setText(DateFormat.format("mm:ss", t));
170153
}
171-
172154
});
173155

174-
mRecordAudioProgressBar.setMax(MAX_DURATION_MS);
175-
}
176-
177-
private void setCurrentRecordingState(RecordingState recordingState) {
178-
Log.i(LOG_TAG, "setCurrentRecordingState: " + recordingState);
179-
180-
mCurrentRecordingState = recordingState;
181-
}
182-
183-
private void setupProgressTimer() {
184-
mProgressTimer = new Timer();
185-
}
186-
187-
private void startProgressTimer() {
188-
if (mProgressTimer == null) {
189-
setupProgressTimer();
190-
}
191-
192-
mProgressTimer.schedule(new TimerTask() {
193-
194-
@Override
195-
public void run() {
196-
runOnUiThread(new Runnable() {
197-
@Override
198-
public void run() {
199-
int nextMilliSeconds;
200-
201-
if (mCurrentRecordingState == RecordingState.STARTED) {
202-
if (mRecordAudioProgressBar.getProgress() < MAX_DURATION_MS) {
203-
nextMilliSeconds = mRecordAudioProgressBar.getProgress() + getProgressIncrement(mRecordAudioProgressBar.getProgress());
204-
205-
Log.i(LOG_TAG, "Recording progress " + nextMilliSeconds);
206-
207-
mRecordAudioProgressBar.setProgress(nextMilliSeconds);
208-
mCurrentRecordTimeCurrentTextView.setText(getTimeString(nextMilliSeconds));
209-
} else {
210-
//Reached maximum duration. Stopping.
211-
tearDownRecording(false);
212-
}
213-
} else if (mCurrentRecordingState == RecordingState.STOPPED) {
214-
if (mAudioSeekBar.getProgress() < MAX_DURATION_MS) {
215-
nextMilliSeconds = mAudioSeekBar.getProgress() + getProgressIncrement(mAudioSeekBar.getProgress());
216-
217-
Log.i(LOG_TAG, "Recording progress " + nextMilliSeconds);
218-
219-
mAudioSeekBar.setProgress(nextMilliSeconds);
220-
mCurrentRecordTimeCurrentTextView.setText(getTimeString(nextMilliSeconds));
221-
}
222-
}
223-
}
224-
});
225-
}
226-
}, 0, 1000);
227-
}
228-
229-
private void stopProgressTimer() {
230-
if (mProgressTimer != null) {
231-
mProgressTimer.cancel();
232-
mProgressTimer.purge();
233-
}
234-
235-
mProgressTimer = null;
236156
}
237157

238158
private void setupRecorder() {
@@ -247,70 +167,48 @@ private void setupRecorder() {
247167
mMediaRecorder.setMaxDuration(MAX_DURATION_MS);
248168
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
249169
mMediaRecorder.setOutputFile(mOutputFileDescriptor);
250-
251-
170+
mAudioSeekBar.setBase(SystemClock.elapsedRealtime());
252171
try {
253172
mMediaRecorder.prepare();
254-
255-
onSetupRecorder();
173+
mCurrentRecordingState = RecordingState.NOT_STARTED;
256174
} catch (IOException exception) {
257175
Log.e(LOG_TAG, "Recording preparation failed", exception);
258176
finish();
259177
}
260178
}
261179

262-
private void onSetupRecorder() {
263-
setCurrentRecordingState(RecordingState.NOT_STARTED);
264-
}
265-
266180
private void startRecording() {
267181
try {
268182
mMediaRecorder.start();
269-
270-
onStartRecording();
183+
mCurrentRecordingState = RecordingState.STARTED;
184+
mRecordAudioControlButton.setImageDrawable(ContextCompat.getDrawable(SoundRecorderActivity.this.getApplication().getBaseContext(), R.drawable.ic_stop));
185+
mAudioSeekBar.start();
186+
mRecordAudioProgressBar.setVisibility(View.VISIBLE);
271187
} catch (IllegalStateException exception) {
272188
Log.e(LOG_TAG, "Bad state when starting recording", exception);
273189
}
274190
}
275191

276-
private void onStartRecording() {
277-
Log.i(LOG_TAG, "Recording started");
278-
279-
setCurrentRecordingState(RecordingState.STARTED);
280-
281-
mRecordAudioControlButton.setText(R.string.stop_dialog);
282-
mRecordAudioProgressBar.setVisibility(View.VISIBLE);
283-
startProgressTimer();
284-
}
285-
286192
private void stopRecording() {
287193
try {
288194
mMediaRecorder.stop();
195+
mAudioSeekBar.stop();
289196

290197
} catch (IllegalStateException exception) {
291198
Log.e(LOG_TAG, "Bad state when stopping recording (ignoring)", exception);
292199
} catch (RuntimeException exception) {
293200
Log.e(LOG_TAG, "Exception when stopping recording (ignoring)", exception);
294201
}
295202

296-
onStopRecording();
297-
}
298-
299-
private void onStopRecording() {
300203
Log.i(LOG_TAG, "Recording stopped");
301-
302-
setCurrentRecordingState(RecordingState.STOPPED);
303-
304-
stopProgressTimer();
204+
mCurrentRecordingState = RecordingState.STOPPED;
205+
mRecordAudioControlButton.setImageDrawable(ContextCompat.getDrawable(SoundRecorderActivity.this.getApplication().getBaseContext(), R.drawable.ic_mic_white_24dp));
305206
}
306207

208+
307209
private void completeRecording() {
308210
Log.d(LOG_TAG, "completeRecording");
309211
tearDownRecording(true);
310-
onCompleteRecording();
311-
}
312-
313-
private void onCompleteRecording() {
314212
Intent returnIntent = new Intent();
315213
returnIntent.setData(mOutputUri);
316214
setResult(RESULT_OK, returnIntent);
@@ -335,59 +233,15 @@ private void tearDownRecording(boolean fromCancellation) {
335233
}
336234

337235
if (!fromCancellation) {
338-
mRecordAudioControlButton.setText(R.string.okay);
339-
mRecordAudioProgressBar.setVisibility(View.INVISIBLE);
340-
mAudioSeekBar.setVisibility(View.VISIBLE);
341-
mAudioSeekBar.setProgress(0);
236+
mRecordingStatus.setText(R.string.record_ready);
342237
}
343238
}
344239

345-
private void onCancel() {
346-
tearDownRecording(true);
347-
finish();
348-
}
349-
350-
private String getTimeString(int miliSeconds) {
351-
int minutes = (int) Math.floor((miliSeconds / 1000.0) / 60);
352-
int seconds = miliSeconds / 1000 - minutes * 60;
353-
354-
return String.format("%01d:%02d", minutes, seconds);
355-
}
356-
357-
private int getNumIncrements(int durationMiliSeconds) {
358-
int numIncrements = (int) Math.ceil(durationMiliSeconds / 1000.0);
359-
360-
if (numIncrements == 0) {
361-
return 1;
362-
}
363-
364-
return numIncrements;
365-
}
366-
367-
private int getMaxDuration(int durationMiliSeconds) {
368-
int numIncrements = getNumIncrements(durationMiliSeconds) * 1000;
369-
370-
if (numIncrements > MAX_DURATION_MS) {
371-
numIncrements = MAX_DURATION_MS;
372-
}
373-
374-
return numIncrements;
375-
}
376-
377-
private int getProgressIncrement(int durationMiliSeconds) {
378-
int numIncrements = getNumIncrements(durationMiliSeconds);
379-
380-
if (numIncrements == 1) {
381-
return 1000;
382-
}
383-
384-
return Math.round(durationMiliSeconds / numIncrements);
385-
}
386-
387240
@Override
388241
protected void onDestroy() {
389242
super.onDestroy();
390243

391-
onCancel();
244+
tearDownRecording(true);
245+
finish();
392246
}
393247
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.open311.android.adapters;
2+
3+
/**
4+
* Created by miblon on 11/12/16.
5+
*/
6+
7+
public class ServiceListAdapter {
8+
}

app/src/main/java/org/open311/android/fragments/PolicyFragment.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212

1313
/**
1414
* Policy {@link Fragment} subclass.
15-
*
1615
*/
1716
public class PolicyFragment extends Fragment {
1817
private static final String LOG_TAG = "PolicyFragment";
18+
1919
public PolicyFragment() {
2020
// Required empty public constructor
2121
}

0 commit comments

Comments
 (0)