Android仿最新微信相机功能

时间:2019-04-15
本文章向大家介绍Android仿最新微信相机功能,主要包括Android仿最新微信相机功能使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

最近在开发即时通讯这个模块的时候使用到了自定义的相机,需求与微信一样,要求相机能长按和轻点,当时在网上找自定义相机的资源,很少,所以,我在这里把我的一些开发经验贴出来,供大家学习。

大致完成的功能如下:

  • 长按拍摄视频,轻点拍照
  • 前后摄像头的切换
  • 闪光的的开启,关闭,自动
  • 图片的压缩
  • 自动聚焦,手动聚焦

效果图如下:

相关代码如下:

package com.ses.im.app.chat.newcamera;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.PointF;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.ses.im.app.chat.R;

import java.io.File;
import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;


/**
 *
 * 拍摄界面
 */
public class CameraActivity extends AppCompatActivity implements View.OnClickListener {
 /**
  * 获取相册
  */
 public static final int REQUEST_PHOTO = 1;
 /**
  * 获取视频
  */
 public static final int REQUEST_VIDEO = 2;
 /**
  * 最小录制时间
  */
 private static final int MIN_RECORD_TIME = 1 * 1000;
 /**
  * 最长录制时间
  */
 private static final int MAX_RECORD_TIME = 15 * 1000;
 /**
  * 刷新进度的间隔时间
  */
 private static final int PLUSH_PROGRESS = 100;

 private Context mContext;
 /**
  * TextureView
  */
 private TextureView mTextureView;
 /**
  * 带手势识别
  */
 private CameraView mCameraView;
 /**
  * 录制按钮
  */
 private CameraProgressBar mProgressbar;
 /**
  * 顶部像机设置
  */
 private RelativeLayout rl_camera;
 /**
  * 关闭,选择,前后置
  */
 private ImageView iv_close, iv_facing;
 private RelativeLayout iv_choice;
 private RelativeLayout cancel;
 /**
  * 闪光
  */
 private TextView tv_flash;
 /**
  * camera manager
  */
 private CameraManager cameraManager;
 /**
  * player manager
  */
 private MediaPlayerManager playerManager;
 /**
  * true代表视频录制,否则拍照
  */
 private boolean isSupportRecord;
 /**
  * 视频录制地址
  */
 private String recorderPath;
 /**
  * 图片地址
  */
 private String photoPath;
 /**
  * 录制视频的时间,毫秒
  */
 private int recordSecond;
 /**
  * 获取照片订阅, 进度订阅
  */
 private Subscription takePhotoSubscription, progressSubscription;
 /**
  * 是否正在录制
  */
 private boolean isRecording;

 /**
  * 是否为点了拍摄状态(没有拍照预览的状态)
  */
 private boolean isPhotoTakingState;

 public static void lanuchForPhoto(Activity context) {
  Intent intent = new Intent(context, CameraActivity.class);
  context.startActivityForResult(intent, REQUEST_PHOTO);
 }

 @Override
 protected void onCreate(@Nullable Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  mContext = this;
  setContentView(R.layout.activity_camera);
  initView();
  initDatas();
 }

 private void initView() {
  mTextureView = (TextureView) findViewById(R.id.mTextureView);
  mCameraView = (CameraView) findViewById(R.id.mCameraView);
  mProgressbar = (CameraProgressBar) findViewById(R.id.mProgressbar);
  rl_camera = (RelativeLayout) findViewById(R.id.rl_camera);
  iv_close = (ImageView) findViewById(R.id.iv_close);
  iv_close.setOnClickListener(this);
  iv_choice = (RelativeLayout) findViewById(R.id.iv_choice);
  iv_choice.setOnClickListener(this);
  iv_close.setOnClickListener(this);
  iv_facing = (ImageView) findViewById(R.id.iv_facing);
  iv_facing.setOnClickListener(this);
  iv_close.setOnClickListener(this);
  tv_flash = (TextView) findViewById(R.id.tv_flash);
  tv_flash.setOnClickListener(this);
  cancel= (RelativeLayout) findViewById(R.id.cancel);
  cancel.setOnClickListener(this);
 }

 protected void initDatas() {
  cameraManager = CameraManager.getInstance(getApplication());
  playerManager = MediaPlayerManager.getInstance(getApplication());
  cameraManager.setCameraType(isSupportRecord ? 1 : 0);

  tv_flash.setVisibility(cameraManager.isSupportFlashCamera() ? View.VISIBLE : View.GONE);
  setCameraFlashState();
  iv_facing.setVisibility(cameraManager.isSupportFrontCamera() ? View.VISIBLE : View.GONE);
  rl_camera.setVisibility(cameraManager.isSupportFlashCamera()
    || cameraManager.isSupportFrontCamera() ? View.VISIBLE : View.GONE);

  final int max = MAX_RECORD_TIME / PLUSH_PROGRESS;
  mProgressbar.setMaxProgress(max);

  /**
   * 拍照,拍摄按钮监听
   */
  mProgressbar.setOnProgressTouchListener(new CameraProgressBar.OnProgressTouchListener() {
   @Override
   public void onClick(CameraProgressBar progressBar) {
    cameraManager.takePhoto(callback);
    isSupportRecord = false;
   }

   @Override
   public void onLongClick(CameraProgressBar progressBar) {
    isSupportRecord = true;
    cameraManager.setCameraType(1);
    rl_camera.setVisibility(View.GONE);
    recorderPath = FileUtils.getUploadVideoFile(mContext);
    cameraManager.startMediaRecord1(recorderPath);
    isRecording = true;
    progressSubscription = Observable.interval(100, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread()).take(max).subscribe(new Subscriber<Long>() {
     @Override
     public void onCompleted() {
      stopRecorder(true);
     }

     @Override
     public void onError(Throwable e) {

     }

     @Override
     public void onNext(Long aLong) {
      mProgressbar.setProgress(mProgressbar.getProgress() + 1);
     }
    });
   }

   @Override
   public void onZoom(boolean zoom) {
    cameraManager.handleZoom(zoom);
   }

   @Override
   public void onLongClickUp(CameraProgressBar progressBar) {
//    isSupportRecord = false;
    cameraManager.setCameraType(0);
    stopRecorder(true);
    if (progressSubscription != null) {
     progressSubscription.unsubscribe();
    }
   }

   @Override
   public void onPointerDown(float rawX, float rawY) {
    if (mTextureView != null) {
     mCameraView.setFoucsPoint(new PointF(rawX, rawY));
    }
   }
  });

  /**
   *点击预览图聚焦 
   */
  mCameraView.setOnViewTouchListener(new CameraView.OnViewTouchListener() {
   @Override
   public void handleFocus(float x, float y) {
    cameraManager.handleFocusMetering(x, y);
   }

   @Override
   public void handleZoom(boolean zoom) {
    cameraManager.handleZoom(zoom);
   }
  });
 }

 /**
  * 设置闪光状态
  */
 private void setCameraFlashState() {
  int flashState = cameraManager.getCameraFlash();
  switch (flashState) {
   case 0: //自动
    tv_flash.setSelected(true);
    tv_flash.setText("自动");
    break;
   case 1://open
    tv_flash.setSelected(true);
    tv_flash.setText("开启");
    break;
   case 2: //close
    tv_flash.setSelected(false);
    tv_flash.setText("关闭");
    break;
  }
 }

 /**
  * 是否显示录制按钮
  * @param isShow
  */
 private void setTakeButtonShow(boolean isShow) {
  if (isShow) {
   mProgressbar.setVisibility(View.VISIBLE);
   rl_camera.setVisibility(cameraManager.isSupportFlashCamera()
     || cameraManager.isSupportFrontCamera() ? View.VISIBLE : View.GONE);
  } else {
   mProgressbar.setVisibility(View.GONE);
   rl_camera.setVisibility(View.GONE);
  }
 }

 /**
  * 停止拍摄
  */
 private void stopRecorder(boolean play) {
  isRecording = false;
  cameraManager.stopMediaRecord();
  recordSecond = mProgressbar.getProgress() * PLUSH_PROGRESS;//录制多少毫秒
  mProgressbar.reset();
  if (recordSecond < MIN_RECORD_TIME) {//小于最小录制时间作废
   if (recorderPath != null) {
    FileUtils.delteFiles(new File(recorderPath));
    recorderPath = null;
    recordSecond = 0;
   }
   setTakeButtonShow(true);
  } else if (play && mTextureView != null && mTextureView.isAvailable()){
   setTakeButtonShow(false);
   mProgressbar.setVisibility(View.GONE);
   iv_choice.setVisibility(View.VISIBLE);
   cancel.setVisibility(View.VISIBLE);
   iv_close.setVisibility(View.GONE);
   cameraManager.closeCamera();
   playerManager.playMedia(new Surface(mTextureView.getSurfaceTexture()), recorderPath);
  }
 }

 @Override
 protected void onResume() {
  super.onResume();
  if (mTextureView.isAvailable()) {
   if (recorderPath != null) {//优先播放视频
    iv_choice.setVisibility(View.VISIBLE);
    setTakeButtonShow(false);
    playerManager.playMedia(new Surface(mTextureView.getSurfaceTexture()), recorderPath);
   } else {
    iv_choice.setVisibility(View.GONE);
    setTakeButtonShow(true);
    cameraManager.openCamera(mTextureView.getSurfaceTexture(),
      mTextureView.getWidth(), mTextureView.getHeight());
   }
  } else {
   mTextureView.setSurfaceTextureListener(listener);
  }
 }

 @Override
 protected void onPause() {
  if (progressSubscription != null) {
   progressSubscription.unsubscribe();
  }
  if (takePhotoSubscription != null) {
   takePhotoSubscription.unsubscribe();
  }
  if (isRecording) {
   stopRecorder(false);
  }
  cameraManager.closeCamera();
  playerManager.stopMedia();
  super.onPause();
 }

 @Override
 protected void onDestroy() {
  mCameraView.removeOnZoomListener();
  super.onDestroy();
 }

 @Override
 public void onClick(View v) {
  int i = v.getId();
  if (i == R.id.iv_close) {
//   if (recorderPath != null) {//有拍摄好的正在播放,重新拍摄
//    FileUtils.delteFiles(new File(recorderPath));
//    recorderPath = null;
//    recordSecond = 0;
//    playerManager.stopMedia();
//    setTakeButtonShow(true);
//    iv_choice.setVisibility(View.GONE);
//    cameraManager.openCamera(mTextureView.getSurfaceTexture(), mTextureView.getWidth(), mTextureView.getHeight());
//   } else if (isPhotoTakingState) {
//    isPhotoTakingState = false;
//    iv_choice.setVisibility(View.GONE);
//    setTakeButtonShow(true);
//    cameraManager.restartPreview();
//   } else {
    finish();
//   }

  } else if (i == R.id.iv_choice) {//拿到图片或视频路径
   Intent intent=new Intent();
   if(isSupportRecord){
    intent.putExtra("videopath", recorderPath);
    setResult(3, intent);
    finish();
   }else{
    intent.putExtra("videopath", photoPath);
    setResult(3, intent);
    finish();
   }



  } else if (i == R.id.tv_flash) {
   cameraManager.changeCameraFlash(mTextureView.getSurfaceTexture(),
     mTextureView.getWidth(), mTextureView.getHeight());
   setCameraFlashState();

  } else if (i == R.id.iv_facing) {
   cameraManager.changeCameraFacing(mTextureView.getSurfaceTexture(),
     mTextureView.getWidth(), mTextureView.getHeight());

  }else if(i == R.id.cancel){
   if (recorderPath != null) {//有拍摄好的正在播放,重新拍摄
    FileUtils.delteFiles(new File(recorderPath));
    recorderPath = null;
    recordSecond = 0;
    playerManager.stopMedia();
    setTakeButtonShow(true);
    iv_choice.setVisibility(View.GONE);
    cancel.setVisibility(View.GONE);
    iv_close.setVisibility(View.VISIBLE);

    cameraManager.openCamera(mTextureView.getSurfaceTexture(), mTextureView.getWidth(), mTextureView.getHeight());
   } else if (isPhotoTakingState) {
    isPhotoTakingState = false;
    iv_choice.setVisibility(View.GONE);
    cancel.setVisibility(View.GONE);
    iv_close.setVisibility(View.VISIBLE);
    setTakeButtonShow(true);
    cameraManager.restartPreview();
   }
  }
 }

 /**
  * camera回调监听
  */
 private TextureView.SurfaceTextureListener listener = new TextureView.SurfaceTextureListener() {
  @Override
  public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
   if (recorderPath != null) {
    iv_choice.setVisibility(View.VISIBLE);
    setTakeButtonShow(false);
    playerManager.playMedia(new Surface(texture), recorderPath);
   } else {
    setTakeButtonShow(true);
    iv_choice.setVisibility(View.GONE);
    cameraManager.openCamera(texture, width, height);
   }
  }

  @Override
  public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
  }

  @Override
  public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
   return true;
  }

  @Override
  public void onSurfaceTextureUpdated(SurfaceTexture texture) {
  }
 };

 private Camera.PictureCallback callback = new Camera.PictureCallback() {
  @Override
  public void onPictureTaken(final byte[] data, Camera camera) {
   setTakeButtonShow(false);
   takePhotoSubscription = Observable.create(new Observable.OnSubscribe<Boolean>() {
    @Override
    public void call(Subscriber<? super Boolean> subscriber) {
     if (!subscriber.isUnsubscribed()) {
      photoPath = FileUtils.getUploadPhotoFile(mContext);
      isPhotoTakingState = FileUtils.savePhoto(photoPath, data, cameraManager.isCameraFrontFacing());
      subscriber.onNext(isPhotoTakingState);
     }
    }
   }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<Boolean>() {
    @Override
    public void onCompleted() {

    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onNext(Boolean aBoolean) {
     if (aBoolean != null && aBoolean) {
      iv_choice.setVisibility(View.VISIBLE);
      cancel.setVisibility(View.VISIBLE);
      iv_close.setVisibility(View.GONE);
     } else {
      setTakeButtonShow(true);
     }
    }
   });
  }
 };

}

相机管理类:

package com.ses.im.app.chat.newcamera;

import android.app.Application;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.util.Log;
import android.widget.Toast;

import com.ses.im.app.chat.util.AppConfig;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 
 * 相机管理类
 */

public final class CameraManager {

 private Application context;
 /**
  * camera
  */
 private Camera mCamera;
 private Camera.Parameters mParameters;
 /**
  * 视频录制
  */
 private MediaRecorder mMediaRecorder;
 /**
  * 相机闪光状态
  */
 private int cameraFlash;
 /**
  * 前后置状态
  */
 private int cameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;
 /**
  * 是否支持前置摄像,是否支持闪光
  */
 private boolean isSupportFrontCamera, isSupportFlashCamera;
 /**
  * 录制视频的相关参数
  */
 private CamcorderProfile mProfile;
 /**
  * 0为拍照, 1为录像
  */
 private int cameraType;

 private CameraManager(Application context) {
  this.context = context;
  isSupportFrontCamera = CameraUtils.isSupportFrontCamera();
  isSupportFlashCamera = CameraUtils.isSupportFlashCamera(context);
  if (isSupportFrontCamera) {
   cameraFacing = CameraUtils.getCameraFacing(context, Camera.CameraInfo.CAMERA_FACING_BACK);
  }
  if (isSupportFlashCamera) {
   cameraFlash = CameraUtils.getCameraFlash(context);
  }
 }

 private static CameraManager INSTANCE;

 public static CameraManager getInstance(Application context) {
  if (INSTANCE == null) {
   synchronized (CameraManager.class) {
    if (INSTANCE == null) {
     INSTANCE = new CameraManager(context);
    }
   }
  }
  return INSTANCE;
 }

 /**
  * 打开camera
  */
 public void openCamera(SurfaceTexture surfaceTexture, int width, int height) {
  if (mCamera == null) {
   mCamera = Camera.open(cameraFacing);//打开当前选中的摄像头
   mProfile = CamcorderProfile.get(cameraFacing, CamcorderProfile.QUALITY_HIGH);
   try {
    mCamera.setDisplayOrientation(90);//默认竖直拍照
    mCamera.setPreviewTexture(surfaceTexture);
    initCameraParameters(cameraFacing, width, height);
    mCamera.startPreview();
   } catch (Exception e) {
    LogUtils.i(e);
    if (mCamera != null) {
     mCamera.release();
     mCamera = null;
    }
   }
  }
 }

 /**
  * 开启预览,前提是camera初始化了
  */
 public void restartPreview() {
  if (mCamera == null) return;
  try {
   Camera.Parameters parameters = mCamera.getParameters();
   int zoom = parameters.getZoom();
   if (zoom > 0) {
    parameters.setZoom(0);
    mCamera.setParameters(parameters);
   }
   mCamera.startPreview();
  } catch (Exception e) {
   LogUtils.i(e);
   if (mCamera != null) {
    mCamera.release();
    mCamera = null;
   }
  }
 }

 private void initCameraParameters(int cameraId, int width, int height) {
  Camera.Parameters parameters = mCamera.getParameters();
  if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
   List<String> focusModes = parameters.getSupportedFocusModes();
   if (focusModes != null) {
    if (cameraType == 0) {
     if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
      parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
     }
    } else {
     if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
      parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
     }
    }
   }
  }
  parameters.setRotation(90);//设置旋转代码,
  switch (cameraFlash) {
   case 0:
    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
    break;
   case 1:
    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
    break;
   case 2:
    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
    break;
  }
  List<Camera.Size> pictureSizes = parameters.getSupportedPictureSizes();
  List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
  if (!isEmpty(pictureSizes) && !isEmpty(previewSizes)) {
   /**
   for (Camera.Size size : pictureSizes) {
    LogUtils.i("pictureSize " + size.width + " " + size.height);
   }
   for (Camera.Size size : pictureSizes) {
    LogUtils.i("previewSize " + size.width + " " + size.height);
   }*/
   Camera.Size optimalPicSize = getOptimalCameraSize(pictureSizes, width, height);
   Camera.Size optimalPreSize = getOptimalCameraSize(previewSizes, width, height);
//   Camera.Size optimalPicSize = getOptimalSize(pictureSizes, width, height);
//   Camera.Size optimalPreSize = getOptimalSize(previewSizes, width, height);
   LogUtils.i("TextureSize "+width+" "+height+" optimalSize pic " + optimalPicSize.width + " " + optimalPicSize.height + " pre " + optimalPreSize.width + " " + optimalPreSize.height);
   parameters.setPictureSize(optimalPicSize.width, optimalPicSize.height);
   parameters.setPreviewSize(optimalPreSize.width, optimalPreSize.height);
   mProfile.videoFrameWidth = optimalPreSize.width;
   mProfile.videoFrameHeight = optimalPreSize.height;
   mProfile.videoBitRate = 5000000;//此参数主要决定视频拍出大小
  }
  mCamera.setParameters(parameters);
 }

 /**
  * 释放摄像头
  */
 public void closeCamera() {
  this.cameraType = 0;
  if (mCamera != null) {
   try {
    mCamera.stopPreview();
    mCamera.release();
    mCamera = null;
   } catch (Exception e) {
    LogUtils.i(e);
    if (mCamera != null) {
     mCamera.release();
     mCamera = null;
    }
   }
  }
 }

 /**
  * 集合不为空
  *
  * @param list
  * @param <E>
  * @return
  */
 private <E> boolean isEmpty(List<E> list) {
  return list == null || list.isEmpty();
 }

 /**
  *
  * @param sizes 相机support参数
  * @param w
  * @param h
  * @return 最佳Camera size
  */
 private Camera.Size getOptimalCameraSize(List<Camera.Size> sizes, int w, int h){
  sortCameraSize(sizes);
  int position = binarySearch(sizes, w*h);
  return sizes.get(position);
 }

 /**
  *
  * @param sizes
  * @param targetNum 要比较的数
  * @return
  */
 private int binarySearch(List<Camera.Size> sizes,int targetNum){
  int targetIndex;
  int left = 0,right;
  int length = sizes.size();
  for (right = length-1;left != right;){
   int midIndex = (right + left)/2;
   int mid = right - left;
   Camera.Size size = sizes.get(midIndex);
   int midValue = size.width * size.height;
   if (targetNum == midValue){
    return midIndex;
   }
   if (targetNum > midValue){
    left = midIndex;
   }else {
    right = midIndex;
   }

   if (mid <= 1){
    break;
   }
  }
  Camera.Size rightSize = sizes.get(right);
  Camera.Size leftSize = sizes.get(left);
  int rightNum = rightSize.width * rightSize.height;
  int leftNum = leftSize.width * leftSize.height;
  targetIndex = Math.abs((rightNum - leftNum)/2) > Math.abs(rightNum - targetNum) ? right : left;
  return targetIndex;
 }

 /**
  * 排序
  * @param previewSizes
  */
 private void sortCameraSize(List<Camera.Size> previewSizes){
  Collections.sort(previewSizes, new Comparator<Camera.Size>() {
   @Override
   public int compare(Camera.Size size1, Camera.Size size2) {
    int compareHeight = size1.height - size2.height;
    if (compareHeight == 0){
     return (size1.width == size2.width ? 0 :(size1.width > size2.width ? 1:-1));
    }
    return compareHeight;
   }
  });
 }



 /**
  * 获取最佳预览相机Size参数
  *
  * @return
  */
 private Camera.Size getOptimalSize(List<Camera.Size> sizes, int w, int h) {
  Camera.Size optimalSize = null;
  float targetRadio = h / (float) w;
  float optimalDif = Float.MAX_VALUE; //最匹配的比例
  int optimalMaxDif = Integer.MAX_VALUE;//最优的最大值差距
  for (Camera.Size size : sizes) {
   float newOptimal = size.width / (float) size.height;
   float newDiff = Math.abs(newOptimal - targetRadio);
   if (newDiff < optimalDif) { //更好的尺寸
    optimalDif = newDiff;
    optimalSize = size;
    optimalMaxDif = Math.abs(h - size.width);
   } else if (newDiff == optimalDif) {//更好的尺寸
    int newOptimalMaxDif = Math.abs(h - size.width);
    if (newOptimalMaxDif < optimalMaxDif) {
     optimalDif = newDiff;
     optimalSize = size;
     optimalMaxDif = newOptimalMaxDif;
    }
   }
  }
  return optimalSize;
 }

 /**
  * 缩放
  * @param isZoomIn
  */
 public void handleZoom(boolean isZoomIn) {
  if (mCamera == null) return;
  Camera.Parameters params = mCamera.getParameters();
  if (params == null) return;
  if (params.isZoomSupported()) {
   int maxZoom = params.getMaxZoom();
   int zoom = params.getZoom();
   if (isZoomIn && zoom < maxZoom) {
    zoom++;
   } else if (zoom > 0) {
    zoom--;
   }
   params.setZoom(zoom);
   mCamera.setParameters(params);
  } else {
   LogUtils.i("zoom not supported");
  }
 }

 /**
  * 更换前后置摄像
  */
 public void changeCameraFacing(SurfaceTexture surfaceTexture, int width, int height) {
  if(isSupportFrontCamera) {
   Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
   int cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数
   for(int i = 0; i < cameraCount; i++) {
    Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
    if(cameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) { //现在是后置,变更为前置
     if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位为前置
      closeCamera();
      cameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;
      CameraUtils.setCameraFacing(context, cameraFacing);
      openCamera(surfaceTexture, width, height);
      break;
     }
    } else {//现在是前置, 变更为后置
     if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位
      closeCamera();
      cameraFacing = Camera.CameraInfo.CAMERA_FACING_FRONT;
      CameraUtils.setCameraFacing(context, cameraFacing);
      openCamera(surfaceTexture, width, height);
      break;
     }
    }
   }
  } else { //不支持摄像机
   Toast.makeText(context, "您的手机不支持前置摄像", Toast.LENGTH_SHORT).show();
  }
 }

 /**
  * 改变闪光状态
  */
 public void changeCameraFlash(SurfaceTexture surfaceTexture, int width, int height) {
  if (!isSupportFlashCamera) {
   Toast.makeText(context, "您的手机不支闪光", Toast.LENGTH_SHORT).show();
   return;
  }
  if(mCamera != null) {
   Camera.Parameters parameters = mCamera.getParameters();
   if(parameters != null) {
    int newState = cameraFlash;
    switch (cameraFlash) {
     case 0: //自动
      parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
      newState = 1;
      break;
     case 1://open
      parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
      newState = 2;
      break;
     case 2: //close
      parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
      newState = 0;
      break;
    }
    cameraFlash = newState;
    CameraUtils.setCameraFlash(context, newState);
    mCamera.setParameters(parameters);
   }
  }
 }

 /**
  * 拍照
  */
 public void takePhoto(Camera.PictureCallback callback) {
  if (mCamera != null) {
   try {
    mCamera.takePicture(null, null, callback);
   } catch(Exception e) {
    Toast.makeText(context, "拍摄失败", Toast.LENGTH_SHORT).show();
   }
  }
 }

 /**
  * 开始录制视频
  */
// public void startMediaRecord(String savePath) {
//  if (mCamera == null || mProfile == null) return;
//  mCamera.unlock();
//  if (mMediaRecorder == null) {
//   mMediaRecorder = new MediaRecorder();
//  }
//  if (isCameraFrontFacing()) {
//   mMediaRecorder.setOrientationHint(270);
//   Log.i("wujie","front");
//  }else
//  {
//   Log.i("wujie","back");
//   mMediaRecorder.setOrientationHint(90);
//  }
//  mMediaRecorder.reset();
//  mMediaRecorder.setCamera(mCamera);
//  mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//  mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
//  mMediaRecorder.setProfile(mProfile);
//  mMediaRecorder.setOutputFile(savePath);
//  try {
//   mMediaRecorder.prepare();
//   mMediaRecorder.start();
//  } catch (Exception e) {
//   e.printStackTrace();
//
//  }
// }
 /**
  * 开始录制视频
  */
 public void startMediaRecord1(String savePath) {
  if (mCamera == null) {
   return;
  }
  if (mMediaRecorder == null) {
   mMediaRecorder = new MediaRecorder();
  } else {
   mMediaRecorder.reset();
  }


  if (isCameraFrontFacing()) {
   mMediaRecorder.setOrientationHint(270);
   Log.i("wujie","front");
  }else
  {
   Log.i("wujie","back");
   mMediaRecorder.setOrientationHint(90);
  }
  mParameters = mCamera.getParameters();
  mCamera.unlock();
  mMediaRecorder.setCamera(mCamera);
  mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
  mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  // 设置录像参数
  mMediaRecorder.setProfile(CamcorderProfile.get(AppConfig.VIDEOSIZE));
  try {
   mMediaRecorder.setOutputFile(savePath);
   mMediaRecorder.prepare();
   mMediaRecorder.start();
  } catch (Exception e) {

  }

 }

 /**
  * 停止录制
  */
 public void stopMediaRecord() {
  this.cameraType = 0;
  stopRecorder();
  releaseMediaRecorder();
 }

 private void releaseMediaRecorder() {
  if (mMediaRecorder != null) {
   try {
    mMediaRecorder.reset();
    mMediaRecorder.release();
    mMediaRecorder = null;
    mCamera.lock();
   } catch (Exception e) {
    e.printStackTrace();
    LogUtils.i(e);
   }
  }
 }

 private void stopRecorder() {
  if (mMediaRecorder != null) {
   try {
    mMediaRecorder.stop();
   } catch (Exception e) {
    e.printStackTrace();
    LogUtils.i(e);
   }

  }
 }

 public boolean isSupportFrontCamera() {
  return isSupportFrontCamera;
 }

 public boolean isSupportFlashCamera() {
  return isSupportFlashCamera;
 }

 public boolean isCameraFrontFacing() {
  return cameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT;
 }

 /**
  * 设置对焦类型
  * @param cameraType
  */
 public void setCameraType(int cameraType) {
  this.cameraType = cameraType;
  if (mCamera != null) {//拍摄视频时
   if (cameraFacing == Camera.CameraInfo.CAMERA_FACING_BACK) {
    Camera.Parameters parameters = mCamera.getParameters();
    List<String> focusModes = parameters.getSupportedFocusModes();
    if (focusModes != null) {
     if (cameraType == 0) {
      if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
       parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
      }
     } else {
      if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
       parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
      }
     }
    }
   }
  }
 }

 public int getCameraFlash() {
  return cameraFlash;
 }

 /**
  * 对焦
  * @param x
  * @param y
  */
 public void handleFocusMetering(float x, float y) {
  if(mCamera!=null){
   Camera.Parameters params = mCamera.getParameters();
   Camera.Size previewSize = params.getPreviewSize();
   Rect focusRect = calculateTapArea(x, y, 1f, previewSize);
   Rect meteringRect = calculateTapArea(x, y, 1.5f, previewSize);
   mCamera.cancelAutoFocus();

   if (params.getMaxNumFocusAreas() > 0) {
    List<Camera.Area> focusAreas = new ArrayList<>();
    focusAreas.add(new Camera.Area(focusRect, 1000));
    params.setFocusAreas(focusAreas);
   } else {
    LogUtils.i("focus areas not supported");
   }
   if (params.getMaxNumMeteringAreas() > 0) {
    List<Camera.Area> meteringAreas = new ArrayList<>();
    meteringAreas.add(new Camera.Area(meteringRect, 1000));
    params.setMeteringAreas(meteringAreas);
   } else {
    LogUtils.i("metering areas not supported");
   }
   final String currentFocusMode = params.getFocusMode();
   params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
   mCamera.setParameters(params);

   mCamera.autoFocus(new Camera.AutoFocusCallback() {
    @Override
    public void onAutoFocus(boolean success, Camera camera) {
     Camera.Parameters params = camera.getParameters();
     params.setFocusMode(currentFocusMode);
     camera.setParameters(params);
    }
   });
  }

 }

 private Rect calculateTapArea(float x, float y, float coefficient, Camera.Size previewSize) {
  float focusAreaSize = 300;
  int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();
  int centerX = (int) (x / previewSize.width - 1000);
  int centerY = (int) (y / previewSize.height - 1000);
  int left = clamp(centerX - areaSize / 2, -1000, 1000);
  int top = clamp(centerY - areaSize / 2, -1000, 1000);
  RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);
  return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom));
 }

 private int clamp(int x, int min, int max) {
  if (x > max) {
   return max;
  }
  if (x < min) {
   return min;
  }
  return x;
 }

}

自定义拍摄,拍照按钮:

package com.ses.im.app.chat.newcamera;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

import com.ses.im.app.chat.R;

/**
 * 自定义拍照,拍摄按钮
 */

public class CameraProgressBar extends View {
 /**
  * 默认缩小值
  */
 public static final float DEF_SCALE = 0.75F;
 /**
  * 默认缩小值
  */
 private float scale = DEF_SCALE;

 /**
  * 内圆颜色
  */
 private int innerColor = Color.GRAY;
 /**
  * 背景颜色
  */
 private int backgroundColor = Color.WHITE;
 /**
  * 外圆颜色
  */
 private int outerColor = Color.parseColor("#e9e9e9");
 /**
  * 进度颜色
  */
 private int progressColor = Color.parseColor("#0ebffa");
 /**
  * 进度宽
  */
 private int progressWidth = 15;
 /**
  * 内圆宽度
  */
 private int innerRadio = 10;
 /**
  * 进度
  */
 private int progress;
 /**
  * 最大进度
  */
 private int maxProgress = 100;
 /**
  * paint
  */
 private Paint backgroundPaint, progressPaint, innerPaint;
 /**
  * 圆的中心坐标点, 进度百分比
  */
 private float sweepAngle;
 /**
  * 手识识别
  */
 private GestureDetectorCompat mDetector;
 /**
  * 是否为长按录制
  */
 private boolean isLongClick;
 /**
  * 是否产生滑动
  */
 private boolean isBeingDrag;
 /**
  * 滑动单位
  */
 private int mTouchSlop;
 /**
  * 记录上一次Y轴坐标点
  */
 private float mLastY;
 /**
  * 是否长按放大
  */
 private boolean isLongScale;


 public CameraProgressBar(Context context) {
  super(context);
  init(context, null);
 }

 public CameraProgressBar(Context context, AttributeSet attrs) {
  super(context, attrs);
  init(context, attrs);
 }

 public CameraProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init(context, attrs);
 }

 private void init(Context context, AttributeSet attrs) {
  mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
  if (attrs != null) {
   TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CameraProgressBar);
   innerColor = a.getColor(R.styleable.CameraProgressBar_innerColor, innerColor);
   outerColor = a.getColor(R.styleable.CameraProgressBar_outerColor, outerColor);
   progressColor = a.getColor(R.styleable.CameraProgressBar_progressColor, progressColor);
   innerRadio = a.getDimensionPixelOffset(R.styleable.CameraProgressBar_innerRadio, innerRadio);
   progressWidth = a.getDimensionPixelOffset(R.styleable.CameraProgressBar_progressWidth, progressWidth);
   progress = a.getInt(R.styleable.CameraProgressBar_progresscamera, progress);
   scale = a.getFloat(R.styleable.CameraProgressBar_scale, scale);
   isLongScale = a.getBoolean(R.styleable.CameraProgressBar_isLongScale, isLongScale);
   maxProgress = a.getInt(R.styleable.CameraProgressBar_maxProgress, maxProgress);
   a.recycle();
  }
  backgroundPaint = new Paint();
  backgroundPaint.setAntiAlias(true);
  backgroundPaint.setColor(backgroundColor);

  progressPaint = new Paint();
  progressPaint.setAntiAlias(true);
  progressPaint.setStrokeWidth(progressWidth);
  progressPaint.setStyle(Paint.Style.STROKE);

  innerPaint = new Paint();
  innerPaint.setAntiAlias(true);
  innerPaint.setStrokeWidth(innerRadio);
  innerPaint.setStyle(Paint.Style.STROKE);

  sweepAngle = ((float) progress / maxProgress) * 360;

  mDetector = new GestureDetectorCompat(context, new GestureDetector.SimpleOnGestureListener() {
   @Override
   public boolean onSingleTapConfirmed(MotionEvent e) {
    isLongClick = false;
    if (CameraProgressBar.this.listener != null) {
     CameraProgressBar.this.listener.onClick(CameraProgressBar.this);
    }
    return super.onSingleTapConfirmed(e);
   }

   @Override
   public void onLongPress(MotionEvent e) {
    isLongClick = true;
    postInvalidate();
    mLastY = e.getY();
    if (CameraProgressBar.this.listener != null) {
     CameraProgressBar.this.listener.onLongClick(CameraProgressBar.this);
    }
   }
  });
  mDetector.setIsLongpressEnabled(true);
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  int width = MeasureSpec.getSize(widthMeasureSpec);
  int height = MeasureSpec.getSize(heightMeasureSpec);
  if (width > height) {
   setMeasuredDimension(height, height);
  } else {
   setMeasuredDimension(width, width);
  }
 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  int width = getWidth();
  float circle = width / 2.0f;

  if (/*isLongScale && */!isLongClick) {
   canvas.scale(scale, scale, circle, circle);
  }


  //画内圆
  float backgroundRadio = circle - progressWidth - innerRadio;
  canvas.drawCircle(circle, circle, backgroundRadio, backgroundPaint);

  //画内外环
  float halfInnerWidth = innerRadio / 2.0f + progressWidth;
  RectF innerRectF = new RectF(halfInnerWidth, halfInnerWidth, width - halfInnerWidth, width - halfInnerWidth);
  canvas.drawArc(innerRectF, -90, 360, true, innerPaint);

  progressPaint.setColor(outerColor);
  float halfOuterWidth = progressWidth / 2.0f;
  RectF outerRectF = new RectF(halfOuterWidth, halfOuterWidth, getWidth() - halfOuterWidth, getWidth() - halfOuterWidth);
  canvas.drawArc(outerRectF, -90, 360, true, progressPaint);

  progressPaint.setColor(progressColor);
  canvas.drawArc(outerRectF, -90, sweepAngle, false, progressPaint);
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  if (!isLongScale) {
   return super.onTouchEvent(event);
  }
  this.mDetector.onTouchEvent(event);
  switch(MotionEventCompat.getActionMasked(event)) {
   case MotionEvent.ACTION_DOWN:
    isLongClick = false;
    isBeingDrag = false;
    break;
   case MotionEvent.ACTION_MOVE:
    if (isLongClick) {
     float y = event.getY();
     if (isBeingDrag) {
      boolean isUpScroll = y < mLastY;
      mLastY = y;
      if (this.listener != null) {
       this.listener.onZoom(isUpScroll);
      }
     } else {
      isBeingDrag = Math.abs(y - mLastY) > mTouchSlop;
     }
    }
    break;
   case MotionEvent.ACTION_UP:
   case MotionEvent.ACTION_CANCEL:
    isBeingDrag = false;
    if (isLongClick) {
     isLongClick = false;
     postInvalidate();
     if (this.listener != null) {
      this.listener.onLongClickUp(this);
     }
    }
    break;
   case MotionEvent.ACTION_POINTER_DOWN:
    if (isLongClick) {
     if (this.listener != null) {
      this.listener.onPointerDown(event.getRawX(), event.getRawY());
     }
    }
    break;
  }
  return true;
 }

 @Override
 protected Parcelable onSaveInstanceState() {
  Bundle bundle = new Bundle();
  Parcelable superData = super.onSaveInstanceState();
  bundle.putParcelable("superData", superData);
  bundle.putInt("progress", progress);
  bundle.putInt("maxProgress", maxProgress);
  return bundle;
 }

 @Override
 protected void onRestoreInstanceState(Parcelable state) {
  Bundle bundle = (Bundle) state;
  Parcelable superData = bundle.getParcelable("superData");
  progress = bundle.getInt("progress");
  maxProgress = bundle.getInt("maxProgress");
  super.onRestoreInstanceState(superData);
 }

 /**
  * 设置进度
  * @param progress
  */
 public void setProgress(int progress) {
  if (progress <= 0) progress = 0;
  if (progress >= maxProgress) progress = maxProgress;
  if (progress == this.progress) return;
  this.progress = progress;
  this.sweepAngle = ((float) progress / maxProgress) * 360;
  postInvalidate();
 }

 /**
  * 还原到初始状态
  */
 public void reset() {
  isLongClick = false;
  this.progress = 0;
  this.sweepAngle = 0;
  postInvalidate();
 }

 public int getProgress() {
  return progress;
 }

 public void setLongScale(boolean longScale) {
  isLongScale = longScale;
 }

 public void setMaxProgress(int maxProgress) {
  this.maxProgress = maxProgress;
 }

 private OnProgressTouchListener listener;

 public void setOnProgressTouchListener(OnProgressTouchListener listener) {
  this.listener = listener;
 }

 /**
  * 进度触摸监听
  */
 public interface OnProgressTouchListener {
  /**
   * 单击
   * @param progressBar
   */
  void onClick(CameraProgressBar progressBar);

  /**
   * 长按
   * @param progressBar
   */
  void onLongClick(CameraProgressBar progressBar);

  /**
   * 移动
   * @param zoom true放大
   */
  void onZoom(boolean zoom);

  /**
   * 长按抬起
   * @param progressBar
   */
  void onLongClickUp(CameraProgressBar progressBar);

  /**
   * 触摸对焦
   * @param rawX
   * @param rawY
   */

  void onPointerDown(float rawX, float rawY);
 }

}

预览试图页:

package com.ses.im.app.chat.newcamera;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.support.v4.view.MotionEventCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewParent;

import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.Subscriber;
import rx.Subscription;

/**
 * 相机预览页
 */

public class CameraView extends View {
 /**
  * 动画时长
  */
 private static final int ANIM_MILS = 600;
 /**
  * 动画每多久刷新一次
  */
 private static final int ANIM_UPDATE = 30;
 /**
  * focus paint
  */
 private Paint paint, clearPaint;

 private int paintColor = Color.GREEN;
 /**
  * 进度订阅
  */
 private Subscription subscription;
 /**
  * focus rectf
  */
 private RectF rectF = new RectF();
 /**
  * focus size
  */
 private int focusSize = 120;

 private int lineSize = focusSize / 4;
 /**
  * 上一次两指距离
  */
 private float oldDist = 1f;
 /**
  * 画笔宽
  */
 private float paintWidth = 6.0f;
 /**
  * s
  */
 private float scale;

 public CameraView(Context context) {
  super(context);
  init();
 }

 public CameraView(Context context, AttributeSet attrs) {
  super(context, attrs);
  init();
 }

 public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init();
 }

 private void init() {
  paint = new Paint();
  paint.setColor(paintColor);
  paint.setStyle(Paint.Style.STROKE);
  paint.setStrokeWidth(paintWidth);

  clearPaint = new Paint();
  clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  int action = MotionEventCompat.getActionMasked(event);
  if (event.getPointerCount() == 1 && action == MotionEvent.ACTION_DOWN) {
   float x = event.getX();
   float y = event.getY();
   setFoucsPoint(x, y);
   if (listener != null) {
    listener.handleFocus(x, y);
   }
  } else if (event.getPointerCount() >= 2){
   switch (event.getAction() & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_POINTER_DOWN:
     oldDist = getFingerSpacing(event);
     break;
    case MotionEvent.ACTION_MOVE:
     float newDist = getFingerSpacing(event);
     if (newDist > oldDist) {
      if (this.listener != null) {
       this.listener.handleZoom(true);
      }
     } else if (newDist < oldDist) {
      if (this.listener != null) {
       this.listener.handleZoom(false);
      }
     }
     oldDist = newDist;
     break;
   }
  }
  return true;
 }

 /**
  * 计算两点触控距离
  * @param event
  * @return
  */
 private float getFingerSpacing(MotionEvent event) {
  float x = event.getX(0) - event.getX(1);
  float y = event.getY(0) - event.getY(1);
  return (float) Math.sqrt(x * x + y * y);
 }

 /**
  * 设置坐标点(坐标为rawX, rawY)
  */
 public void setFoucsPoint(PointF pointF) {
  PointF transPointF = transPointF(pointF, this);
  setFoucsPoint(transPointF.x, transPointF.y);
 }

 /**
  * 设置当前触摸点
  * @param x
  * @param y
  */
 private void setFoucsPoint(float x, float y) {
  if (subscription != null) {
   subscription.unsubscribe();
  }
  rectF.set(x - focusSize, y - focusSize, x + focusSize, y + focusSize);
  final int count = ANIM_MILS / ANIM_UPDATE;
  subscription = Observable.interval(ANIM_UPDATE, TimeUnit.MILLISECONDS).take(count).subscribe(new Subscriber<Long>() {
   @Override
   public void onCompleted() {
    scale = 0;
    postInvalidate();
   }

   @Override
   public void onError(Throwable e) {
    scale = 0;
    postInvalidate();
   }

   @Override
   public void onNext(Long aLong) {
    float current = aLong== null ? 0 : aLong.longValue();
    scale = 1 - current / count;
    if (scale <= 0.5f) {
     scale = 0.5f;
    }
    postInvalidate();
   }
  });
 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  if (scale != 0) {
   float centerX = rectF.centerX();
   float centerY = rectF.centerY();
   canvas.scale(scale, scale, centerX, centerY);
   canvas.drawRect(rectF, paint);
   canvas.drawLine(rectF.left, centerY, rectF.left + lineSize, centerY, paint);
   canvas.drawLine(rectF.right, centerY, rectF.right - lineSize, centerY, paint);
   canvas.drawLine(centerX, rectF.top, centerX, rectF.top + lineSize, paint);
   canvas.drawLine(centerX, rectF.bottom, centerX, rectF.bottom - lineSize, paint);
  }
 }

 @Override
 protected void onDetachedFromWindow() {
  super.onDetachedFromWindow();
  if (subscription != null) {
   subscription.unsubscribe();
  }
 }

 /**
  * 根据raw坐标转换成屏幕中所在的坐标
  * @param pointF
  * @return
  */
 private PointF transPointF(PointF pointF, View view) {
  pointF.x -= view.getX();
  pointF.y -= view.getY();
  ViewParent parent = view.getParent();
  if (parent instanceof View) {
   return transPointF(pointF, (View) parent);
  } else {
   return pointF;
  }
 }

 private OnViewTouchListener listener;

 public void setOnViewTouchListener(OnViewTouchListener listener) {
  this.listener = listener;
 }

 public void removeOnZoomListener() {
  this.listener = null;
 }

 public interface OnViewTouchListener {
  /**
   * 对焦
   * @param x
   * @param y
   */
  void handleFocus(float x, float y);

  /**
   * 缩放
   * @param zoom true放大反之
   */
  void handleZoom(boolean zoom);

 }

}

视频管理类:

package com.ses.im.app.chat.newcamera;

import android.app.Application; 
import android.media.MediaPlayer; 
import android.view.Surface;

/** 
* Created by you on 2016/10/24. 
* 由于拍摄跟播放都关联TextureView,停止播放时要释放mediaplayer 
*/

public class MediaPlayerManager {

private Application app;

private MediaPlayer mPlayer;

private MediaPlayerManager(Application app) {
 this.app = app;
}

private static MediaPlayerManager INSTANCE;

public static MediaPlayerManager getInstance(Application app) {
 if (INSTANCE == null) {
  synchronized (CameraManager.class) {
   if (INSTANCE == null) {
    INSTANCE = new MediaPlayerManager(app);
   }
  }
 }
 return INSTANCE;
}

/**
 * 播放Media
 */
public void playMedia(Surface surface, String mediaPath) {
 try {
  if (mPlayer == null) {
   mPlayer = new MediaPlayer();
   mPlayer.setDataSource(mediaPath);
  } else {
   if (mPlayer.isPlaying()) {
    mPlayer.stop();
   }
   mPlayer.reset();
   mPlayer.setDataSource(mediaPath);
  }
  mPlayer.setSurface(surface);
  mPlayer.setLooping(true);
  mPlayer.prepareAsync();
  mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
   @Override
   public void onPrepared(MediaPlayer mp) {
    mp.start();
   }
  });
 } catch (Exception e) {
  LogUtils.i(e);
 }
}

/**
 * 停止播放Media
 */
public void stopMedia() {
 try {
  if (mPlayer != null) {
   if (mPlayer.isPlaying()) {
    mPlayer.stop();
   }
   mPlayer.release();
   mPlayer = null;
  }
 } catch (Exception e) {
  LogUtils.i(e);
 }
}

}

由于本人上传的demo被csdn弄丢了,想要做微信相机的可以参考陈嘉桐的demo

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。