2016-12-06 46 views
0

我正在檢查,如果我的surfaceView項目工作正常,所以我已經嘗試過我的妻子銀河s7 G930F,它工作得很好,當我嘗試過使用我的HTC ONE M9,它甚至沒有動,一直崩潰。這是在Android 6.奇怪的問題,兩個手機的運行速度雖然試圖運行我是連接日誌:致命的例外 - Camera.release()被調用後,相機正在使用HTC ONE M9

E/AndroidRuntime: FATAL EXCEPTION: main 
       Process: com.example.arturs.androidmirrorapplicationv2, PID: 15974 
       java.lang.RuntimeException: Camera is being used after Camera.release() was called 
        at android.hardware.Camera.setPreviewSurface(Native Method) 
        at android.hardware.Camera.setPreviewDisplay(Camera.java:923) 
        at com.example.arturs.androidmirrorapplicationv2.CameraView.surfaceCreated(CameraView.java:46) 
        at android.view.SurfaceView.updateWindow(SurfaceView.java:582) 
        at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:177) 
        at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944) 
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2152) 
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1174) 
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6241) 
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:873) 
        at android.view.Choreographer.doCallbacks(Choreographer.java:676) 
        at android.view.Choreographer.doFrame(Choreographer.java:606) 
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:859) 
        at android.os.Handler.handleCallback(Handler.java:739) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:168) 
Disconnected from the target VM, address: 'localhost:8602', transport: 'socket' 
         at android.app.ActivityThread.main(ActivityThread.java:5845) 
         at java.lang.reflect.Method.invoke(Native Method) 

和我的代碼的其餘部分看起來像上面:MainActivity類別

import android.content.pm.PackageManager; 
import android.hardware.Camera; 
import android.os.Bundle; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.content.ContextCompat; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 

public class MainActivity extends AppCompatActivity { 

private Camera mCamera; 
private CameraView mCameraView; 
private static final String TAG = "MainActivity"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
} 


@Override 
protected void onResume(){ 
    super.onResume(); 


    try{ 
     if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) 
      //pyta użytkownika o autoryzację - potrzebne w androidzie => 6.0 tzw. run permission 
      ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CAMERA}, 50); 
     else 

     mCamera = openFrontFacingCamera(); 
     mCameraView = new CameraView(this, mCamera); 
     setContentView(mCameraView); 
    } catch (Exception e){ 
     finish(); 
    } 
} 

@Override 
protected void onPause(){ 
    if(mCamera != null){ 
     mCamera.release(); 
     mCamera = null; 
    } 
    super.onPause(); 
} 


public Camera openFrontFacingCamera() { 



    int cameraCount = 0; 
    Camera cam = null; 
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); 
    cameraCount = Camera.getNumberOfCameras(); 
    for (int camIdx = 0; camIdx < cameraCount; camIdx++) { 
     Camera.getCameraInfo(camIdx, cameraInfo); 
     if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
      try { 
       cam = Camera.open(camIdx); 
      } catch (RuntimeException e) { 
       Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage()); 
      } 
     } 
    } 

    return cam; 
    } 
} 

CameraView類

import android.content.Context; 
import android.hardware.Camera; 
import android.hardware.Camera.Parameters; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.Surface; 
import android.view.Display; 
import android.view.WindowManager; 
import java.io.IOException; 
import java.util.List; 


public class CameraView extends SurfaceView implements SurfaceHolder.Callback{ 


private Camera mCamera; 
private View mView; 
private WindowManager display; 
private Context mContext; 
private static final String cameraPreview = "CameraView"; 
private static final String APP_CLASS = "APP_CLASS"; 
private static final String Bug = "Bug"; 

public CameraView(Context context, Camera mCamera) { 
    super(context); 

    mContext = context; 

    this.mCamera = mCamera; 
    mCamera.setDisplayOrientation(90); 

    SurfaceHolder holder = getHolder(); 
    holder.addCallback(this); 
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

} 


@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    try{ 
     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     Log.e(cameraPreview, "The failure of the camera settings"); 
    } 
} 


@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
    Camera.Parameters params = mCamera.getParameters(); 
    List<Camera.Size> sizes = params.getSupportedPreviewSizes(); 
    Camera.Size optionalSize = getOptimalPreviewSize(sizes, width, height); 
    params.setPreviewSize(optionalSize.width, optionalSize.height); 
    mCamera.setParameters(params); 

    boolean isPreviewRunning = true; 

    if (isPreviewRunning) 
    { 
     mCamera.stopPreview(); 
    } 

    Parameters parameters = mCamera.getParameters(); 
    Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
    width = display.getWidth(); 
    height = display.getHeight(); 

    if(display.getRotation() == Surface.ROTATION_0) 
    { 
     parameters.setPreviewSize(height, width); 
     mCamera.setDisplayOrientation(90); 
    } 

    if(display.getRotation() == Surface.ROTATION_90) 
    { 
     parameters.setPreviewSize(width, height); 
     mCamera.setDisplayOrientation(0); 
    } 

    if(display.getRotation() == Surface.ROTATION_180) 
    { 
     parameters.setPreviewSize(height, width); 
     mCamera.setDisplayOrientation(270); 
    } 

    if(display.getRotation() == Surface.ROTATION_270) 
    { 
     parameters.setPreviewSize(width, height); 
     mCamera.setDisplayOrientation(180); 
    } 

    try{ 
    mCamera.setParameters(parameters); 
    previewCamera(holder); 
    mCamera.startPreview();} 
    catch(Exception e){ 
     Log.e(Bug, "setting Parameters Failed" + e.getLocalizedMessage()); 

    } 
} 

public void previewCamera(SurfaceHolder holder) 
{ 
    try 
    { 
     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 
     boolean isPreviewRunning = true; 
    } 
    catch(Exception e) 
    { 
     Log.d(APP_CLASS, "Cannot start preview", e); 
    } 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    mCamera.release(); 
    mCamera = null; 
} 

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { 

    final double ASPECT_TOLERANCE = 0.1; 
    double targetRatio=(double)h/w; 

    if (sizes == null) return null; 

    Camera.Size optimalSize = null; 
    double minDiff = Double.MAX_VALUE; 

    int targetHeight = h; 

    for (Camera.Size size : sizes) { 
     double ratio = (double) size.width/size.height; 
     if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; 
     if (Math.abs(size.height - targetHeight) < minDiff) { 
      optimalSize = size; 
      minDiff = Math.abs(size.height - targetHeight); 
     } 
    } 

    if (optimalSize == null) { 
     minDiff = Double.MAX_VALUE; 
     for (Camera.Size size : sizes) { 
      if (Math.abs(size.height - targetHeight) < minDiff) { 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 
     } 
    } 
    return optimalSize; 


} 

} 

我會感謝所有類型的建議,這可以讓我解決這個問題。

回答

0

我已經想通了:)所以在MainActivity類應該是現在這個樣子

package com.example.arturs.androidmirrorapplicationv2; 

import android.app.Activity; 
import android.hardware.Camera; 
import android.os.Bundle; 
import android.util.Log; 

public class MainActivity extends Activity { 

private CameraView mCameraView; 
private Camera mCamera; 
private static final String TAG = " => Main Activity: "; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mCamera = openFrontFacingCamera(); 
    setContentView(R.layout.activity_main); 

} 


@Override 
protected void onResume() { 
    super.onResume(); 

// 
//   if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) 
//    //pyta użytkownika o autoryzację - potrzebne w androidzie => 6.0 tzw. run permission 
//    ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CAMERA}, 50); 
//   else 

      Log.d(TAG, " -> OnResume"); 
     try { 
      mCamera = openFrontFacingCamera(); 
      if (mCamera != null) { 
       mCameraView = new CameraView(this, mCamera); 
       setContentView(mCameraView); 
      } else { 
       Log.d(TAG, " = Camera == NULL"); 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
      finish(); 
     } 

     Log.d(TAG, " <- OnResume"); 


} 

@Override 
protected void onPause(){ 
    Log.d(TAG, " -> onPause"); 
    if(mCamera != null){ 
     mCamera.release(); 
     mCamera = null; 
    } 
    super.onPause(); 
    Log.d(TAG, " <- onPause"); 
} 


public Camera openFrontFacingCamera() { 

//  if (mCamera != null) { 
//   mCamera.release(); 
//   mCamera = null;} 

    int cameraCount = 0; 
    Camera cam = null; 
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo(); 
    cameraCount = Camera.getNumberOfCameras(); 
    for (int camIdx = 0; camIdx < cameraCount; camIdx++) { 
     Camera.getCameraInfo(camIdx, cameraInfo); 
     Log.d(TAG, "Camera Info: "+cameraInfo.facing); 
     if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { 
      try { 
       return Camera.open(camIdx); 
      } catch (RuntimeException e) { 
       Log.e(TAG, "Camera failed to open: " + e.getLocalizedMessage()); 
      } 
     } 
    } 

    return null; 
} 
} 

和類CameraView應該看起來像上面這個,糾正

package com.example.arturs.androidmirrorapplicationv2; 

import android.content.Context; 
import android.hardware.Camera; 
import android.hardware.Camera.Parameters; 
import android.util.Log; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 
import android.view.View; 
import android.view.Surface; 
import android.view.Display; 
import android.view.WindowManager; 
import java.io.IOException; 
import java.util.List; 


public class CameraView extends SurfaceView implements SurfaceHolder.Callback{ 


private Camera mCamera; 
private View mView; 
private WindowManager display; 
private Context mContext; 
private static final String cameraPreview = "CameraView"; 
private static final String APP_CLASS = "APP_CLASS"; 
private static final String Bug = "Bug"; 

public CameraView(Context context, Camera mCamera) { 
    super(context); 

    mContext = context; 

    this.mCamera = mCamera; 
    mCamera.setDisplayOrientation(90); 

    SurfaceHolder holder = getHolder(); 
    holder.addCallback(this); 
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

} 


@Override 
public void surfaceCreated(SurfaceHolder holder) { 
    try{ 
     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     Log.e(cameraPreview, "The failure of the camera settings"); 
    } 
} 


@Override 
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
    Camera.Parameters params = mCamera.getParameters(); 
    List<Camera.Size> sizes = params.getSupportedPreviewSizes(); 
    Camera.Size optionalSize = getOptimalPreviewSize(sizes, width, height); 
    params.setPreviewSize(optionalSize.width, optionalSize.height); 
    mCamera.setParameters(params); 


    Parameters parameters = mCamera.getParameters(); 
    Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 


    if(display.getRotation() == Surface.ROTATION_0) 
    { 
     mCamera.setDisplayOrientation(90); 
    } 

    if(display.getRotation() == Surface.ROTATION_90) 
    { 
     mCamera.setDisplayOrientation(0); 
    } 

    if(display.getRotation() == Surface.ROTATION_180) 
    { 
     mCamera.setDisplayOrientation(270); 
    } 

    if(display.getRotation() == Surface.ROTATION_270) 
    { 
     mCamera.setDisplayOrientation(180); 
    } 

    try{ 
    mCamera.setParameters(parameters); 
    previewCamera(holder); 
    mCamera.startPreview();} 
    catch(Exception e){ 
     e.printStackTrace(); 
     Log.e(Bug, "setting Parameters Failed" + e.getLocalizedMessage()); 

    } 
} 

public void previewCamera(SurfaceHolder holder) 
{ 
    try 
    { 
     mCamera.setPreviewDisplay(holder); 
     mCamera.startPreview(); 
     boolean isPreviewRunning = true; 
    } 
    catch(Exception e) 
    { 
     e.printStackTrace(); 
     Log.d(APP_CLASS, "Cannot start preview", e); 
    } 
} 

@Override 
public void surfaceDestroyed(SurfaceHolder holder) { 
    mCamera.release(); 
    mCamera = null; 
} 

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) { 

    final double ASPECT_TOLERANCE = 0.1; 
    double targetRatio=(double)h/w; 

    if (sizes == null) return null; 

    Camera.Size optimalSize = null; 
    double minDiff = Double.MAX_VALUE; 

    int targetHeight = h; 

    for (Camera.Size size : sizes) { 
     double ratio = (double) size.width/size.height; 
     if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; 
     if (Math.abs(size.height - targetHeight) < minDiff) { 
      optimalSize = size; 
      minDiff = Math.abs(size.height - targetHeight); 
     } 
    } 

    if (optimalSize == null) { 
     minDiff = Double.MAX_VALUE; 
     for (Camera.Size size : sizes) { 
      if (Math.abs(size.height - targetHeight) < minDiff) { 
       optimalSize = size; 
       minDiff = Math.abs(size.height - targetHeight); 
      } 
     } 
    } 
    return optimalSize; 
} 

}