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

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