Android仿最新微信相机功能

作者:竹林枫fly 时间:2022-06-08 00:35:08 

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

大致完成的功能如下:

  • 长按拍摄视频,轻点拍照

  • 前后摄像头的切换

  • 闪光的的开启,关闭,自动

  • 图片的压缩

  • 自动聚焦,手动聚焦

效果图如下:

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

来源:https://blog.csdn.net/Banboofly/article/details/70159549

标签:Android,微信,相机
0
投稿

猜你喜欢

  • JavaFX 监听窗口关闭事件实例详解

    2023-07-20 21:53:06
  • android开发教程之android的handler使用方法

    2022-04-29 08:25:43
  • android实现双日期选择控件(可隐藏日,只显示年月)

    2023-05-09 12:59:10
  • springboot 注解方式批量插入数据的实现

    2022-02-20 19:03:50
  • idea 创建properties配置文件的步骤

    2023-11-18 18:03:30
  • Android Binder的原理与使用

    2023-04-06 04:08:49
  • 详解SpringBoot2.0的@Cacheable(Redis)缓存失效时间解决方案

    2023-07-23 07:20:54
  • java安全编码指南之:Number操作详解

    2021-09-27 07:14:50
  • kotlin 定义接口并实现回调的例子

    2022-12-06 14:30:19
  • Java中i++与++i的区别和使用

    2022-03-20 18:08:18
  • JPA如何设置表名和实体名,表字段与实体字段的对应

    2022-07-14 14:36:27
  • Java实现多线程断点下载

    2022-04-27 00:29:16
  • Java持久化框架Hibernate与Mybatis优劣及选择详解

    2023-12-03 19:46:14
  • Java线程池并发执行多个任务方式

    2023-08-14 16:26:03
  • C#使用round函数四舍五入的方法

    2022-01-19 04:33:57
  • spring mvc中@PathVariable / 带斜杠方式获取

    2022-09-15 04:47:27
  • c#文件名/路径处理方法示例

    2021-11-28 21:02:40
  • java实现文件拷贝的七种方式

    2023-07-20 19:01:41
  • 详解springmvc控制登录用户session失效后跳转登录页面

    2021-12-08 19:36:40
  • JAVA基础-GUI

    2023-10-24 22:26:07
  • asp之家 软件编程 m.aspxhome.com