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.