1

I have built a Camera based on the code example presented here and have enhanced it with the Camera.java and ShutterButton.java from AOSP GingerBread,the code I took away was mostly for the autofocus and for the ShutterButton.The Camera has been tested on Samsung Galaxy Nexus and the Samsung Galaxy S4 and the LG Optimus Phone running 4.0.x and it works.However,upon testing at appthwack.com the results are here.This was my Camera.open code which was not working:

    try{   
         Camera.open();
       }
       catch(Exception ex)
       {
          Log.e(TAG,"Could not open camera",ex);//running on HTC prints could not open camera
       }
   mPreview=new CameraPreview(this,mCamera);//this is which the NullPointerException is thrown     

The above code is called in the Activity's onResume which means that the Camera object is only in use when the screen is visible to the user,I release the Camera in onPause() like this:

    sensorManager.unregisterListener(this);
    isPreviewShowing=false;
    if(mCamera!=null)
    killCamera();
    container.removeAllViews();

     private void killCamera()
{
    if(mCamera!=null)
    {
        mCamera.cancelAutoFocus();
        mCamera.setPreviewCallback(null);
        mCamera.stopPreview();
        mCamera.release();
        mCamera=null;
    }
}

I have changed the code for opening the camera to:

 Camera.CameraInfo info=new Camera.CameraInfo();
    int cameraCount=mCamera.getNumberOfCameras();
    int cameraIndex=0;
    for(cameraIndex=0;cameraIndex<cameraCount;cameraIndex++)
    {
        Camera.getCameraInfo(cameraIndex, info);
        if(info.facing==CameraInfo.CAMERA_FACING_BACK)
        {
            try
            {
                mCamera=Camera.open(cameraIndex);
            }
            catch(Exception ex)
            {
                Log.e(TAG, "Could not open camera",ex);
            }
        }
    }

This did not work either,I have also tried adding the following code to the CameraPreview class that has:

 @SuppressWarnings("deprecation")
public CameraPreview(Context context,Camera camera) {
    super(context);
    this.ctx=context;
    mCamera=camera;
    mHolder=this.getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

    @Override
public void surfaceCreated(SurfaceHolder holder) {
    if(mCamera==null)
    {
        mCamera=null;
        Camera.CameraInfo info=new Camera.CameraInfo();
        int cameraCount=mCamera.getNumberOfCameras();
        int cameraIndex=0;
        for(cameraIndex=0;cameraIndex<cameraCount;cameraIndex++)
        {
            Camera.getCameraInfo(cameraIndex, info);
            if(info.facing==CameraInfo.CAMERA_FACING_BACK)
            {
                try
                {
                    mCamera=Camera.open(cameraIndex);
                }
                catch(Exception ex)
                {
                    Log.e(TAG, "Could not open camera",ex);
                }
            }
        }
        
    }
    try
    {
        if(mCamera==null)
        {
            Log.d(TAG,"Camera is null here but why???");
        }
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();
    }
    catch(IOException e)
    {
        Log.e("CameraPreview","Error getting camera preview",e);
    }
}

This did not work either.Also,for anyone asking me about permissions,I have declared all the requisite permissions as:

  <uses-permission android:name="android.permission.CAMERA" />


<uses-feature android:name="android.hardware.camera"
    android:required="true"
     />
<uses-feature android:name="android.hardware.camera.autofocus"
              android:required="true"
     />
<uses-feature android:name="android.hardware.sensor.accelerometer"
              android:required="true"
    />

It would be a little difficult to get started working on a brand new Camera,I would like to(if possible) keep the existing structure of the Camera intact,so could you please help me sort this issue out.The entire logcat file is available along with the test results posted above.

EDIT:

Using the global SurfaceHolder Object instead of the holder on holder provider by surfaceCreated solves the issue on HTC Desire HD but not on HTC One S.It throws the error here:

 java.lang.NullPointerException at 
 com.blutechnologies.scancard.CameraPreview.surfaceCreated(CameraPreview.java:95) at   
 android.view.SurfaceView.updateWindow(SurfaceView.java:543) at 
 android.view.SurfaceView.access$000(SurfaceView.java:81) at 
 android.view.SurfaceView$3.onPreDraw(SurfaceView.java:169) at 
 android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:590) at 
 android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1793) at 
 android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2700) at 
 android.os.Handler.dispatchMessage(Handler.java:99) at 
 android.os.Looper.loop(Looper.java:156) at 
 android.app.ActivityThread.main(ActivityThread.java:5045) at 
 java.lang.reflect.Method.invokeNative(Native Method) at 
 java.lang.reflect.Method.invoke(Method.java:511) at 
 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at 
 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at 
 dalvik.system.NativeStart.main(Native Method)

This is preceeded by:

 I  ActivityManager START {cmp=com.blutechnologies.scancard/.CameraActivity} from pid 21085
 I  QualcommCamera  Qint android::get_camera_info(int, camera_info*): E
 V  QCameraHAL  void android::HAL_getCameraInfo(int, android::CameraInfo*): E
 V  QCameraHAL  void android::HAL_getCameraInfo(int, android::CameraInfo*): X

I guess it means that the Camera is busy,that is it is being used elsewhere,is it due to a previous crash on the device,would it rectify itself if I put the camera closing code in surfaceDestroyed,doing that seems extremely dangerous,I added this code to my surfaceDestroyed:

  private void killCamera()
{
    if(mCamera!=null)
    {
        mCamera.cancelAutoFocus();
        mCamera.release();
        mCamera=null;
    }
}

The Camera is now blank and does not show a preview at all,it gets stuck at setting the Preview Size.There must be some thing I am not doing that can solve this error.

4

2 回答 2

2

这是如何获取相机的示例:

 private Camera getCameraInstance() {
        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_BACK  ) {
                try {
                    cam = Camera.open( camIdx );
                } catch (RuntimeException e) {
                    Log.e("Camera", "Camera failed to open: " + e.getLocalizedMessage());
                }
            }
        }

        return cam;
    }

并检查清单中的权限

   <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" android:required="false" />
    <uses-feature android:name="android.hardware.camera.front" android:required="false" />
于 2013-12-25T10:41:51.063 回答
0

我不知道确切的问题是什么,但是您正在编写代码,surfaceCreated但我还有其他一些技术。

Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;

**OnCreate** 
...
...

getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView) findViewById(R.id.surfaceview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

OnPreviewStart()

OnPreviewStart() {
    if (!previewing) {
        camera = Camera.open();
        if (camera != null) {
            try {
                camera.setPreviewDisplay(surfaceHolder);
                camera.startPreview();
                previewing = true;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

onPreviewStop()

onPreviewStop() {
               if (camera != null && previewing) {
                   camera.stopPreview();
                   camera.release();
                   camera = null;

                   previewing = false;
               }
       }

您可以在任何您想使用的地方调用以上两个函数,在表面上显示和预览相机。

下一件事implements SurfaceHolder.Callback

这将@Override 三种方法用于表面很少喜欢

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height){}
public void surfaceCreated(SurfaceHolder holder){}
public void surfaceDestroyed(SurfaceHolder holder){}

检查更多细节。

于 2013-12-25T12:00:22.577 回答