android:仿微信录制短视频的实现

一、需求

仿微信短视频录制,点击拍照,长按录视频

二、实现代码

1、RecordVideoActivity

/**
 * Created by yxj on 17/4/17.
 * 
 * 录制视频的界面
 */

public class RecordVideoActivity extends TitleActivity {
    private JCameraView mJCameraView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);//没有标题
        this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏
        this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);//设置竖屏
        setContentView(R.layout.record_video);

        mJCameraView = (JCameraView) findViewById(R.id.cameraView);
        mJCameraView.setActivity(this);
        //设置视频保存路径(如果不设置默认为Environment.getExternalStorageDirectory().getPath())
        mJCameraView.setAutoFocus(false);
//        mJCameraView.setSaveVideoPath(Environment.getExternalStorageDirectory().getPath());
        mJCameraView.setCameraViewListener(new JCameraView.CameraViewListener() {
            @Override
            public void quit() {
                RecordVideoActivity.this.finish();
            }

            @Override
            public void captureSuccess(Bitmap bitmap) {//拍照成功
                String url = FileUtil.saveBitmapToSDCard(bitmap);//拍照保存路径
                Intent intent = new Intent();
                //把返回数据存入Intent 0是照片,1是视频
                intent.putExtra("url", url);
                intent.putExtra("type", 0);
                //设置返回数据
                setResult(RESULT_OK, intent);
                finish();
            }

            @Override
            public void recordSuccess(String url) {//录视频成功
                Intent intent = new Intent();
                //把返回数据存入Intent 0是照片,1是视频
                intent.putExtra("url", url);
                intent.putExtra("type", 1);
                //设置返回数据
                setResult(RESULT_OK, intent);
                finish();
            }
        });
    }

    @Override
    protected void onResume() {
        if (Build.VERSION.SDK_INT < 23) {
            if (!PermissionUtils.PermissionToolBefore23()){
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("提示")
                        .setMessage("没有照相机权限,请赋予本权限再开始拍照吧~").setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {
                        finish();
                    }
                }).show();
                return;
            }
        }
        mJCameraView.onResume();
        super.onResume();
    }

    @Override
    protected void onPause() {
        mJCameraView.onPause();
        super.onPause();
    }

    public PermissionUtils.PermissionGrant mPermissionGrant = new PermissionUtils.PermissionGrant() {
        @Override
        public void onPermissionGranted(int requestCode) {
            switch (requestCode) {
                case PermissionUtils.CODE_CAMERA:
                    PermissionUtils.requestPermission(RecordVideoActivity.this, PermissionUtils.CODE_RECORD_AUDIO,
                            mPermissionGrant, false);
                    break;
                case PermissionUtils.CODE_RECORD_AUDIO:
                    BuriedPointManager.getInstance().savePoint(R.integer.share_create_photograph_click);
                    break;
                default:
                    break;
            }
        }
    };
}

2、record_video.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.zjelite.commonview.JCameraView
        android:id="@+id/cameraView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

3、CaptureButton


/**
 * 录制视频的按钮,长按录制,点击拍照
 */
public class CaptureButton extends View {
    public final String TAG = "CaptureButtom";

    private Paint               mPaint;
    private Context             mContext;
    private RecordVideoActivity activity;
    
    private float btn_center_Y;
    private float btn_center_X;

    private float btn_inside_radius;
    private float btn_outside_radius;
    //before radius
    private float btn_before_inside_radius;
    private float btn_before_outside_radius;
    //after radius
    private float btn_after_inside_radius;
    private float btn_after_outside_radius;

    private float btn_return_length;
    private float btn_return_X;
    private float btn_return_Y;

    private float btn_left_X, btn_right_X, btn_result_radius;

    //state
    private int STATE_SELECTED;
    private final int STATE_LESSNESS       = 0;     //空闲状态
    private final int STATE_KEY_DOWN       = 1;
    private final int STATE_CAPTURED       = 2;
    private final int STATE_RECORD         = 3;
    private final int STATE_PICTURE_BROWSE = 4;     //拍照完成后的预览状态
    private final int STATE_RECORD_BROWSE  = 5;     //录像完成后的预览状态
    private final int STATE_READYQUIT      = 6;     //退出
    private final int STATE_RECORDED       = 7;

    private float key_down_Y;

    private RectF rectF;
    private float             progress          = 0;
    private LongPressRunnable longPressRunnable = new LongPressRunnable();
    private RecordRunnable    recordRunnable    = new RecordRunnable();
    private ValueAnimator     record_anim       = ValueAnimator.ofFloat(0, 360);
    private CaptureListener mCaptureListener;

    public CaptureButton(Context context) {
        this(context, null);
    }

    public CaptureButton(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CaptureButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        STATE_SELECTED = STATE_LESSNESS;
    }

    public void setActivity(RecordVideoActivity activity) {
        this.activity = activity;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
//        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int width = widthSize;
        Log.i(TAG, "measureWidth = " + width);
        int height = (width / 9) * 4;
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        btn_center_X = getWidth() / 2f;
        btn_center_Y = getHeight() / 2f;

        btn_outside_radius = (float) (getWidth() / 9);
        btn_inside_radius = (float) (btn_outside_radius * 0.75);

        btn_before_outside_radius = (float) (getWidth() / 9);
        btn_before_inside_radius = (float) (btn_outside_radius * 0.75);
        btn_after_outside_radius = (float) (getWidth() / 6);
        btn_after_inside_radius = (float) (btn_outside_radius * 0.6);

        btn_return_length = (float) (btn_outside_radius * 0.35);
        //        btn_result_radius = 80;
        btn_result_radius = (float) (getWidth() / 9);
        btn_left_X = getWidth() / 2;
        btn_right_X = getWidth() / 2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (STATE_SELECTED == STATE_LESSNESS || STATE_SELECTED == STATE_RECORD) {
            //draw capture button
            mPaint.setColor(0xFFEEEEEE);
            canvas.drawCircle(btn_center_X, btn_center_Y, btn_outside_radius, mPaint);
            mPaint.setColor(Color.WHITE);
            canvas.drawCircle(btn_center_X, btn_center_Y, btn_inside_radius, mPaint);

            //draw Progress bar
            Paint paintArc = new Paint();
            paintArc.setAntiAlias(true);
            paintArc.setColor(0xFF00CC00);
            paintArc.setStyle(Paint.Style.STROKE);
            paintArc.setStrokeWidth(10);

            rectF = new RectF(btn_center_X - (btn_after_outside_radius - 5), btn_center_Y - (btn_after_outside_radius
                    - 5), btn_center_X + (btn_after_outside_radius - 5), btn_center_Y + (btn_after_outside_radius - 5));
            canvas.drawArc(rectF, -90, progress, false, paintArc);

            //draw return button
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setColor(Color.WHITE);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(4);
            Path path = new Path();

            btn_return_X = ((getWidth() / 2) - btn_outside_radius) / 2;
            btn_return_Y = (getHeight() / 2 + 10);

            path.moveTo(btn_return_X - btn_return_length, btn_return_Y - btn_return_length);
            path.lineTo(btn_return_X, btn_return_Y);
            path.lineTo(btn_return_X + btn_return_length, btn_return_Y - btn_return_length);
            canvas.drawPath(path, paint);
        } else if (STATE_SELECTED == STATE_RECORD_BROWSE || STATE_SELECTED == STATE_PICTURE_BROWSE) {

            mPaint.setColor(0xFFEEEEEE);
            canvas.drawCircle(btn_left_X, btn_center_Y, btn_result_radius, mPaint);
            mPaint.setColor(Color.WHITE);
            canvas.drawCircle(btn_right_X, btn_center_Y, btn_result_radius, mPaint);

            //left button
            Paint paint = new Paint();
            paint.setAntiAlias(true);
            paint.setColor(Color.BLACK);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeWidth(3);
            Path path = new Path();

            path.moveTo(btn_left_X - 2, btn_center_Y + 14);
            path.lineTo(btn_left_X + 14, btn_center_Y + 14);
            path.arcTo(new RectF(btn_left_X, btn_center_Y - 14, btn_left_X + 28, btn_center_Y + 14), 90, -180);
            path.lineTo(btn_left_X - 14, btn_center_Y - 14);
            canvas.drawPath(path, paint);

            paint.setStyle(Paint.Style.FILL);
            path.reset();
            path.moveTo(btn_left_X - 14, btn_center_Y - 22);
            path.lineTo(btn_left_X - 14, btn_center_Y - 6);
            path.lineTo(btn_left_X - 23, btn_center_Y - 14);
            path.close();
            canvas.drawPath(path, paint);

            paint.setStyle(Paint.Style.STROKE);
            paint.setColor(0xFF00CC00);
            paint.setStrokeWidth(4);
            path.reset();
            path.moveTo(btn_right_X - 28, btn_center_Y);
            path.lineTo(btn_right_X - 8, btn_center_Y + 22);
            path.lineTo(btn_right_X + 30, btn_center_Y - 20);
            path.lineTo(btn_right_X - 8, btn_center_Y + 18);
            path.close();
            canvas.drawPath(path, paint);
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
//        try {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    if (STATE_SELECTED == STATE_LESSNESS) {
                        if (event.getY() > btn_return_Y - 37 && event.getY() < btn_return_Y + 10 && event.getX() > 
                                btn_return_X - 37 && event.getX() < btn_return_X + 37) {
                            STATE_SELECTED = STATE_READYQUIT;
                        } else if (event.getY() > btn_center_Y - btn_outside_radius && event.getY() < btn_center_Y + 
                                btn_outside_radius && event.getX() > btn_center_X - btn_outside_radius && event.getX
                                () < btn_center_X + btn_outside_radius && event.getPointerCount() == 1) {
                            key_down_Y = event.getY();
                            STATE_SELECTED = STATE_KEY_DOWN;
                            postCheckForLongTouch();
                        }
                    } else if (STATE_SELECTED == STATE_RECORD_BROWSE || STATE_SELECTED == STATE_PICTURE_BROWSE) {
                        if (event.getY() > btn_center_Y - btn_result_radius && event.getY() < btn_center_Y + 
                                btn_result_radius && event.getX() > btn_left_X - btn_result_radius && event.getX() < 
                                btn_left_X + btn_result_radius && event.getPointerCount() == 1) {
                            if (mCaptureListener != null) {
                                if (STATE_SELECTED == STATE_RECORD_BROWSE) {
                                    mCaptureListener.deleteRecordResult();
                                } else if (STATE_SELECTED == STATE_PICTURE_BROWSE) {
                                    mCaptureListener.cancel();
                                }
                            }
                            STATE_SELECTED = STATE_LESSNESS;
                            btn_left_X = btn_center_X;
                            btn_right_X = btn_center_X;
                            invalidate();
                        } else if (event.getY() > btn_center_Y - btn_result_radius && event.getY() < btn_center_Y + 
                                btn_result_radius && event.getX() > btn_right_X - btn_result_radius && event.getX() <
                                btn_right_X + btn_result_radius && event.getPointerCount() == 1) {
                            if (mCaptureListener != null) {
                                if (STATE_SELECTED == STATE_RECORD_BROWSE) {
                                    mCaptureListener.getRecordResult();
                                } else if (STATE_SELECTED == STATE_PICTURE_BROWSE) {
                                    mCaptureListener.determine();
                                }
                            }
                            STATE_SELECTED = STATE_LESSNESS;
                            btn_left_X = btn_center_X;
                            btn_right_X = btn_center_X;
                            invalidate();
                        }
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    //                    if (event.getY() > btn_center_Y - btn_outside_radius &&
                    //                            event.getY() < btn_center_Y + btn_outside_radius &&
                    //                            event.getX() > btn_center_X - btn_outside_radius &&
                    //                            event.getX() < btn_center_X + btn_outside_radius) {
                    //                    }
                    //                    if (mCaptureListener != null) {
                    //                        mCaptureListener.scale(key_down_Y - event.getY());
                    //                    }
                    break;
                case MotionEvent.ACTION_UP:
                    removeCallbacks(longPressRunnable);
                    if (STATE_SELECTED == STATE_READYQUIT) {
                        if (event.getY() > btn_return_Y - 37 && event.getY() < btn_return_Y + 10 && event.getX() > 
                                btn_return_X - 37 && event.getX() < btn_return_X + 37) {
                            STATE_SELECTED = STATE_LESSNESS;
                            if (mCaptureListener != null) {    // 录制完成不使用直接返回键时,这个监听器null了,导致再次点击下箭头无法返回
                                mCaptureListener.quit();
                            }
                        }
                    } else if (STATE_SELECTED == STATE_KEY_DOWN) {
                        if (event.getY() > btn_center_Y - btn_outside_radius && event.getY() < btn_center_Y + 
                                btn_outside_radius && event.getX() > btn_center_X - btn_outside_radius && event.getX
                                () < btn_center_X + btn_outside_radius) {
                            if (mCaptureListener != null) {
                                mCaptureListener.capture();
                            }
                            STATE_SELECTED = STATE_PICTURE_BROWSE;
                        }
                    } else if (STATE_SELECTED == STATE_RECORD) {
                        LogUtils.e("CaptureButton", "record_anim.getCurrentPlayTime==" + record_anim
                                .getCurrentPlayTime());
                        if (record_anim.getCurrentPlayTime() < 800) {
                            ToastUtil.toastShort("视频过短,请重新录制");
                            STATE_SELECTED = STATE_LESSNESS;
                            //                        Toast.makeText(mContext, "Under time", Toast.LENGTH_SHORT).show();
                            progress = 0;
                            invalidate();
                            record_anim.cancel();
                            if (mCaptureListener != null) {
                                mCaptureListener.cancel();
                            }
                        } else {
                            STATE_SELECTED = STATE_RECORD_BROWSE;
                            removeCallbacks(recordRunnable);
                            //                        Toast.makeText(mContext, "Time length " + record_anim
                            // .getCurrentPlayTime(), Toast.LENGTH_SHORT).show();
                            captureAnimation(getWidth() / 5, (getWidth() / 5) * 4);
                            record_anim.cancel();
                            progress = 0;
                            invalidate();
                            if (mCaptureListener != null) {
                                mCaptureListener.recordEnd();
                            }
                        }
                        if (btn_outside_radius == btn_after_outside_radius && btn_inside_radius == 
                                btn_after_inside_radius) {
                            //                            startAnimation(btn_outside_radius, btn_outside_radius - 40,
                            // btn_inside_radius, btn_inside_radius + 20);
                            startAnimation(btn_after_outside_radius, btn_before_outside_radius, 
                                    btn_after_inside_radius, btn_before_inside_radius);
                        } else {
                            startAnimation(btn_after_outside_radius, btn_before_outside_radius, 
                                    btn_after_inside_radius, btn_before_inside_radius);
                        }
                    }
                    break;
                default:
                    break;
            }
//        } catch (Exception e) {
//            return false;
//        }
        return true;
    }

    public void initButton() {
        STATE_SELECTED = STATE_LESSNESS;
        invalidate();
    }

    public void captureSuccess() {
        captureAnimation(getWidth() / 5, (getWidth() / 5) * 4);
    }

    private void postCheckForLongTouch() {
        postDelayed(longPressRunnable, 200);
    }

    private class LongPressRunnable implements Runnable {
        @Override
        public void run() {
            startAnimation(btn_before_outside_radius, btn_after_outside_radius, btn_before_inside_radius, 
                    btn_after_inside_radius);
            STATE_SELECTED = STATE_RECORD;
        }
    }

    private class RecordRunnable implements Runnable {
        @Override
        public void run() {
            if (mCaptureListener != null) {
                mCaptureListener.record();
            }
            record_anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    if (STATE_SELECTED == STATE_RECORD) {
                        progress = (float) animation.getAnimatedValue();
                    }
                    invalidate();
                }
            });
            record_anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    if (STATE_SELECTED == STATE_RECORD) {
                        STATE_SELECTED = STATE_RECORD_BROWSE;
                        progress = 0;
                        invalidate();
                        captureAnimation(getWidth() / 5, (getWidth() / 5) * 4);
                        if (btn_outside_radius == btn_after_outside_radius && btn_inside_radius == 
                                btn_after_inside_radius) {
                            startAnimation(btn_after_outside_radius, btn_before_outside_radius, 
                                    btn_after_inside_radius, btn_before_inside_radius);
                        } else {
                            startAnimation(btn_after_outside_radius, btn_before_outside_radius, 
                                    btn_after_inside_radius, btn_before_inside_radius);
                        }
                        if (mCaptureListener != null) {
                            mCaptureListener.recordEnd();
                        }
                    }
                }
            });
            record_anim.setInterpolator(new LinearInterpolator());
            record_anim.setDuration(10000);
            record_anim.start();
        }
    }

    private void startAnimation(float outside_start, float outside_end, float inside_start, float inside_end) {

        ValueAnimator outside_anim = ValueAnimator.ofFloat(outside_start, outside_end);
        ValueAnimator inside_anim = ValueAnimator.ofFloat(inside_start, inside_end);
        outside_anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                btn_outside_radius = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        outside_anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                if (STATE_SELECTED == STATE_RECORD) {
                    postDelayed(recordRunnable, 100);
                }
            }
        });
        inside_anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                btn_inside_radius = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        outside_anim.setDuration(100);
        inside_anim.setDuration(100);
        outside_anim.start();
        inside_anim.start();
    }

    private void captureAnimation(float left, float right) {
        //        Toast.makeText(mContext,left+ " = "+right,Toast.LENGTH_SHORT).show();
        ValueAnimator left_anim = ValueAnimator.ofFloat(btn_left_X, left);
        ValueAnimator right_anim = ValueAnimator.ofFloat(btn_right_X, right);
        left_anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                btn_left_X = (float) animation.getAnimatedValue();
                invalidate();
            }

        });
        right_anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                btn_right_X = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        left_anim.setDuration(200);
        right_anim.setDuration(200);
        left_anim.start();
        right_anim.start();
    }

    public void setCaptureListener(CaptureListener mCaptureListener) {
        this.mCaptureListener = mCaptureListener;
    }

    public interface CaptureListener {
        void capture();

        void cancel();//拍照点击返回

        void determine();//拍照的确定

        void quit();//关闭界面

        void record();

        void recordEnd();

        void getRecordResult();//录像点击确定

        void deleteRecordResult();//录像点击返回

        void scale(float scaleValue);
    }
}

4、JCwebView

/**
 * Created by yxj on 17/4/17.
 * 录制视频的自定义控件
 */

public class JCameraView extends RelativeLayout implements SurfaceHolder.Callback, Camera.AutoFocusCallback,
        CameraFocusListener {

    private Context             mContext;
    private VideoView           mVideoView;
    private FocusView           mFocusView;     //对焦的按钮
    private CaptureButton       mCaptureButton; //录制视频/拍照的按钮
    private ImageView           mImageView;     //右上角摄像头切换的图标
    private ImageView           picPreImageView;//拍照完成的预览的图片
    private float               screenProp;
    private MediaRecorder       mediaRecorder;
    private Camera              mCamera;
    private Camera.Parameters   mParam;
    private int                 previewWidth;
    private int                 previewHeight;
    private int                 pictureWidth;
    private int                 pictureHeight;
    private boolean             autoFocus;
    private String              fileName;
    private Bitmap              pictureBitmap;
    private CameraViewListener  cameraViewListener;
    private RecordVideoActivity activity;
    private boolean             needSetVisible;

    public final String                TAG                   = "JCameraView";
    private      PowerManager          powerManager          = null;
    private      PowerManager.WakeLock wakeLock              = null;
    private      int                   iconMargin            = 0;
    private      int                   iconSrc               = 0;
    private      SurfaceHolder         mHolder               = null;
    private      String                videoFileName         = "";
    private      boolean               isPlay                = false;
    private      boolean               isRecorder            = false;
    private      boolean               isPre                 = false;//是不是在拍照的预览
    private      int                   SELECTED_CAMERA       = -1;
    private      int                   CAMERA_POST_POSITION  = -1;
    private      int                   CAMERA_FRONT_POSITION = -1;


    public void setCameraViewListener(CameraViewListener cameraViewListener) {
        this.cameraViewListener = cameraViewListener;
    }

    public JCameraView(Context context) {
        this(context, null);
    }

    public JCameraView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public JCameraView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        powerManager = (PowerManager) mContext.getSystemService(mContext.POWER_SERVICE);
        wakeLock = this.powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "My Lock");
        findAvailableCameras();
        SELECTED_CAMERA = CAMERA_POST_POSITION;

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.JCameraView, defStyleAttr, 0);
        iconMargin = a.getDimensionPixelSize(R.styleable.JCameraView_iconMargin, (int) TypedValue.applyDimension
                (TypedValue.COMPLEX_UNIT_SP, 15, getResources().getDisplayMetrics()));
        iconSrc = a.getResourceId(R.styleable.JCameraView_iconSrc, R.drawable.capture);

        initView();
    }

    public void setActivity(RecordVideoActivity activity) {
        this.activity = activity;
        mCaptureButton.setActivity(activity);
    }

    /**
     * 初始化View界面,含控件的初始化以及控件监听器的初始化
     */
    private void initView() {
        setWillNotDraw(false);
        this.setBackgroundColor(Color.BLACK);

        initVideoView();            //视频播放控件
        initPicPreImageView();      //预览
        initCaptureButton();        //录像按钮
        initCameraChangeButton();   //切换摄像头
        initFocusView();            //对焦视图
        initSurfaceHolder();
    }

    private void initSurfaceHolder() {
        mHolder = mVideoView.getHolder();
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        mHolder.addCallback(this);
    }

    private void initFocusView() {
        //        对焦的图标
        mFocusView = new FocusView(mContext, 120);
        mFocusView.setVisibility(INVISIBLE);

        this.addView(mFocusView);       //对焦
    }

    private void initCameraChangeButton() {
        //右上角切换摄像头的按钮       
        mImageView = new ImageView(mContext);
        LayoutParams imageViewParam = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        imageViewParam.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
        imageViewParam.setMargins(0, iconMargin, iconMargin, 0);
        mImageView.setLayoutParams(imageViewParam);
        mImageView.setImageResource(iconSrc);
        mImageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!isRecorder && mCamera != null) {
                    releaseCamera();

                    //切换摄像头
                    SELECTED_CAMERA = SELECTED_CAMERA == CAMERA_POST_POSITION ? CAMERA_FRONT_POSITION :
                            CAMERA_POST_POSITION;

                    getCamera(SELECTED_CAMERA);
                    previewWidth = previewHeight = 0;
                    pictureWidth = pictureHeight = 0;
                    setStartPreview(mCamera, mHolder);
                }
            }
        });

        this.addView(mImageView);       //右上角摄像头切换
    }

    private void initCaptureButton() {
        //底部居中的录像/拍照按钮 
        LayoutParams btnParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        btnParams.addRule(RelativeLayout.CENTER_HORIZONTAL, RelativeLayout.TRUE);
        btnParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
        mCaptureButton = new CaptureButton(mContext);
        mCaptureButton.setLayoutParams(btnParams);

        //初始化为自动对焦
        autoFocus = true;
        initCaptureButtonListener();

        this.addView(mCaptureButton);   //录视频
    }

    private void initPicPreImageView() {
        LayoutParams picPreImageViewParam = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        picPreImageViewParam.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
        picPreImageView = new ImageView(mContext);
        picPreImageView.setLayoutParams(picPreImageViewParam);
        picPreImageView.setVisibility(INVISIBLE);

        this.addView(picPreImageView);  //预览
    }

    private void initVideoView() {
    /*VideoView 播放视频的界面*/
        mVideoView = new VideoView(mContext);
        LayoutParams videoViewParam = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        videoViewParam.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
        mVideoView.setLayoutParams(videoViewParam);
        this.addView(mVideoView);       //viedoView

        mVideoView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mCamera.autoFocus(JCameraView.this);
            }
        });
    }

    /**
     * 初始化拍照/录像按钮的监听器
     */
    private void initCaptureButtonListener() {
        mCaptureButton.setCaptureListener(new CaptureButton.CaptureListener() {
            @Override
            public void capture() {
                JCameraView.this.capture();
            }

            @Override
            public void cancel() {
                isRecorder = false;
                releaseCamera();
                getCamera(SELECTED_CAMERA);
                isPre = false;
                setStartPreview(mCamera, mHolder);
                picPreImageView.setVisibility(INVISIBLE);
            }

            @Override
            public void determine() {
                if (cameraViewListener != null) {
                    cameraViewListener.captureSuccess(pictureBitmap);
                }
                releaseCamera();
                isPre = false;
            }

            @Override
            public void quit() {
                if (cameraViewListener != null) {
                    cameraViewListener.quit();
                }
            }

            @Override
            public void record() {
                startRecord();
            }

            @Override
            public void recordEnd() {
                stopRecord();
            }

            @Override
            public void getRecordResult() {
                if (cameraViewListener != null) {
                    cameraViewListener.recordSuccess(fileName);
                }
                mVideoView.stopPlayback();
                releaseCamera();
                isPlay = false;
            }

            @Override
            public void deleteRecordResult() {
                File file = new File(fileName);
                if (file.exists()) {
                    file.delete();
                }
                fileName = null;
                releaseCamera();

                mVideoView.pause();
                mVideoView.stopPlayback();  //整个界面销毁,各种按钮不存在了,依附于按钮的监听器也就不存在了

                isPlay = false;
                getCamera(SELECTED_CAMERA);
                setStartPreview(mCamera, mHolder);
            }

            @Override
            public void scale(float scaleValue) {
                if (scaleValue >= 0) {
                    int scaleRate = (int) (scaleValue / 50);

                    if (scaleRate < 10 && scaleRate >= 0 && mParam != null && mCamera != null && mParam
                            .isSmoothZoomSupported()) {
                        mParam = mCamera.getParameters();
                        mParam.setZoom(scaleRate);
                        mCamera.setParameters(mParam);
                    }
                }
            }
        });
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
    }

    //获取Camera
    private void getCamera(int position) {
        try {
            if (null == mCamera) {
                Log.d(JCameraView.class.getName(), "position:" + position);
                mCamera = Camera.open(position);
                LogUtils.d("guo_zjin:", "create camera success");
            }
        } catch (RuntimeException e) {
            LogUtils.d("guo_zjin:", "create camera Runtime Exception");
            AlertDialog.Builder builder = new AlertDialog.Builder(activity);
            builder.setTitle("提示").setMessage("没有照相机权限,请赋予本权限再开始拍照吧~").setPositiveButton("确定", new DialogInterface
                    .OnClickListener() {
                @Override
                public void onClick(DialogInterface arg0, int arg1) {
                    activity.finish();
                }
            }).show();
        } catch (Exception e) {
            LogUtils.d("guo_zjin:", "create camera Exception");
            mCamera = null;
            e.printStackTrace();
        }
    }

    private void setStartPreview(Camera camera, SurfaceHolder holder) {
        if (camera == null) {
            return;
        }
        if (mImageView.getVisibility() != View.VISIBLE && !isPre && !isPlay && !isRecorder) {
            mImageView.setVisibility(View.VISIBLE);
            this.removeView(mImageView);
            this.addView(mImageView);
        }
        this.invalidate();

        mParam = camera.getParameters();

        if (screenProp != 0) {
            Camera.Size previewSize = CameraParamUtil.getInstance().getPreviewSize(mParam.getSupportedPreviewSizes(),
                    1000, screenProp);
            Camera.Size pictureSize = CameraParamUtil.getInstance().getPictureSize(mParam.getSupportedPictureSizes(),
                    1200, screenProp);
            mParam.setPreviewSize(previewSize.width, previewSize.height);
            mParam.setPictureSize(pictureSize.width, pictureSize.height);
        }
        if (CameraParamUtil.getInstance().isSupportedFocusMode(mParam.getSupportedFocusModes(), Camera.Parameters
                .FOCUS_MODE_CONTINUOUS_VIDEO)) {
            mParam.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
        } else if (CameraParamUtil.getInstance().isSupportedFocusMode(mParam.getSupportedFocusModes(), Camera
                .Parameters.FOCUS_MODE_AUTO)) {
            mParam.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        }
        if (CameraParamUtil.getInstance().isSupportedPictureFormats(mParam.getSupportedPictureFormats(), ImageFormat
                .JPEG)) {
            mParam.setPictureFormat(ImageFormat.JPEG);
            mParam.setJpegQuality(100);
        }
        camera.setParameters(mParam);
        try {
            LogUtils.d("guo_zjin:", "发生错误的开始。。。。");
            camera.setPreviewDisplay(holder);
            LogUtils.d("guo_zjin:", "发生错误的开始。。。。01");
            camera.setDisplayOrientation(CameraParamUtil.getInstance().setCameraDisplayOrientation(activity,
                    SELECTED_CAMERA));
            LogUtils.d("guo_zjin:", "发生错误的开始。。。。02");

            camera.startPreview();
            LogUtils.d("guo_zjin:", "发生错误的开始。。。。03");
        } catch (FileNotFoundException e) {
            LogUtils.d("guo_zjin:", "在setStartPreview里发生文件不存在,被release");
            releasePre();
        } catch (IOException e) {
            LogUtils.d("guo_zjin: ", "在这里发生了一个该死的异常,但是我不得不在这里处理掉。。。。。00" + e.getMessage());
        } catch (Exception e) {
            LogUtils.d("guo_zjin:", "在这里发生了一个该死的异常,但是我不得不在这里处理掉。。。。。01" + e.getMessage());
        }
    }

    private void releaseMediaRecorder() {
        if (mVideoView != null) {
            mVideoView.stopPlayback();
            mHolder = mVideoView.getHolder();
        }
        if (mediaRecorder != null) {
            mediaRecorder.reset();   // clear recorder configuration
            mediaRecorder.release(); // release the recorder object
            mediaRecorder = null;
            mCamera.lock();           // lock camera for later use
        }
    }

    private void releaseCamera() {
        LogUtils.d("guo_zjin: ", "release Camera here.......");
        if (mCamera != null) {
            mCamera.stopPreview();
            try {
                mCamera.setPreviewDisplay(null);
            } catch (IOException e) {
                e.printStackTrace();
            }
            mCamera.setPreviewCallback(null);
            mCamera.release();
            mCamera = null;
        }
    }

    public void capture() {
        if (autoFocus) {
            mCamera.autoFocus(this);
        } else {
            isPre = true;
            if (SELECTED_CAMERA == CAMERA_POST_POSITION) {
                mCamera.takePicture(null, null, new Camera.PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        mCamera.stopPreview();
                        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                        Matrix matrix = new Matrix();
                        matrix.setRotate(90);
                        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                        pictureBitmap = bitmap;
                        mImageView.setVisibility(INVISIBLE);
                        mCaptureButton.captureSuccess();
                        picPreImageView.setVisibility(VISIBLE);
                        picPreImageView.setImageBitmap(pictureBitmap);
                    }
                });
            } else if (SELECTED_CAMERA == CAMERA_FRONT_POSITION) {
                mCamera.takePicture(null, null, new Camera.PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        mCamera.stopPreview();
                        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                        Matrix matrix = new Matrix();
                        matrix.setRotate(270);
                        matrix.postScale(-1, 1);
                        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                        pictureBitmap = bitmap;
                        mImageView.setVisibility(INVISIBLE);
                        mCaptureButton.captureSuccess();
                        picPreImageView.setVisibility(VISIBLE);
                        picPreImageView.setImageBitmap(pictureBitmap);
                    }
                });
            }
        }
    }

    //自动对焦
    @Override
    public void onAutoFocus(boolean success, Camera camera) {
        if (autoFocus) {
            isPre = true;
            if (SELECTED_CAMERA == CAMERA_POST_POSITION && success) {
                mCamera.takePicture(null, null, new Camera.PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        mCamera.stopPreview();
                        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                        Matrix matrix = new Matrix();
                        matrix.setRotate(90);
                        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                        pictureBitmap = bitmap;
                        mImageView.setVisibility(INVISIBLE);
                        mCaptureButton.captureSuccess();
                        picPreImageView.setVisibility(VISIBLE);
                        picPreImageView.setImageBitmap(pictureBitmap);
                    }
                });
            } else if (SELECTED_CAMERA == CAMERA_FRONT_POSITION) {
                mCamera.takePicture(null, null, new Camera.PictureCallback() {
                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        mCamera.stopPreview();
                        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                        Matrix matrix = new Matrix();
                        matrix.setRotate(270);
                        matrix.postScale(-1, 1);
                        bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                        pictureBitmap = bitmap;
                        mImageView.setVisibility(INVISIBLE);
                        mCaptureButton.captureSuccess();
                        picPreImageView.setVisibility(VISIBLE);
                        picPreImageView.setImageBitmap(pictureBitmap);
                    }
                });
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        float widthSize = MeasureSpec.getSize(widthMeasureSpec);
        float heightSize = MeasureSpec.getSize(heightMeasureSpec);
        screenProp = heightSize / widthSize;
    }

    //    @Override
    //    public void surfaceCreated(SurfaceHolder holder) {
    //        LogUtils.d("拍摄视频", "surfaceCreated");
    //        setStartPreview(mCamera, holder);
    //        mHolder = holder;
    //        LogUtils.d("guo_zjin:surfaceCreated ", mHolder.getSurface().hashCode() + "");
    //    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            if (mCamera != null) {
                mCamera.setPreviewDisplay(holder);
                mHolder = holder;
            }
            LogUtils.d("guo_zjin:surfaceCreated ", mHolder.getSurface().hashCode() + "");
        } catch (IOException exception) {
            Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        LogUtils.d("拍摄视频", "surfaceChanged");
        if (mHolder.getSurface() == null) {
            return;
        }
        mHolder = holder;
        // stop preview before making changes
        try {
            LogUtils.d("guo_zjin:surfaceChanged before stopPreview ", mHolder.hashCode() + "");

            if (null == mCamera) {
                getCamera(SELECTED_CAMERA);
            }
            mCamera.stopPreview();
            LogUtils.d("guo_zjin:surfaceChanged ", mHolder.hashCode() + "");
            setStartPreview(mCamera, holder);
        } catch (Exception e) {
            LogUtils.d("guo_zjin:", "surfaceChanged Exception " + e.getMessage());
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        releaseCamera();
    }

    public void onResume() {
        SystemClock.sleep(500);
        if (mCamera == null) {
            getCamera(SELECTED_CAMERA);
            if (needSetVisible && mVideoView != null) {
                mVideoView.setVisibility(View.VISIBLE);
            } else {
                needSetVisible = true;
            }
            if (mHolder != null && !isPre) {
                setStartPreview(mCamera, mHolder);
            }
        }
        wakeLock.acquire();
    }

    public void onPause() {
        if (wakeLock.isHeld()) {
            wakeLock.release();
        }
        releaseMediaRecorder();
        releaseCamera();
        if (needSetVisible && mVideoView != null) {
            mVideoView.setVisibility(View.INVISIBLE);
        }
    }

    private void startRecord() {
        if (isRecorder) {
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
        }
        if (mCamera == null) {
            stopRecord();
            return;
        }
        mCamera.unlock();
        if (mediaRecorder == null) {
            mediaRecorder = new MediaRecorder();
        }
        mediaRecorder.reset();
        mediaRecorder.setCamera(mCamera);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

        if (android.os.Build.MODEL.contains("vivo X5Pro")) {
            mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
        } else {
            mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        }
        mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        //在1加手机上,如果设置15,直接挂掉,好像是能接受的最大值是30,所以屏蔽掉
        //        mediaRecorder.setVideoFrameRate(15);//帧率

        if (mParam == null) {
            mParam = mCamera.getParameters();
        }
        Camera.Size videoSize = CameraParamUtil.getInstance().getPictureSize(CameraParamUtil.getSupportedVideoSizes
                (mParam), 1000, screenProp);

        mediaRecorder.setVideoSize(videoSize.width, videoSize.height);
        int rotationRecord = CameraParamUtil.getInstance().setCameraDisplayOrientation(activity, SELECTED_CAMERA);
        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(SELECTED_CAMERA, info);
        int frontRotation;
        if (rotationRecord == 180) {
            //反向横屏的前置角度
            frontRotation = 180;
        } else {
            //竖屏和正向横屏的前置角度
            //录制下来的视屏选择角度,此处为前置
            frontRotation = (rotationRecord == 0) ? 270 - info.orientation : info.orientation;
        }
        mediaRecorder.setOrientationHint((SELECTED_CAMERA == 1) ? frontRotation : rotationRecord);
        mediaRecorder.setMaxDuration(10000);
        mediaRecorder.setVideoEncodingBitRate(1024 * 1024);
        mediaRecorder.setPreviewDisplay(mHolder.getSurface());

        videoFileName = "/myimage/video_" + System.currentTimeMillis() + ".mp4";
        File file = new File(PathUtil.getPathFile(), videoFileName);
        FileUtil.checkFilePath(file, false);
        mediaRecorder.setOutputFile(file.getPath());
        try {
            mediaRecorder.prepare();
            mediaRecorder.start();
            isRecorder = true;
            mImageView.setVisibility(INVISIBLE);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            LogUtils.d("错误", e.getMessage());
        }
    }

    private void stopRecord() {
        if (mediaRecorder != null) {
            mediaRecorder.setOnErrorListener(new MediaRecorder.OnErrorListener() {
                @Override
                public void onError(MediaRecorder mr, int what, int extra) {
                    ToastUtil.toastShort("视频过短,请重新录制");
                    if (mr != null) {
                        mr.reset();
                    }
                    mediaRecorder.release();
                    mediaRecorder = null;
                    isRecorder = false;
                    fileName = PathUtil.getPathFile() + videoFileName;
                    File file = new File(fileName);
                    if (file.exists()) {
                        file.delete();
                    }
                    releaseCamera();
                    getCamera(SELECTED_CAMERA);
                    isPlay = false;
                    setStartPreview(mCamera, mHolder);
                    mCaptureButton.initButton();
                }
            });

            mediaRecorder.setOnInfoListener(null);
            mediaRecorder.setPreviewDisplay(null);
            try {
                mediaRecorder.stop();
                mediaRecorder.release();
                mediaRecorder = null;
                isRecorder = false;
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }

            releaseCamera();

            mImageView.setVisibility(INVISIBLE);

            fileName = PathUtil.getPathFile() + videoFileName;
            File file = new File(fileName);
            if (file.exists() && file.length() > 0) {
                mVideoView.setVideoPath(fileName);
                mVideoView.start();

                mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        isPlay = true;
                        mp.start();
                        mp.setLooping(true);
                    }
                });
                mVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        if (fileName != null) {
                            mVideoView.setVideoPath(fileName);
                            mVideoView.start();
                        }
                    }
                });

                mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                    @Override
                    public boolean onError(MediaPlayer mp, int what, int extra) {
                        LogUtils.d("guo_zjin:", "mVideoView.setOnErrorListener,被release");
                        if (!isPre) {
                            releasePre();
                        }
                        return true;
                    }
                });
            } else {
                ToastUtil.toastShort("视频不存在,赶紧重拍一个吧~");
                LogUtils.d("guo_zjin:", "stopRecorder,被release");
                releasePre();
            }
        }
    }

    //关闭预览
    private void releasePre() {
        if (mVideoView != null && mVideoView.isPlaying()) {
            mVideoView.stopPlayback();
        }
        if (mHolder != null) {
            mHolder.getSurface().release();
        }
        mCaptureButton.initButton();
        picPreImageView.setVisibility(INVISIBLE);
        // 区分一下是照片还是视频
        releaseCamera();
        isPre = false;
        isPlay = false;
        getCamera(SELECTED_CAMERA);
        setStartPreview(mCamera, mHolder);
    }

    /**
     * 获得可用的相机,并设置前后摄像机的ID
     */
    private void findAvailableCameras() {
        Camera.CameraInfo info = new Camera.CameraInfo();
        int numCamera = Camera.getNumberOfCameras();
        for (int i = 0; i < numCamera; i++) {
            Camera.getCameraInfo(i, info);
            // 找到了前置摄像头
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                CAMERA_FRONT_POSITION = info.facing;
            }
            // 找到了后置摄像头
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                CAMERA_POST_POSITION = info.facing;
            }
        }
    }

    public void setAutoFocus(boolean autoFocus) {
        this.autoFocus = autoFocus;
    }

    private int count = 0;

    @Override
    public void onFocusBegin(float x, float y) {
        mFocusView.setVisibility(VISIBLE);
        mFocusView.setX(x - mFocusView.getWidth() / 2);
        mFocusView.setY(y - mFocusView.getHeight() / 2);
        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if (!success) {
                    count++;
                    if (count > 3) {
                        mCamera.cancelAutoFocus();
                        onFocusEnd();
                        count = 0;
                    }
                }
                if (success) {
                    mCamera.cancelAutoFocus();
                    onFocusEnd();
                    count = 0;
                }
            }
        });
    }

    //手动对焦结束
    @Override
    public void onFocusEnd() {
        mFocusView.setVisibility(INVISIBLE);
    }

    public interface CameraViewListener {
        void quit();//关闭界面

        void captureSuccess(Bitmap bitmap);

        void recordSuccess(String url);
    }

    @Override
    public boolean onTouchEvent(final MotionEvent event) {
        if (!autoFocus && event.getAction() == MotionEvent.ACTION_DOWN && SELECTED_CAMERA == CAMERA_POST_POSITION &&
                !isPlay && !isPre) {
            if (mCamera != null) {
                mParam = mCamera.getParameters();
                mParam.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                mCamera.setParameters(mParam);
            }
            onFocusBegin(event.getX(), event.getY());
        }
        return super.onTouchEvent(event);
    }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,900评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,068评论 4 62
  • hide([speed,[fn]])     隐藏显示的元素    参数:speed:三种预定速度之一的字符串("...
    w_01阅读 210评论 0 0
  • 著名教育家苏霍姆林斯基曾经说过:“教育教学的全部奥秘就在于如何爱护学生,如果你讨厌你的学生,那么你的教育还没开始就...
    纷飞的落叶飘过阅读 623评论 0 1
  • 什么样的姑娘是好姑娘? 1.面容姣好,身材很好 2.上得厅堂,下得厨房 3.孝顺父母,相夫教子 4.为人善良,简单...
    叶轻筠阅读 643评论 6 7