/* * The MIT License (MIT) * * Copyright � 2013 Clover Studio Ltd. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.cloverstudio.spikademo; import java.io.File; import java.io.IOException; import java.util.concurrent.ExecutionException; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Typeface; import android.media.MediaPlayer; import android.os.Bundle; import android.os.CountDownTimer; import android.os.Environment; import android.os.Handler; import android.os.SystemClock; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.animation.AlphaAnimation; import android.widget.Button; import android.widget.Chronometer; import android.widget.EditText; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; import com.cloverstudio.spikademo.R; import com.cloverstudio.spikademo.couchdb.CouchDB; import com.cloverstudio.spikademo.dialog.HookUpAlertDialog; import com.cloverstudio.spikademo.dialog.HookUpDialog; import com.cloverstudio.spikademo.dialog.HookUpProgressDialog; import com.cloverstudio.spikademo.dialog.HookUpAlertDialog.ButtonType; import com.cloverstudio.spikademo.extendables.SpikaActivity; import com.cloverstudio.spikademo.extendables.SpikaAsync; import com.cloverstudio.spikademo.lazy.ImageLoader; import com.cloverstudio.spikademo.management.UsersManagement; import com.cloverstudio.spikademo.messageshandling.SendMessageAsync; import com.cloverstudio.spikademo.utils.Const; import com.cloverstudio.spikademo.utils.ExtAudioRecorder; import com.cloverstudio.spikademo.utils.LayoutHelper; import com.cloverstudio.spikademo.utils.Logger; import com.cloverstudio.spikademo.utils.Utils; /** * RecordingActivity * * Records a voice message. */ @SuppressLint("DefaultLocale") public class RecordingActivity extends SpikaActivity { private static int START_PLAYING = 0; private static int PAUSE_PLAYING = 1; private static int STOP_PLAYING = 2; private static int PLAYING = 2; private static int PAUSE = 1; private static int STOP = 0; private boolean mIsRecording; private static String sFileName = null; private ExtAudioRecorder mExtAudioRecorder; private Chronometer mRecordTime; private TextView mRecordingText; private Handler mHandlerForProgressBar = new Handler(); private Runnable mRunnForProgressBar; private int mIsPlaying = STOP; // 0 - play is on stop, 1 - play is on pause, // 2 - playing private MediaPlayer mPlayer = null; private ProgressBar mPbForPlaying; private ImageView mPlayPause; private ImageView mStopSound; private RelativeLayout mRlSoundControler; private Button mBtnSend; private Button mBtnRecording; private EditText mEtNameOfUserVoice; private CountDownTimer mRecordingTimer; private HookUpAlertDialog mRecordingDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_recording); mRecordingDialog = new HookUpAlertDialog(this); mRecordingTimer = new CountDownTimer(Const.MAX_RECORDING_TIME_VOICE, 1000) { public void onTick(long millisUntilFinished) { } public void onFinish() { mRecordingDialog.show(getString(R.string.exceed_voice_duration), ButtonType.OK); onRecord(false); } }; Button back = (Button) findViewById(R.id.btnBack); back.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { finish(); } }); TextView tvTitle = (TextView) findViewById(R.id.tvTitle); tvTitle.setText("VOICE"); ImageView ivAvatar = (ImageView) findViewById(R.id.ivAvatarVoice); LayoutHelper.scaleWidthAndHeightRelativeLayout(this, 5f, ivAvatar); Utils.displayImage(UsersManagement.getLoginUser().getAvatarFileId(), ivAvatar, ImageLoader.SMALL, R.drawable.user_stub, false); mEtNameOfUserVoice = (EditText) findViewById(R.id.etNameOfUserVoice); mBtnRecording = (Button) findViewById(R.id.btnRecording); mRecordTime = (Chronometer) findViewById(R.id.recordTime); mRecordingText = (TextView) findViewById(R.id.tvRecording); mRlSoundControler = (RelativeLayout) findViewById(R.id.soundControler); mBtnSend = (Button) findViewById(R.id.btnSend); mBtnSend.setTypeface(SpikaApp.getTfMyriadProBold(), Typeface.BOLD); mPbForPlaying = (ProgressBar) findViewById(R.id.pbVoice); mPlayPause = (ImageView) findViewById(R.id.ivPlayPause); mStopSound = (ImageView) findViewById(R.id.ivStopSound); mBtnRecording.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mIsRecording) { onRecord(!mIsRecording); } else { hideAndRestartSoundController(); mIsRecording = true; onRecord(mIsRecording); } } }); } private void onRecord(boolean start) { if (start) { startRecording(); mBtnRecording .setBackgroundResource(R.drawable.icon_microphone_rec_selector); } else { stopRecording(); mBtnRecording .setBackgroundResource(R.drawable.icon_microphone_selector); } } private void startRecording() { mRecordTime.setVisibility(View.VISIBLE); mRecordTime.setBase(SystemClock.elapsedRealtime()); mRecordTime.start(); mRecordingText.setText("RECORDING..."); setRecordingFile(); mExtAudioRecorder = ExtAudioRecorder.getInstanse(false); mExtAudioRecorder.setOutputFile(sFileName); mExtAudioRecorder.prepare(); mExtAudioRecorder.start(); mRecordingTimer.start(); } // stop recodrding for extaudio class private void stopRecording() { mExtAudioRecorder.stop(); mExtAudioRecorder.release(); mRecordTime.stop(); mRecordTime.setVisibility(View.INVISIBLE); applyAlphaAnimationToView(mRecordTime, true); mRecordingText.setText("RECORDING DONE"); showSoundController(); mIsRecording = false; mRecordingTimer.cancel(); } private void hideAndRestartSoundController() { mRlSoundControler.setVisibility(View.INVISIBLE); mBtnSend.setVisibility(View.INVISIBLE); mPbForPlaying.setProgress(0); mRecordTime.setVisibility(View.INVISIBLE); mRecordingText.setText("RECORDING..."); mPlayPause.setBackgroundResource(R.drawable.play_btn); if (mPlayer != null) { mPlayer.stop(); mPlayer.release(); mPlayer = null; } } private void showSoundController() { mBtnSend.setVisibility(View.VISIBLE); applyAlphaAnimationToView(mBtnSend, false); mBtnSend.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Log.d("LOG", sFileName); new FileUploadAsync(RecordingActivity.this).execute(sFileName); } }); mIsPlaying = STOP; mPlayPause.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mIsPlaying == PLAYING) { // pause mPlayPause.setImageResource(R.drawable.play_btn); onPlay(PAUSE_PLAYING); } else { // play mPlayPause.setImageResource(R.drawable.pause_btn); onPlay(START_PLAYING); } } }); mStopSound.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mIsPlaying == PLAYING || mIsPlaying == PAUSE) { // stop mPlayPause.setImageResource(R.drawable.play_btn); onPlay(STOP_PLAYING); } } }); mRlSoundControler.setVisibility(View.VISIBLE); } private void onPlay(int playPauseStop) { // 0 is to start playing, 1 is to // pause playing and 2 is for // stop playing if (playPauseStop == START_PLAYING) { startPlaying(); } else if (playPauseStop == PAUSE_PLAYING) { pausePlaying(); } else { stopPlaying(); } } private void startPlaying() { if (mIsPlaying == STOP) { mPlayer = new MediaPlayer(); try { mPlayer.setDataSource(sFileName); mPlayer.prepare(); mPlayer.start(); mPbForPlaying.setMax((int) mPlayer.getDuration()); mRunnForProgressBar = new Runnable() { @Override public void run() { mPbForPlaying.setProgress((int) mPlayer .getCurrentPosition()); if (mPlayer.getDuration() - 99 > mPlayer .getCurrentPosition()) { mHandlerForProgressBar.postDelayed( mRunnForProgressBar, 100); } else { mPbForPlaying.setProgress((int) mPlayer .getDuration()); } } }; mHandlerForProgressBar.post(mRunnForProgressBar); mIsPlaying = PLAYING; } catch (IOException e) { Log.e("LOG", "prepare() failed"); } } else if (mIsPlaying == PAUSE) { mPlayer.start(); mHandlerForProgressBar.post(mRunnForProgressBar); mIsPlaying = PLAYING; } } private void stopPlaying() { mPlayer.release(); mHandlerForProgressBar.removeCallbacks(mRunnForProgressBar); mPbForPlaying.setProgress(0); mPlayer = null; mIsPlaying = STOP; } private void pausePlaying() { mPlayer.pause(); mHandlerForProgressBar.removeCallbacks(mRunnForProgressBar); mIsPlaying = PAUSE; } private void setRecordingFile() { File audio = getFileDir(getApplicationContext()); audio.mkdirs(); sFileName = audio.getAbsolutePath() + "/voice.wav"; Log.d("Dir:", sFileName); } private File getFileDir(Context context) { File cacheDir = null; if (Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED)) cacheDir = new File( android.os.Environment.getExternalStorageDirectory(), "HookUp"); else cacheDir = context.getCacheDir(); if (!cacheDir.exists()) cacheDir.mkdirs(); return cacheDir; } public void onPause() { super.onPause(); if (mExtAudioRecorder != null) { stopRecording(); mExtAudioRecorder.release(); mExtAudioRecorder.stop(); mExtAudioRecorder = null; } if (mPlayer != null) { mPlayer.release(); mPlayer = null; mIsPlaying = STOP; mPbForPlaying.setProgress(0); mPlayPause.setImageResource(R.drawable.play_btn); } mHandlerForProgressBar.removeCallbacks(mRunnForProgressBar); } public void onFinish() { super.onDestroy(); if (mExtAudioRecorder != null) { mExtAudioRecorder.release(); mExtAudioRecorder.stop(); mExtAudioRecorder = null; } if (mPlayer != null) { mPlayer.release(); mPlayer = null; mIsPlaying = STOP; mPbForPlaying.setProgress(0); mPlayPause.setImageResource(R.drawable.play_btn); } mHandlerForProgressBar.removeCallbacks(mRunnForProgressBar); } private void applyAlphaAnimationToView(View view, boolean toDisapear) { AlphaAnimation animation; if (!toDisapear) { animation = new AlphaAnimation(0.0f, 1.0f); } else { animation = new AlphaAnimation(1.0f, 0.0f); } animation.setDuration(200); view.startAnimation(animation); } @Override protected void checkIfAppIsInForeground() { SpikaApp.gOpenFromBackground = false; } private class FileUploadAsync extends SpikaAsync<String, Void, String> { private HookUpProgressDialog mProgressDialog; protected FileUploadAsync(Context context) { super(context); } @Override protected void onPreExecute() { super.onPreExecute(); if (mProgressDialog == null) { mProgressDialog = new HookUpProgressDialog( RecordingActivity.this); } mProgressDialog.show(); } @Override protected String doInBackground(String... params) { String filePath = params[0]; String fileId = CouchDB.uploadFile(filePath); return fileId; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); if (result != null) { } else { } if (mProgressDialog.isShowing()) mProgressDialog.dismiss(); String voiceSubject = mEtNameOfUserVoice.getText().toString(); if (voiceSubject.equals(null) || voiceSubject.equals("")) { voiceSubject = ""; } try { new SendMessageAsync(getApplicationContext(), SendMessageAsync.TYPE_VOICE).execute(voiceSubject, false, false, result).get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } finish(); } } @Override protected void onDestroy() { mRecordingTimer.cancel(); mRecordingTimer = null; super.onDestroy(); } }