package org.commcare.views.widgets;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.provider.MediaStore.Audio;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import org.commcare.CommCareApplication;
import org.commcare.activities.components.FormEntryConstants;
import org.commcare.dalvik.R;
import org.commcare.logic.PendingCalloutInterface;
import org.commcare.utils.FileUtil;
import org.commcare.utils.StringUtils;
import org.commcare.utils.UriToFilePath;
import org.javarosa.form.api.FormEntryPrompt;
import java.io.File;
import java.io.IOException;
/**
* Widget that allows user to take pictures, sounds or video and add them to
* the form.
*
* @author Carl Hartung (carlhartung@gmail.com)
* @author Yaw Anokwa (yanokwa@gmail.com)
*/
public class AudioWidget extends MediaWidget {
private static final String TAG = AudioWidget.class.getSimpleName();
protected static final String CUSTOM_TAG = "custom";
protected String recordedFileName;
private String customFileTag;
public AudioWidget(Context context, final FormEntryPrompt prompt, PendingCalloutInterface pic) {
super(context, prompt, pic);
}
@Override
protected void initializeButtons(){
// setup capture button
mCaptureButton = new Button(getContext());
WidgetUtils.setupButton(mCaptureButton,
StringUtils.getStringSpannableRobust(getContext(), R.string.capture_audio),
mAnswerFontSize,
!mPrompt.isReadOnly());
// setup audio filechooser button
mChooseButton = new Button(getContext());
WidgetUtils.setupButton(mChooseButton,
StringUtils.getStringSpannableRobust(getContext(), R.string.choose_sound),
mAnswerFontSize,
!mPrompt.isReadOnly());
// setup play button
mPlayButton = new Button(getContext());
WidgetUtils.setupButton(mPlayButton,
StringUtils.getStringSpannableRobust(getContext(), R.string.play_audio),
mAnswerFontSize,
!mPrompt.isReadOnly());
// launch capture intent on click
mCaptureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
captureAudio(mPrompt);
}
});
// launch audio filechooser intent on click
mChooseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("audio/*");
try {
((Activity)getContext()).startActivityForResult(i, FormEntryConstants.AUDIO_VIDEO_FETCH);
pendingCalloutInterface.setPendingCalloutFormIndex(mPrompt.getIndex());
} catch (ActivityNotFoundException e) {
Toast.makeText(getContext(),
StringUtils.getStringSpannableRobust(getContext(),
R.string.activity_not_found,
"choose audio"),
Toast.LENGTH_SHORT).show();
}
}
});
if (QuestionWidget.ACQUIREFIELD.equalsIgnoreCase(mPrompt.getAppearanceHint())) {
mChooseButton.setVisibility(View.GONE);
}
// on play, launch the appropriate viewer
mPlayButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
playAudio();
}
});
}
protected void playAudio() {
Intent i = new Intent("android.intent.action.VIEW");
File f = new File(mInstanceFolder + mBinaryName);
i.setDataAndType(Uri.fromFile(f), "audio/*");
try {
getContext().startActivity(i);
} catch (ActivityNotFoundException e) {
Toast.makeText(getContext(),
StringUtils.getStringSpannableRobust(getContext(),
R.string.activity_not_found,
"play audio"),
Toast.LENGTH_SHORT).show();
}
}
protected void captureAudio(FormEntryPrompt prompt) {
Intent i = new Intent(Audio.Media.RECORD_SOUND_ACTION);
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
Audio.Media.EXTERNAL_CONTENT_URI.toString());
try {
((Activity)getContext()).startActivityForResult(i, FormEntryConstants.AUDIO_VIDEO_FETCH);
pendingCalloutInterface.setPendingCalloutFormIndex(prompt.getIndex());
} catch (ActivityNotFoundException e) {
Toast.makeText(getContext(),
StringUtils.getStringSpannableRobust(getContext(),
R.string.activity_not_found,
"audio capture"),
Toast.LENGTH_SHORT).show();
}
}
@Override
public void setBinaryData(Object binaryuri) {
String binaryPath = getBinaryPathWithSizeCheck(binaryuri);
if (binaryPath == null) {
return;
}
File source = new File(binaryPath);
// get the file path and create a copy in the instance folder
String[] filenameSegments = binaryPath.split("\\.");
String extension = "";
if (filenameSegments.length > 1) {
extension = "." + filenameSegments[filenameSegments.length - 1];
}
String[] filePathSegments = binaryPath.split("/");
if(filePathSegments.length >1){
recordedFileName = filePathSegments[filePathSegments.length-1];
}
String destAudioPath = mInstanceFolder + System.currentTimeMillis() + customFileTag + extension;
File newAudio = new File(destAudioPath);
try {
FileUtil.copyFile(source, newAudio);
}catch (IOException e) {
Log.e(TAG, "IOExeception while copying audio");
e.printStackTrace();
}
if (newAudio.exists()) {
// Add the copy to the content provider
ContentValues values = new ContentValues(6);
values.put(Audio.Media.TITLE, newAudio.getName());
values.put(Audio.Media.DISPLAY_NAME, newAudio.getName());
values.put(Audio.Media.DATE_ADDED, System.currentTimeMillis());
values.put(Audio.Media.DATA, newAudio.getAbsolutePath());
Uri audioUri =
getContext().getContentResolver().insert(Audio.Media.EXTERNAL_CONTENT_URI, values);
String audioUriString = audioUri == null ? "null" : audioUri.toString();
Log.i(TAG, "Inserting AUDIO returned uri = " + audioUriString);
} else {
Log.e(TAG, "Inserting Audio file FAILED");
}
mBinaryName = newAudio.getName();
}
/**
* If file is chosen by user, the file selection intent will return an URI
* If file is auto-selected after recording_fragment, then the recordingfragment will provide a string file path
* Set value of customFileTag if the file is a recent recording from the RecordingFragment
*/
@Override
protected String createFilePath(Object binaryuri){
String path;
if(binaryuri instanceof Uri){
path = UriToFilePath.getPathFromUri(CommCareApplication.instance(),
(Uri)binaryuri);
customFileTag = "";
}else{
path = (String) binaryuri;
customFileTag = CUSTOM_TAG;
}
return path;
}
}