Android - 前置摄像头预览SurfaceView

时间:2012-01-27 17:38:10

标签: android android-camera

我正在使用下面的代码在surfaceView内显示front_camera,但是当我在三星Galaxy S plus 上尝试此代码时,所有屏幕都是黑色的,但没有发生错误。有谁知道它为什么会发生?

public class TestLedActivity extends Activity {
  private SurfaceView preview=null;
  private SurfaceHolder previewHolder=null;
  private Camera camera=null;
  private boolean inPreview=false;

  private int id;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
    if (currentapiVersion > android.os.Build.VERSION_CODES.FROYO){
         id=findFrontFacingCamera(); 
         Log.d("TestLedActivity","L'id trovato e': "+id);
         camera = Camera.open(id); 
    } else{
        Log.d("TestLedActivity","La versione e' froyo");
        camera = Camera.open();
    }
    preview=(SurfaceView)findViewById(R.id.cpPreview);

            // TODO Auto-generated method stub
            previewHolder=preview.getHolder();
            previewHolder.addCallback(surfaceCallback);
            previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


  }

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



  }

  @Override
  public void onPause() {
    if (inPreview) {
      camera.stopPreview();
    }

    camera.release();
    camera=null;
    inPreview=false;

    super.onPause();
  }




  private int findFrontFacingCamera() {
     int idCamera=0;
        // Look for front-facing camera, using the Gingerbread API.
        // Java reflection is used for backwards compatibility with pre-Gingerbread APIs.
        try {
            Class<?> cameraClass = Class.forName("android.hardware.Camera");
            Object cameraInfo = null;
            Field field = null;
            int cameraCount = 0;
            Method getNumberOfCamerasMethod = cameraClass.getMethod( "getNumberOfCameras" );
            if ( getNumberOfCamerasMethod != null ) {
                cameraCount = (Integer) getNumberOfCamerasMethod.invoke( null, (Object[]) null );
            }
            Class<?> cameraInfoClass = Class.forName("android.hardware.Camera$CameraInfo");
            if ( cameraInfoClass != null ) {
                cameraInfo = cameraInfoClass.newInstance();
            }
            if ( cameraInfo != null ) {
                field = cameraInfo.getClass().getField( "facing" );
            }
            Method getCameraInfoMethod = cameraClass.getMethod( "getCameraInfo", Integer.TYPE, cameraInfoClass );
            if ( getCameraInfoMethod != null && cameraInfoClass != null && field != null ) {
                for ( int camIdx = 0; camIdx < cameraCount; camIdx++ ) {
                    getCameraInfoMethod.invoke( null, camIdx, cameraInfo );
                    int facing = field.getInt( cameraInfo );
                    if ( facing == 1 ) { // Camera.CameraInfo.CAMERA_FACING_FRONT
                        try {
                            Method cameraOpenMethod = cameraClass.getMethod( "open", Integer.TYPE );
                            if ( cameraOpenMethod != null ) {
                                Log.d("TestLedActivity","Id frontale trovato: "+camIdx);
                                //camera = (Camera) cameraOpenMethod.invoke( null, camIdx );
                                idCamera=camIdx;
                            }
                        } catch (RuntimeException e) {
                            Log.e("TestLedActivity", "Camera failed to open: " + e.getLocalizedMessage());
                        }
                    }
                }
            }
        }
        // Ignore the bevy of checked exceptions the Java Reflection API throws - if it fails, who cares.
        catch ( ClassNotFoundException e        ) {Log.e("TestLedActivity", "ClassNotFoundException" + e.getLocalizedMessage());}
        catch ( NoSuchMethodException e         ) {Log.e("TestLedActivity", "NoSuchMethodException" + e.getLocalizedMessage());}
        catch ( NoSuchFieldException e          ) {Log.e("TestLedActivity", "NoSuchFieldException" + e.getLocalizedMessage());}
        catch ( IllegalAccessException e        ) {Log.e("TestLedActivity", "IllegalAccessException" + e.getLocalizedMessage());}
        catch ( InvocationTargetException e     ) {Log.e("TestLedActivity", "InvocationTargetException" + e.getLocalizedMessage());}
        catch ( InstantiationException e        ) {Log.e("TestLedActivity", "InstantiationException" + e.getLocalizedMessage());}
        catch ( SecurityException e             ) {Log.e("TestLedActivity", "SecurityException" + e.getLocalizedMessage());}

        if ( camera == null ) {
            Log.d("TestLedActivity","Devo aprire la camera dietro");
            // Try using the pre-Gingerbread APIs to open the camera.
            idCamera=0;
        }

        return idCamera;
    }



  private Camera.Size getBestPreviewSize(int width, int height,
                                         Camera.Parameters parameters) {
    Camera.Size result=null;

    for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
      if (size.width<=width && size.height<=height) {
        if (result==null) {
          result=size;
        }
        else {
          int resultArea=result.width*result.height;
          int newArea=size.width*size.height;

          if (newArea>resultArea) {
            result=size;
          }
        }
      }
    }

    return(result);
  }


  SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
    public void surfaceCreated(SurfaceHolder holder) {
      try {
        camera.setPreviewDisplay(previewHolder);
      }
      catch (Throwable t) {
        Log.e("PreviewDemo-surfaceCallback",
              "Exception in setPreviewDisplay()", t);
        Toast
          .makeText(TestLedActivity.this, t.getMessage(), Toast.LENGTH_LONG)
          .show();
      }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder,
                               int format, int width,
                               int height) {
      Camera.Parameters parameters=camera.getParameters();
      Camera.Size size=getBestPreviewSize(width, height,
                                          parameters);

      if (size!=null) {
        //parameters.set("camera-id", 0);
        parameters.setPreviewSize(size.width, size.height);      
        camera.setParameters(parameters);
        camera.startPreview();
        inPreview=true;
      }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
      // no-op
    }
  };
}

2 个答案:

答案 0 :(得分:6)

识别前置摄像头 Android API级别:

9,10

解决方案:

使用以下getFrontFacingCamera()函数代替camera.open():

Camera getFrontFacingCamera() throws NoSuchElementException {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int cameraIndex = 0; cameraIndex < Camera.getNumberOfCameras(); cameraIndex++) {
    Camera.getCameraInfo(cameraIndex, cameraInfo);
    if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        try {
            return Camera.open(cameraIndex);
        } 
        catch (RuntimeException e) {
            e.printStackTrace();
        }
    }
}
throw new NoSuchElementException("Can't find front camera.");}

三星Galaxy S与Android API 7级,8解决方案

void setFrontCamera(Camera camera) {
Camera.Parameters parameters = camera.getParameters();
parameters.set("camera-id", 2);
// (800, 480) is also supported front camera preview size at Samsung Galaxy S.
parameters.setPreviewSize(640, 480); 
camera.setParameters(parameters);

}

了解更多详情,请访问此链接 http://developer.samsung.com/android/technical-docs/Common-Issues-in-Android

要使用Android 2.2或更低版本中的上述代码删除Class not Found异常,请参阅一篇非常有用的文章 http://digitaldumptruck.jotabout.com/?p=797

答案 1 :(得分:-2)

Camera.Parameters p = c.getParameters(); 

      p.set("camera-id", 2);

    c.setParameters(p);