package cn.jiguang.imui.chatinput;
import android.Manifest;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.Space;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Locale;
import cn.jiguang.imui.chatinput.camera.CameraNew;
import cn.jiguang.imui.chatinput.camera.CameraOld;
import cn.jiguang.imui.chatinput.camera.CameraSupport;
import cn.jiguang.imui.chatinput.listener.OnCameraCallbackListener;
import cn.jiguang.imui.chatinput.listener.OnFileSelectedListener;
import cn.jiguang.imui.chatinput.listener.OnMenuClickListener;
import cn.jiguang.imui.chatinput.model.FileItem;
import cn.jiguang.imui.chatinput.model.VideoItem;
import cn.jiguang.imui.chatinput.photo.SelectPhotoView;
import cn.jiguang.imui.chatinput.record.ProgressButton;
import cn.jiguang.imui.chatinput.record.RecordControllerView;
import cn.jiguang.imui.chatinput.record.RecordVoiceButton;
public class ChatInputView extends LinearLayout
implements View.OnClickListener, TextWatcher, RecordControllerView.OnRecordActionListener,
OnFileSelectedListener {
public static final byte KEYBOARD_STATE_SHOW = -3;
public static final byte KEYBOARD_STATE_HIDE = -2;
public static final byte KEYBOARD_STATE_INIT = -1;
public static final int REQUEST_CODE_TAKE_PHOTO = 0x0001;
public static final int REQUEST_CODE_SELECT_PHOTO = 0x0002;
private EditText mChatInput;
private TextView mSendCountTv;
private CharSequence mInput;
private Space mInputMarginLeft;
private Space mInputMarginRight;
private ImageButton mVoiceBtn;
private ImageButton mPhotoBtn;
private ImageButton mCameraBtn;
private ImageButton mSendBtn;
private LinearLayout mChatInputContainer;
private LinearLayout mMenuItemContainer;
private FrameLayout mMenuContainer;
private RelativeLayout mRecordVoiceRl;
private LinearLayout mPreviewPlayLl;
private ProgressButton mPreviewPlayBtn;
private Button mSendAudioBtn;
private Button mCancelSendAudioBtn;
private LinearLayout mRecordContentLl;
private RecordControllerView mRecordControllerView;
private Chronometer mChronometer;
private TextView mRecordHintTv;
private RecordVoiceButton mRecordVoiceBtn;
SelectPhotoView mSelectPhotoView;
private FrameLayout mCameraFl;
private TextureView mTextureView;
private ImageButton mCaptureBtn;
private ImageButton mCloseBtn;
private ImageButton mSwitchCameraBtn;
private ImageButton mFullScreenBtn;
private ImageButton mRecordVideoBtn;
private OnMenuClickListener mListener;
private OnCameraCallbackListener mCameraListener;
private ChatInputStyle mStyle;
private InputMethodManager mImm;
private Window mWindow;
private int mLastClickId = 0;
private int mWidth;
private int mHeight;
public static int sMenuHeight = 800;
private boolean mShowSoftInput = false;
private long mRecordTime;
private boolean mPlaying = false;
private MediaPlayer mMediaPlayer = new MediaPlayer();
// To judge if it is record video mode
private boolean mIsRecordVideoMode = false;
// To judge if it is recording video now
private boolean mIsRecordingVideo = false;
// To judge if is finish recording video
private boolean mFinishRecordingVideo = false;
// Video file to be saved at
private String mVideoFilePath;
private int mVideoDuration;
// If audio file has been set
private boolean mSetData;
private FileInputStream mFIS;
private FileDescriptor mFD;
private boolean mIsEarPhoneOn;
private File mPhoto;
private CameraSupport mCameraSupport;
private int mCameraId = -1;
private boolean mIsBackCamera = true;
private boolean mIsFullScreen = false;
private Context mContext;
public ChatInputView(Context context) {
super(context);
init(context);
}
public ChatInputView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public ChatInputView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context) {
mContext = context;
inflate(context, R.layout.view_chatinput, this);
// menu buttons
mChatInput = (EditText) findViewById(R.id.aurora_et_chat_input);
mVoiceBtn = (ImageButton) findViewById(R.id.aurora_menuitem_ib_voice);
mPhotoBtn = (ImageButton) findViewById(R.id.aurora_menuitem_ib_photo);
mCameraBtn = (ImageButton) findViewById(R.id.aurora_menuitem_ib_camera);
mSendBtn = (ImageButton) findViewById(R.id.aurora_menuitem_ib_send);
View voiceBtnContainer = findViewById(R.id.aurora_framelayout_menuitem_voice);
View photoBtnContainer = findViewById(R.id.aurora_framelayout_menuitem_photo);
View cameraBtnContainer = findViewById(R.id.aurora_framelayout_menuitem_camera);
voiceBtnContainer.setOnClickListener(onMenuItemClickListener);
photoBtnContainer.setOnClickListener(onMenuItemClickListener);
cameraBtnContainer.setOnClickListener(onMenuItemClickListener);
mSendBtn.setOnClickListener(onMenuItemClickListener);
mSendCountTv = (TextView) findViewById(R.id.aurora_menuitem_tv_send_count);
mInputMarginLeft = (Space) findViewById(R.id.aurora_input_margin_left);
mInputMarginRight = (Space) findViewById(R.id.aurora_input_margin_right);
mChatInputContainer = (LinearLayout) findViewById(R.id.aurora_ll_input_container);
mMenuItemContainer = (LinearLayout) findViewById(R.id.aurora_ll_menuitem_container);
mMenuContainer = (FrameLayout) findViewById(R.id.aurora_fl_menu_container);
mRecordVoiceRl = (RelativeLayout) findViewById(R.id.aurora_rl_recordvoice_container);
mPreviewPlayLl = (LinearLayout) findViewById(R.id.aurora_ll_recordvoice_preview_container);
mPreviewPlayBtn = (ProgressButton) findViewById(R.id.aurora_pb_recordvoice_play_audio);
mRecordContentLl = (LinearLayout) findViewById(R.id.aurora_ll_recordvoice_content_container);
mRecordControllerView = (RecordControllerView) findViewById(R.id.aurora_rcv_recordvoice_controller);
mChronometer = (Chronometer) findViewById(R.id.aurora_chronometer_recordvoice);
mRecordHintTv = (TextView) findViewById(R.id.aurora_tv_recordvoice_hint);
mSendAudioBtn = (Button) findViewById(R.id.aurora_btn_recordvoice_send);
mCancelSendAudioBtn = (Button) findViewById(R.id.aurora_btn_recordvoice_cancel);
mRecordVoiceBtn = (RecordVoiceButton) findViewById(R.id.aurora_rvb_recordvoice_record);
mCameraFl = (FrameLayout) findViewById(R.id.aurora_fl_camera_container);
mTextureView = (TextureView) findViewById(R.id.aurora_txtv_camera_texture);
mCloseBtn = (ImageButton) findViewById(R.id.aurora_ib_camera_close);
mFullScreenBtn = (ImageButton) findViewById(R.id.aurora_ib_camera_full_screen);
mRecordVideoBtn = (ImageButton) findViewById(R.id.aurora_ib_camera_record_video);
mCaptureBtn = (ImageButton) findViewById(R.id.aurora_ib_camera_capture);
mSwitchCameraBtn = (ImageButton) findViewById(R.id.aurora_ib_camera_switch);
mSelectPhotoView = (SelectPhotoView) findViewById(R.id.aurora_view_selectphoto);
mSelectPhotoView.setOnFileSelectedListener(this);
mSelectPhotoView.initData();
mMenuContainer.setVisibility(GONE);
mChatInput.addTextChangedListener(this);
mRecordVoiceBtn.setRecordController(mRecordControllerView);
mPreviewPlayBtn.setOnClickListener(this);
mCancelSendAudioBtn.setOnClickListener(this);
mSendAudioBtn.setOnClickListener(this);
mCloseBtn.setOnClickListener(this);
mFullScreenBtn.setOnClickListener(this);
mRecordVideoBtn.setOnClickListener(this);
mCaptureBtn.setOnClickListener(this);
mSwitchCameraBtn.setOnClickListener(this);
mImm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
mWindow = ((Activity) context).getWindow();
DisplayMetrics dm = getResources().getDisplayMetrics();
mWidth = dm.widthPixels;
mHeight = dm.heightPixels;
mRecordControllerView.setWidth(mWidth);
mRecordControllerView.setOnControllerListener(this);
mChatInput.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN && !mShowSoftInput) {
mShowSoftInput = true;
invisibleMenuLayout();
mChatInput.requestFocus();
}
return false;
}
});
}
private void init(Context context, AttributeSet attrs) {
init(context);
mStyle = ChatInputStyle.parse(context, attrs);
mChatInput.setMaxLines(mStyle.getInputMaxLines());
mChatInput.setHint(mStyle.getInputHint());
mChatInput.setText(mStyle.getInputText());
mChatInput.setTextSize(TypedValue.COMPLEX_UNIT_PX, mStyle.getInputTextSize());
mChatInput.setTextColor(mStyle.getInputTextColor());
mChatInput.setHintTextColor(mStyle.getInputHintColor());
mChatInput.setBackground(mStyle.getInputEditTextBg());
mInputMarginLeft.getLayoutParams().width = mStyle.getInputMarginLeft();
mInputMarginRight.getLayoutParams().width = mStyle.getInputMarginRight();
mVoiceBtn.setImageDrawable(mStyle.getVoiceBtnIcon());
mVoiceBtn.setBackground(mStyle.getVoiceBtnBg());
mPhotoBtn.setBackground(mStyle.getPhotoBtnBg());
mPhotoBtn.setImageDrawable(mStyle.getPhotoBtnIcon());
mCameraBtn.setBackground(mStyle.getCameraBtnBg());
mCameraBtn.setImageDrawable(mStyle.getCameraBtnIcon());
mSendBtn.setBackground(mStyle.getSendBtnBg());
mSendBtn.setImageDrawable(mStyle.getSendBtnIcon());
mSendCountTv.setBackground(mStyle.getSendCountBg());
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
return false;
}
});
}
private void setCursor(Drawable drawable) {
try {
Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
f.setAccessible(true);
f.set(mChatInput, drawable);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setMenuClickListener(OnMenuClickListener listener) {
mListener = listener;
}
public void setOnCameraCallbackListener(OnCameraCallbackListener listener) {
mCameraListener = listener;
}
@Override
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mInput = s;
if (mSelectPhotoView.getSelectFiles() == null || mSelectPhotoView.getSelectFiles().size() == 0) {
if (s.length() >= 1 && start == 0 && before == 0) { // Starting input
triggerSendButtonAnimation(mSendBtn, true, false);
} else if (s.length() == 0 && before >= 1) { // Clear content
triggerSendButtonAnimation(mSendBtn, false, false);
}
}
}
@Override
public void afterTextChanged(Editable editable) {
}
public EditText getInputView() {
return mChatInput;
}
public RecordVoiceButton getRecordVoiceButton() {
return mRecordVoiceBtn;
}
private OnClickListener onMenuItemClickListener = new OnClickListener() {
@Override
public void onClick(View view) {
if (view.getId() == R.id.aurora_menuitem_ib_send) {
// Allow send text and photos at the same time.
if (onSubmit()) {
mChatInput.setText("");
}
if (mSelectPhotoView.getSelectFiles() != null && mSelectPhotoView.getSelectFiles().size() > 0) {
mListener.onSendFiles(mSelectPhotoView.getSelectFiles());
mSendBtn.setImageDrawable(ContextCompat.getDrawable(getContext(),
R.drawable.aurora_menuitem_send));
mSendCountTv.setVisibility(View.INVISIBLE);
mSelectPhotoView.resetCheckState();
dismissMenuLayout();
}
} else {
if (mMenuContainer.getVisibility() != VISIBLE) {
dismissSoftInputAndShowMenu();
} else if (view.getId() == mLastClickId) {
dismissMenuAndResetSoftMode();
return;
}
if (view.getId() == R.id.aurora_framelayout_menuitem_voice) {
if (mListener != null) {
mListener.switchToMicrophoneMode();
}
showRecordVoiceLayout();
} else if (view.getId() == R.id.aurora_framelayout_menuitem_photo) {
if (mListener != null) {
mListener.switchToGalleryMode();
}
if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
return;
}
dismissRecordVoiceLayout();
dismissCameraLayout();
mSelectPhotoView.setVisibility(VISIBLE);
mSelectPhotoView.initData();
} else if (view.getId() == R.id.aurora_framelayout_menuitem_camera) {
if (mListener != null) {
mListener.switchToCameraMode();
}
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
if (mPhoto == null) {
String path = getContext().getFilesDir().getAbsolutePath() + "/photo";
File destDir = new File(path);
if (!destDir.exists()) {
destDir.mkdirs();
}
mPhoto = new File(destDir,
DateFormat.format("yyyy_MMdd_hhmmss", Calendar.getInstance(Locale.CHINA))
+ ".png");
}
if (mCameraSupport == null) {
initCamera();
}
showCameraLayout();
} else {
Toast.makeText(getContext(), getContext().getString(R.string.sdcard_not_exist_toast),
Toast.LENGTH_SHORT).show();
}
}
mLastClickId = view.getId();
}
}
};
@Override
public void onClick(View view) {
if (view.getId() == R.id.aurora_pb_recordvoice_play_audio) {
// press preview play audio button
if (!mPlaying) {
if (mSetData) {
mPreviewPlayBtn.startPlay();
mMediaPlayer.start();
mPlaying = true;
mChronometer.setBase(convertStrTimeToLong(mChronometer.getText().toString()));
mChronometer.start();
} else {
playVoice();
}
} else {
mSetData = true;
mMediaPlayer.pause();
mChronometer.stop();
mPlaying = false;
mPreviewPlayBtn.stopPlay();
}
} else if (view.getId() == R.id.aurora_btn_recordvoice_cancel) {
// preview play audio widget cancel sending audio
mPreviewPlayLl.setVisibility(GONE);
mRecordContentLl.setVisibility(VISIBLE);
mRecordVoiceBtn.cancelRecord();
mChronometer.setText("00:00");
} else if (view.getId() == R.id.aurora_btn_recordvoice_send) {
// preview play audio widget send audio
mPreviewPlayLl.setVisibility(GONE);
dismissMenuLayout();
mRecordVoiceBtn.finishRecord();
mChronometer.setText("00:00");
} else if (view.getId() == R.id.aurora_ib_camera_full_screen) {
// full screen/recover screen button in texture view
if (!mIsFullScreen) {
fullScreen();
} else {
recoverScreen();
}
} else if (view.getId() == R.id.aurora_ib_camera_record_video) {
// click record video button
// if it is not record video mode
if (!mIsRecordVideoMode) {
mIsRecordVideoMode = true;
mCaptureBtn.setBackgroundResource(R.drawable.aurora_preview_record_video_start);
mRecordVideoBtn.setBackgroundResource(R.drawable.aurora_preview_camera);
fullScreen();
mCloseBtn.setVisibility(VISIBLE);
} else {
mIsRecordVideoMode = false;
mRecordVideoBtn.setBackgroundResource(R.drawable.aurora_preview_record_video);
mCaptureBtn.setBackgroundResource(R.drawable.aurora_menuitem_send_pres);
mFullScreenBtn.setBackgroundResource(R.drawable.aurora_preview_recover_screen);
mFullScreenBtn.setVisibility(VISIBLE);
mCloseBtn.setVisibility(GONE);
}
} else if (view.getId() == R.id.aurora_ib_camera_capture) {
// click capture button in preview camera view
// is record video mode
if (mIsRecordVideoMode) {
if (!mIsRecordingVideo) { // start recording
mCameraSupport.startRecordingVideo();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mCaptureBtn.setBackgroundResource(R.drawable.aurora_preview_record_video_stop);
mRecordVideoBtn.setVisibility(GONE);
mSwitchCameraBtn.setVisibility(GONE);
mCloseBtn.setVisibility(VISIBLE);
}
}, 200);
mIsRecordingVideo = true;
} else { // finish recording
mVideoFilePath = mCameraSupport.finishRecordingVideo();
mIsRecordingVideo = false;
mIsRecordVideoMode = false;
mFinishRecordingVideo = true;
mCaptureBtn.setBackgroundResource(R.drawable.aurora_menuitem_send_pres);
mRecordVideoBtn.setVisibility(GONE);
mSwitchCameraBtn.setBackgroundResource(R.drawable.aurora_preview_delete_video);
mSwitchCameraBtn.setVisibility(VISIBLE);
if (mVideoFilePath != null) {
playVideo();
}
}
// if finished recording video, send it
} else if (mFinishRecordingVideo) {
if (mListener != null) {
VideoItem video = new VideoItem(mVideoFilePath, null, null, null, mMediaPlayer.getDuration());
List<FileItem> list = new ArrayList<>();
list.add(video);
mListener.onSendFiles(list);
mFinishRecordingVideo = false;
mVideoFilePath = null;
}
mMediaPlayer.stop();
mMediaPlayer.release();
recoverScreen();
dismissMenuAndResetSoftMode();
// take picture and send it
} else {
mCameraSupport.takePicture();
if (mIsFullScreen) {
recoverScreen();
}
}
} else if (view.getId() == R.id.aurora_ib_camera_close) {
try {
mMediaPlayer.stop();
mMediaPlayer.release();
} catch (IllegalStateException e) {
e.printStackTrace();
}
recoverScreen();
dismissMenuAndResetSoftMode();
if (mFinishRecordingVideo) {
mCameraSupport.cancelRecordingVideo();
mFinishRecordingVideo = false;
}
} else if (view.getId() == R.id.aurora_ib_camera_switch) {
if (mFinishRecordingVideo) {
mCameraSupport.cancelRecordingVideo();
mSwitchCameraBtn.setBackgroundResource(R.drawable.aurora_preview_switch_camera);
mRecordVideoBtn.setBackgroundResource(R.drawable.aurora_preview_camera);
mRecordVideoBtn.setVisibility(VISIBLE);
mVideoFilePath = null;
mFinishRecordingVideo = false;
mIsRecordVideoMode = true;
mCaptureBtn.setBackgroundResource(R.drawable.aurora_preview_record_video_start);
mMediaPlayer.stop();
mMediaPlayer.release();
mCameraSupport.open(mCameraId, mWidth, mHeight, mIsBackCamera);
} else {
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (mIsBackCamera) {
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
mCameraId = i;
mIsBackCamera = false;
mCameraSupport.release();
mCameraSupport.open(mCameraId, mTextureView.getWidth(),
mTextureView.getHeight(), mIsBackCamera);
break;
}
} else {
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
mCameraId = i;
mIsBackCamera = true;
mCameraSupport.release();
mCameraSupport.open(mCameraId, mTextureView.getWidth(),
mTextureView.getHeight(), mIsBackCamera);
break;
}
}
}
}
}
}
// play audio
private void playVoice() {
try {
mMediaPlayer.reset();
mFIS = new FileInputStream(mRecordVoiceBtn.getRecordFile());
mFD = mFIS.getFD();
mMediaPlayer.setDataSource(mFD);
if (mIsEarPhoneOn) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL);
} else {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
mMediaPlayer.prepare();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(final MediaPlayer mp) {
mChronometer.setBase(SystemClock.elapsedRealtime());
mPreviewPlayBtn.startPlay();
mChronometer.start();
mp.start();
mPlaying = true;
}
});
mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.stop();
mSetData = false;
mChronometer.stop();
mPlaying = false;
mPreviewPlayBtn.finishPlay();
}
});
} catch (Exception e) {
Toast.makeText(getContext(), getContext().getString(R.string.file_not_found_toast),
Toast.LENGTH_SHORT).show();
e.printStackTrace();
} finally {
try {
if (mFIS != null) {
mFIS.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void playVideo() {
try {
mCameraSupport.release();
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(mVideoFilePath);
Surface surface = new Surface(mTextureView.getSurfaceTexture());
mMediaPlayer.setSurface(surface);
surface.release();
mMediaPlayer.setLooping(true);
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
}
});
} catch (IOException | IllegalArgumentException | IllegalStateException e) {
e.printStackTrace();
}
}
public void setAudioPlayByEarPhone(int state) {
AudioManager audioManager = (AudioManager) getContext()
.getSystemService(Context.AUDIO_SERVICE);
int currVolume = audioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL);
audioManager.setMode(AudioManager.MODE_IN_CALL);
if (state == 0) {
mIsEarPhoneOn = false;
audioManager.setSpeakerphoneOn(true);
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,
audioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL),
AudioManager.STREAM_VOICE_CALL);
} else {
mIsEarPhoneOn = true;
audioManager.setSpeakerphoneOn(false);
audioManager.setStreamVolume(AudioManager.STREAM_VOICE_CALL, currVolume,
AudioManager.STREAM_VOICE_CALL);
}
}
private void initCamera() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mCameraSupport = new CameraNew(getContext(), mTextureView);
} else {
mCameraSupport = new CameraOld(getContext(), mTextureView);
}
mCameraSupport.setCameraCallbackListener(mCameraListener);
mCameraSupport.setOutputFile(mPhoto);
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
mCameraId = i;
break;
}
}
mTextureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
Log.e("ChatInputView", "Opening camera");
mCameraSupport.open(mCameraId, width, height, mIsBackCamera);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int width,
int height) {
Log.e("ChatInputView", "Texture size changed, Opening camera");
if (mTextureView.getVisibility() == VISIBLE) {
mCameraSupport.open(mCameraId, width, height, mIsBackCamera);
}
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
mCameraSupport.release();
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
});
}
/**
* Full screen mode
*/
private void fullScreen() {
// hide top status bar
Activity activity = (Activity) getContext();
WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
activity.getWindow().setAttributes(attrs);
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
mFullScreenBtn.setBackgroundResource(R.drawable.aurora_preview_recover_screen);
mFullScreenBtn.setVisibility(VISIBLE);
mChatInputContainer.setVisibility(GONE);
mMenuItemContainer.setVisibility(GONE);
mMenuContainer.setLayoutParams(new LinearLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, mHeight));
mTextureView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, mHeight));
mIsFullScreen = true;
}
/**
* Recover screen
*/
private void recoverScreen() {
Activity activity = (Activity) getContext();
WindowManager.LayoutParams attrs = activity.getWindow().getAttributes();
attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
activity.getWindow().setAttributes(attrs);
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
mIsFullScreen = false;
mCloseBtn.setVisibility(GONE);
mFullScreenBtn.setBackgroundResource(R.drawable.aurora_preview_full_screen);
mFullScreenBtn.setVisibility(VISIBLE);
mChatInputContainer.setVisibility(VISIBLE);
mMenuItemContainer.setVisibility(VISIBLE);
setMenuContainerHeight(sMenuHeight);
ViewGroup.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, sMenuHeight);
mTextureView.setLayoutParams(params);
mRecordVideoBtn.setBackgroundResource(R.drawable.aurora_preview_record_video);
mRecordVideoBtn.setVisibility(VISIBLE);
mSwitchCameraBtn.setBackgroundResource(R.drawable.aurora_preview_switch_camera);
mSwitchCameraBtn.setVisibility(VISIBLE);
mCaptureBtn.setBackgroundResource(R.drawable.aurora_menuitem_send_pres);
}
public void dismissMenuLayout() {
mMenuContainer.setVisibility(GONE);
}
public void invisibleMenuLayout() {
mMenuContainer.setVisibility(INVISIBLE);
}
public void showMenuLayout() {
mMenuContainer.setVisibility(VISIBLE);
}
public void showRecordVoiceLayout() {
mSelectPhotoView.setVisibility(GONE);
mCameraFl.setVisibility(GONE);
mRecordVoiceRl.setVisibility(VISIBLE);
mRecordContentLl.setVisibility(VISIBLE);
}
public void dismissRecordVoiceLayout() {
mRecordVoiceRl.setVisibility(GONE);
}
public void dismissPhotoLayout() {
mSelectPhotoView.setVisibility(View.GONE);
}
public void showCameraLayout() {
dismissRecordVoiceLayout();
dismissPhotoLayout();
mCameraFl.setVisibility(VISIBLE);
}
public void dismissCameraLayout() {
mCameraFl.setVisibility(GONE);
ViewGroup.LayoutParams params =
new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, sMenuHeight);
mTextureView.setLayoutParams(params);
}
/**
* Set menu container's height, invoke this method once the menu was initialized.
*
* @param height Height of menu, set same height as soft keyboard so that display to perfection.
*/
public void setMenuContainerHeight(int height) {
if (height > 0) {
sMenuHeight = height;
mMenuContainer.setLayoutParams(
new LinearLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, height));
}
}
private boolean onSubmit() {
return mListener != null && mListener.onSendTextMessage(mInput);
}
public boolean getSoftInputState() {
return mShowSoftInput;
}
public void setSoftInputState(boolean state) {
mShowSoftInput = state;
}
public int getMenuState() {
return mMenuContainer.getVisibility();
}
/**
* Select aurora_menuitem_photo callback
*/
@Override
public void onFileSelected() {
if (mInput.length() == 0 && mSelectPhotoView.getSelectFiles().size() == 1) {
triggerSendButtonAnimation(mSendBtn, true, true);
} else if (mInput.length() > 0 && mSendCountTv.getVisibility() != View.VISIBLE) {
mSendCountTv.setVisibility(View.VISIBLE);
}
mSendCountTv.setText(String.valueOf(mSelectPhotoView.getSelectFiles().size()));
}
/**
* Cancel select aurora_menuitem_photo callback
*/
@Override
public void onFileDeselected() {
int size = mSelectPhotoView.getSelectFiles().size();
if (size > 0) {
mSendCountTv.setText(String.valueOf(size));
} else {
if (mInput.length() == 0) {
triggerSendButtonAnimation(mSendBtn, false, true);
} else {
mSendCountTv.setVisibility(View.INVISIBLE);
}
}
}
/**
* Trigger aurora_menuitem_send button animation
*
* @param sendBtn aurora_menuitem_send button
* @param hasContent EditText has content or photos have been selected
* @param isSelectPhoto check if selecting photos
*/
private void triggerSendButtonAnimation(final ImageButton sendBtn, final boolean hasContent,
final boolean isSelectPhoto) {
float[] shrinkValues = new float[]{0.6f};
AnimatorSet shrinkAnimatorSet = new AnimatorSet();
shrinkAnimatorSet.playTogether(ObjectAnimator.ofFloat(sendBtn, "scaleX", shrinkValues),
ObjectAnimator.ofFloat(sendBtn, "scaleY", shrinkValues));
shrinkAnimatorSet.setDuration(100);
float[] restoreValues = new float[]{1.0f};
final AnimatorSet restoreAnimatorSet = new AnimatorSet();
restoreAnimatorSet.playTogether(ObjectAnimator.ofFloat(sendBtn, "scaleX", restoreValues),
ObjectAnimator.ofFloat(sendBtn, "scaleY", restoreValues));
restoreAnimatorSet.setDuration(100);
restoreAnimatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
}
@Override
public void onAnimationEnd(Animator animator) {
mSendCountTv.bringToFront();
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
requestLayout();
invalidate();
}
if (hasContent && isSelectPhoto) {
mSendCountTv.setVisibility(View.VISIBLE);
}
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
shrinkAnimatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animator) {
if (!hasContent && isSelectPhoto) {
mSendCountTv.setVisibility(View.INVISIBLE);
}
}
@Override
public void onAnimationEnd(Animator animator) {
if (hasContent) {
mSendBtn.setImageDrawable(ContextCompat.getDrawable(getContext(),
R.drawable.aurora_menuitem_send_pres));
} else {
mSendBtn.setImageDrawable(ContextCompat.getDrawable(getContext(),
R.drawable.aurora_menuitem_send));
}
restoreAnimatorSet.start();
}
@Override
public void onAnimationCancel(Animator animator) {
}
@Override
public void onAnimationRepeat(Animator animator) {
}
});
shrinkAnimatorSet.start();
}
/**
* Set aurora_menuitem_camera capture file path and file name. If user didn't invoke this method, will save in
* default path.
*
* @param path Photo to be saved in.
* @param fileName File name.
*/
public void setCameraCaptureFile(String path, String fileName) {
File destDir = new File(path);
if (!destDir.exists()) {
destDir.mkdirs();
}
mPhoto = new File(path, fileName + ".png");
}
/**
* Record audio widget finger on touch record button callback
*/
@Override
public void onStart() {
Log.e("ChatInputView", "starting chronometer");
mChronometer.setBase(SystemClock.elapsedRealtime());
mChronometer.start();
mChronometer.setVisibility(VISIBLE);
mRecordHintTv.setVisibility(INVISIBLE);
}
/**
* Recording audio mode, finger moving callback
*/
@Override
public void onMoving() {
mChronometer.setVisibility(VISIBLE);
mRecordHintTv.setVisibility(INVISIBLE);
}
/**
* Recording audio mode, finger moved left button (preview button) callback
*/
@Override
public void onMovedLeft() {
mChronometer.setVisibility(INVISIBLE);
mRecordHintTv.setVisibility(VISIBLE);
mRecordHintTv.setText(getContext().getString(R.string.preview_play_audio_hint));
}
/**
* Recording audio mode, finger moved right button (cancel button)
*/
@Override
public void onMovedRight() {
mChronometer.setVisibility(INVISIBLE);
mRecordHintTv.setVisibility(VISIBLE);
mRecordHintTv.setText(getContext().getString(R.string.cancel_record_voice_hint));
}
/**
* Recording audio mode, finger moved left button and release
*/
@Override
public void onLeftUpTapped() {
mChronometer.stop();
mRecordTime = SystemClock.elapsedRealtime() - mChronometer.getBase();
mPreviewPlayBtn.setMax((int) (mRecordTime / 1000));
mChronometer.setVisibility(VISIBLE);
mRecordHintTv.setVisibility(INVISIBLE);
mPreviewPlayLl.setVisibility(VISIBLE);
mRecordContentLl.setVisibility(GONE);
}
/**
* Recording audio mode, finger moved right button and release
*/
@Override
public void onRightUpTapped() {
mChronometer.stop();
mChronometer.setVisibility(INVISIBLE);
mRecordHintTv.setText(getContext().getString(R.string.record_voice_hint));
mRecordHintTv.setVisibility(VISIBLE);
}
private long convertStrTimeToLong(String strTime) {
String[] timeArray = strTime.split(":");
long longTime = 0;
if (timeArray.length == 2) { // If time format is MM:SS
longTime = Integer.parseInt(timeArray[0]) * 60 * 1000 + Integer.parseInt(timeArray[1]) * 1000;
}
return SystemClock.elapsedRealtime() - longTime;
}
public void dismissMenuAndResetSoftMode() {
mWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
dismissMenuLayout();
mChatInput.requestFocus();
ViewGroup.LayoutParams params =
new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, sMenuHeight);
mTextureView.setLayoutParams(params);
}
public void dismissSoftInputAndShowMenu() {
// dismiss soft input
mWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
showMenuLayout();
if (mImm != null) {
mImm.hideSoftInputFromWindow(mChatInput.getWindowToken(), 0);
}
setMenuContainerHeight(sMenuHeight);
mShowSoftInput = false;
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (mCameraSupport != null) {
mCameraSupport.release();
}
mMediaPlayer.release();
mMediaPlayer = null;
}
@Override
public void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
if (visibility == GONE) {
if (mCameraSupport != null) {
mCameraSupport.release();
}
}
}
}