package org.commcare.views.widgets;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.content.DialogInterface;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.commcare.dalvik.R;
import org.commcare.google.services.analytics.GoogleAnalyticsUtils;
import org.javarosa.core.services.locale.Localization;
import java.io.File;
import java.io.IOException;
/**
* A popup dialog fragment that handles recording_fragment and saving of audio
* files without external callout.
*
* @author Saumya Jain (sjain@dimagi.com)
*/
public class RecordingFragment extends android.support.v4.app.DialogFragment {
private String fileName;
private static final String FILE_BASE =
"/Android/data/org.commcare.dalvik/temp/Custom_Recording";
private static final String FILE_EXT = ".mp4";
private LinearLayout layout;
private ImageButton toggleRecording;
private Button saveRecording;
private Button recordAgain;
private TextView instruction;
private ProgressBar recordingProgress;
private Chronometer recordingDuration;
private long currentTimeMillis;
private MediaRecorder recorder;
private RecordingCompletionListener listener;
private MediaPlayer player;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
layout = (LinearLayout)inflater.inflate(R.layout.recording_fragment, container);
disableScreenRotation((Activity)getContext());
prepareButtons();
prepareText();
setWindowSize();
fileName = Environment.getExternalStorageDirectory().getAbsolutePath() + FILE_BASE + listener.getFileUniqueIdentifier() + FILE_EXT;
File f = new File(fileName);
if (f.exists()) {
reloadSavedRecording();
}
return layout;
}
private void reloadSavedRecording() {
recordAgain.setVisibility(View.VISIBLE);
saveRecording.setVisibility(View.VISIBLE);
recordingDuration.setVisibility(View.VISIBLE);
toggleRecording.setBackgroundResource(R.drawable.play);
toggleRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playAudio();
}
});
saveRecording.setEnabled(true);
instruction.setText(Localization.get("after.recording"));
}
private void setWindowSize() {
Rect displayRectangle = new Rect();
Window window = getActivity().getWindow();
window.getDecorView().getWindowVisibleDisplayFrame(displayRectangle);
layout.setMinimumWidth((int)(displayRectangle.width() * 0.9f));
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
}
private void prepareText() {
TextView header = (TextView)layout.findViewById(R.id.recording_header);
header.setText(Localization.get("recording.header"));
instruction = (TextView)layout.findViewById(R.id.recording_instruction);
instruction.setText(Localization.get("before.recording"));
recordingDuration = (Chronometer)layout.findViewById(R.id.recording_time);
}
private void prepareButtons() {
ImageButton discardRecording = (ImageButton)layout.findViewById(R.id.discardrecording);
toggleRecording = (ImageButton)layout.findViewById(R.id.startrecording);
saveRecording = (Button)layout.findViewById(R.id.saverecording);
recordAgain = (Button)layout.findViewById(R.id.recycle);
recordAgain.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
resetRecordingView();
}
});
discardRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
toggleRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GoogleAnalyticsUtils.reportRecordingStarted();
startRecording();
}
});
saveRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GoogleAnalyticsUtils.reportAudioFileSaved();
saveRecording();
}
});
saveRecording.setText(Localization.get("save"));
recordingProgress = (ProgressBar)layout.findViewById(R.id.demo_mpc);
}
private void resetRecordingView() {
if (recorder != null) {
recorder.release();
recorder = null;
}
if (player != null) {
resetAudioPlayer();
}
toggleRecording.setBackgroundResource(R.drawable.record_start);
toggleRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startRecording();
}
});
instruction.setText(Localization.get("before.recording"));
saveRecording.setVisibility(View.INVISIBLE);
recordAgain.setVisibility(View.INVISIBLE);
recordingDuration.setVisibility(View.INVISIBLE);
GoogleAnalyticsUtils.reportRecordingRecycled();
}
private void startRecording() {
disableScreenRotation((Activity)getContext());
setCancelable(false);
setupRecorder();
recorder.start();
toggleRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GoogleAnalyticsUtils.reportRecordingStopped();
stopRecording();
}
});
toggleRecording.setBackgroundResource(R.drawable.record_in_progress);
instruction.setText(Localization.get("during.recording"));
recordingProgress.setVisibility(View.VISIBLE);
recordingDuration.setVisibility(View.VISIBLE);
recordingDuration.setBase(SystemClock.elapsedRealtime());
recordingDuration.start();
}
private void setupRecorder() {
if (recorder == null) {
recorder = new MediaRecorder();
}
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setOutputFile(fileName);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
recorder.prepare();
} catch (IOException e) {
Log.d("Recorder", "Failed to prepare media recorder");
}
}
private void stopRecording() {
recordingDuration.stop();
recordAgain.setVisibility(View.VISIBLE);
recordingProgress.setVisibility(View.INVISIBLE);
recorder.stop();
toggleRecording.setBackgroundResource(R.drawable.play);
toggleRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playAudio();
GoogleAnalyticsUtils.reportAudioPlayed();
}
});
saveRecording.setEnabled(true);
saveRecording.setVisibility(View.VISIBLE);
instruction.setText(Localization.get("after.recording"));
}
private void saveRecording() {
if (listener != null) {
listener.onRecordingCompletion();
}
dismiss();
}
public interface RecordingCompletionListener {
void onRecordingCompletion();
String getFileUniqueIdentifier();
}
public void setListener(RecordingCompletionListener listener) {
this.listener = listener;
}
@Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
enableScreenRotation((Activity)getContext());
if (recorder != null) {
recorder.release();
this.recorder = null;
}
if (player != null) {
try {
player.release();
} catch (IllegalStateException e) {
//Do nothing because player wasn't recording
}
}
}
public String getFileName() {
return fileName;
}
private static void disableScreenRotation(Activity context) {
int currentOrientation = context.getResources().getConfiguration().orientation;
if (currentOrientation == Configuration.ORIENTATION_LANDSCAPE) {
context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
} else {
context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
}
}
private static void enableScreenRotation(Activity context) {
context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
private void playAudio() {
Uri myPath = Uri.parse(fileName);
player = MediaPlayer.create(getContext(), myPath);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
resetAudioPlayer();
}
});
recordingDuration.setBase(SystemClock.elapsedRealtime());
recordingDuration.start();
player.start();
toggleRecording.setBackgroundResource(R.drawable.pause);
toggleRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GoogleAnalyticsUtils.reportAudioPaused();
pauseAudioPlayer();
}
});
}
private void pauseAudioPlayer() {
player.pause();
recordingDuration.stop();
currentTimeMillis = recordingDuration.getBase();
toggleRecording.setBackgroundResource(R.drawable.play);
toggleRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GoogleAnalyticsUtils.reportAudioPlayed();
resumeAudioPlayer();
}
});
}
private void resumeAudioPlayer() {
recordingDuration.setBase(currentTimeMillis);
recordingDuration.start();
player.start();
toggleRecording.setBackgroundResource(R.drawable.pause);
toggleRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GoogleAnalyticsUtils.reportAudioPaused();
pauseAudioPlayer();
}
});
}
private void resetAudioPlayer() {
player.release();
recordingDuration.stop();
toggleRecording.setBackgroundResource(R.drawable.play);
toggleRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GoogleAnalyticsUtils.reportAudioPlayed();
playAudio();
}
});
}
}