public int mCameraId = DEFAULT_CAMERA_ID;
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
super.surfaceChanged(holder, format, w, h);
tryInit(holder, w, h);
}
public void tryInit(SurfaceHolder holder ,int w, int h){
if(!checkHasPermission(CAMERA)) {
uiObserver.onPermissionDeny();
return false;
}
uiObserver.onPermissionGranted();
mAspectRatio = w / h;
CameraManager.of().initCamera(holder, mAspectRatio, mCameraId)
}
public static final int MSG_INIT_CAMERA = 0;
public void initCamera(SurfaceHolder holder, float aspectRatio, int cameraId,){
getCameraHandler()
.sendMessage(handler.obtainMessage(MSG_INIT_CAMERA, cameraId, aspectRatio));
}
...
public void handleMessage(Message msg){
switch (msg.what) {
case MSG_INIT_CAMERA:
camera.initCamera((SurfaceHolder)msg.obj[0], (float)msg.obj[1],(int)msg.obj[2]);
break;
...
}
}
public void initCamera(SurfaceHolder holder, int cameraId, float aspectRatio){
this.mHolder = holder;
this.mCameraId = cameraId;
this.mAspectRatio = aspectRatio;
synchronized(lock){
try{
if(acquireLock(timeout = 2000)){
Log.i(TAG, "initCamera超时")
}
openCamera(cameraId);
applyDefaultParameters();
startPreview();
releaseLock();
Log.i(TAG, "initCamera succ")
retryCount = 0;
}catch(Exception e){
releaseLock();
Log.e(TAG, "initCamera exception info = "+e.getInfo();
if(retryCount > DEFAULT_RETRY_COUNT){
getCameraHandler().postDelay(()->{
retryCount++;
initCamera(holder, cameraId, aspectRatio);
},20);
}
}
}
}
public void openCamera(int cameraId){
int count = 0;
try{
count = Camera.getNumberOfCameras();
}catch(Exception e){
count = -1;
}
if(count == 0){
Toast("清检查设备前后置摄像头")
releaseLock();
return;
}
if(count == -1){
releaseLock();
if(retryCount> DEFAULT_RETRY_COUNT){
getCameraHandle().postDelay(()->{
openCamera(cameraId);
retryCount++;
},20);
}
return;
}
retryCount= 0;
if(mCamera!=null){
releaseCamera();
}
mCamera = Camera.open(cameraId);
if(mCamera == null){
Toast("打开摄像头失败");
releaseLock();
return;
}
mCameraId = cameraId;
Camera.CameraInfo info = new Camera.CameraInfo();
try{
Camera.getCameraInfo(mCameraId,info)
}catch(Exception e){
Log.e(TAG,"exception info = "+ e.getInfo());
}
mCanDisableSound = info.canDisableShutterSound;
if(mCanDisableSound){
try {
mCamera.enableShutterSound(false);
}catch (Exception e){
}
}else{
}
}
private void applyDefaultParameters(){
applyDefaultOrientation();
applyDefaultPreviewSize();
applyDefaultPictureSize();
applyDefaultFocusMode();
applyDefaultFlashMode();
}
private int applyDefaultOrientation() {
int displayOrientation;
if(CameraCompat.Camera1.isOrientationExcepDevice(Build.Model)){
displayOrientation = CameraCompat.Camera1.getOrientationForExcepDevices();
}else{
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
if (mFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
displayOrientation = (mOrientation + degrees) % 360;
displayOrientation = (360 - displayOrientation) % 360;
} else {
displayOrientation = (mOrientation - degrees + 360) % 360;
}
}
try{
camera.setDisplayOrientation(displayOrientation);
}catch(Exception e){
Log.e(TAG, "setDisplayOrientation exception info = "+e.getInfo());
}
}
public void applyDefaultPreviewSize(){
if (mShowingPreview) {
mCamera.stopPreview();
}
Camera.Parameters params = null;
try{
params = mCamera.getParameters();
}catch(Exception e){
...
}
if(params == null){
return;
}
List<Size> previewSize = null;
try{
previewSize = params.getSupportedPreviewSizes();
}catch(Exception e){
...
}
if(previewSize == null || previewSize.size() == 0){
return;
}
float min = Integer.MAX_VALUE;
Size selectSize = null;
for(Size s : previewSize){
float ar = AspectRatio.cal(s);
if(ar - mAspectRatio < min){
selectPreviewSize = s;
min = Math.min(min,Math.abs(mAspectRatio - ar));
}
}
if(selectPreviewSize == null){
return;
}
try{
params.setPreviewSize(selectSize.getWidth(),selectSize.getHeight());
}catch(Exception e){
...
}
}
public void applyDefaultPictureSize(){
if (mShowingPreview) {
mCamera.stopPreview();
}
Camera.Parameters params = null;
try{
params = mCamera.getParameters();
}catch(Exception e){
...
}
if(params == null){
return;
}
List<Size> pictureSize = null;
try{
pictureSize = params.getSupportedPictureSizes();
}catch(Exception e){
...
}
if(pictureSize == null || pictureSize.size() == 0){
return;
}
float min = Integer.MAX_VALUE;
Size selectSize = null;
for(Size s : pictureSize){
float ar = AspectRatio.cal(s);
if(ar - mAspectRatio < min){
selectPictureSize = s;
min = Math.min(min,Math.abs(mAspectRatio - ar));
}
}
if(selectPictureSize == null){
return;
}
try{
params.setPictureSize(selectSize.getWidth(),selectSize.getHeight());
}catch(Exception e){
...
}
}
public boolean applyDefaultFocusMode(){
if(!isCameraOpened()){
return false;
}
try{
final List<String> modes = mCameraParameters.getSupportedFocusModes();
if(modes == null || modes.size() == 0){
return false;
}
if (isCurVideoTab()
&& modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
} else if (modes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}else if (modes.contains(Camera.Parameters.FOCUS_MODE_FIXED)) {
mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
} else if (modes.contains(Camera.Parameters.FOCUS_MODE_INFINITY)) {
mCameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_INFINITY);
} else {
mCameraParameters.setFocusMode(modes.get(0));
}
}catch(Exception e){
...
}
}
private static final SparseArrayCompat<String> FLASH_MODES = new SparseArrayCompat<>();
static {
FLASH_MODES.put(Constants.FLASH_OFF, Camera.Parameters.FLASH_MODE_OFF);
FLASH_MODES.put(Constants.FLASH_ON, Camera.Parameters.FLASH_MODE_ON);
FLASH_MODES.put(Constants.FLASH_TORCH, Camera.Parameters.FLASH_MODE_TORCH);
FLASH_MODES.put(Constants.FLASH_AUTO, Camera.Parameters.FLASH_MODE_AUTO);
FLASH_MODES.put(Constants.FLASH_RED_EYE, Camera.Parameters.FLASH_MODE_RED_EYE);
}
private boolean applyDefaultFlashMode(int flash) {
if (isCameraOpened()) {
List<String> modes = mCameraParameters.getSupportedFlashModes();
String mode = FLASH_MODES.get(flash);
if (modes != null && modes.contains(mode)) {
mCameraParameters.setFlashMode(mode);
mFlash = flash;
return true;
}
String currentMode = FLASH_MODES.get(mFlash);
if (modes == null || !modes.contains(currentMode)) {
mCameraParameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mFlash = Constants.FLASH_OFF;
return true;
}
return false;
} else {
mFlash = flash;
return false;
}
}
public void startPreview(){
if(CheckHasPermission(CAMERA_PERMISSION)){
Toast("无相机权限")
return;
}
if(isPreviewing){
Toast("重复初始化")
return;
}
if(mCamera == null){
return;
}
try{
mCamera.cancelAutoFocus();
}catch(Exception e){
}
synchronize(Lock){
if(acquireLock(timeot = 2000)){
Log.w("timeout");
}
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.setPreviewCallBack(new PreviewCallback(){
void onPreviewFrame(byte[] data, Camera camera){
releaseLock();
if(isPreviewing) return;
isPreviewing = true;
CameraManager.of().onCameraPreviewed();=
}
})
try{
mCamera.startPreview();
}catch(Exception e){
Log.e(TAG, "exp info = "+e.getInfos());
retryStartPreview();
}
}
}
public void releaseCamera(){
if(mCamera == null) return;
synchronized(Lock){
try{
if(acquireLock(timeout = 2000)){
Log.e(TAG, "timeout")
}
mCamera.stopPreview();
mCamera.release();
mCamera = null;
releaseLock();
}catch(Exception e){
...
}
}
}
|