Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android camera functions don't work on a few phones

I just realized my camera activity in a surfaceholder doesn't work on some devices. Some DROID branded and skinned phones. It works on all google phones with standard android implementation so far.

I got a brief moment to debug a device on 2.2 (don't know exactly what model phone this was, but it was skinned) and I saw the debugger said (ICamera failed) (Camera Error 100)

but I didn't get a chance to find out exactly where it goes wrong, but I do see that others have encountered this issue (something about getting preview size before starting preview??), but no obvious responses or anything intuitive to what I have, but here is my camera code, what would make this work more universally?

   //this is in OnCreate
   preview = (SurfaceView) findViewById(R.id.cameraplacer);
    previewHolder = preview.getHolder();

    previewHolder.addCallback(surfaceCallback);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

//this is outside the lifecycle methods

 SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
    public void surfaceCreated(SurfaceHolder holder) {
        if (camera == null) {
            camera = Camera.open();
            try {
                Camera.Parameters camParams = camera.getParameters();
                camParams.setFlashMode(Parameters.FLASH_MODE_AUTO);

                setDisplayOrientation(camera, 90);
                camera.setPreviewDisplay(previewHolder);
                camera.setParameters(camParams);

            } catch (IOException e) {
                camera.release();
                camera = null;
            }
        }


    }//end surfaceCreated

    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.setPreviewSize(size.width, size.height);
            camera.setParameters(parameters);
            camera.startPreview();
            inPreview=true;
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (camera != null) {
            camera.stopPreview();
            camera.setPreviewCallback(null);
            camera.release();
            camera = null;
        }
    }
};//end CallBack

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);
}//end getBestPreviewSize

//this is on OnResume

     try {
        //Method rotateMethod = android.hardware.Camera.class.getMethod("setDisplayOrientation", int.class);
        //rotateMethod.invoke(camera, 90);
        //Camera.Parameters camParams = camera.getParameters();
        //camParams.setPreviewSize(480, 320);// here w h are reversed
        //camera.setParameters(camParams);*/
        //setCameraDisplayOrientation(MainPhoto.this, 0, camera);
        if(camera!=null)
        {
            Camera.Parameters camParams = camera.getParameters();
            camParams.setFlashMode(Parameters.FLASH_MODE_AUTO);
            camera.setParameters(camParams);
            setDisplayOrientation(camera, 90);
            camera.setPreviewDisplay(previewHolder);
            camera.startPreview();
        }


    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (SecurityException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }/* catch (NoSuchMethodException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }*/ catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }/* catch (IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }*/
like image 221
CQM Avatar asked Dec 14 '11 22:12

CQM


3 Answers

I'd delete the onResume() logic, as it duplicates what you have in surfaceChanged(), and it may not be safe to do that work by the time onResume() is called, as the surface may not yet be ready.

Also, you are blindly asking for FLASH_MODE_AUTO without seeing if that is supported by the device.

Those would be two places to start.

like image 121
CommonsWare Avatar answered Nov 13 '22 03:11

CommonsWare


first a question where is your onPause method, I am assuming you are releasing all the resources related to camera, as you cant hold back on it till your app is paused.

secondly, have variable to keep track of surface status whether its destroyed or not based upon that you have to decide what to do in onResume. Some thing like this

if (hasSurface) {
            // The activity was paused but not stopped, so the surface still
            // exists. Therefore
            // surfaceCreated() won't be called, so init the camera here.
            initCamera(surfaceHolder);
        } else {
            surfaceHolder.addCallback(this);
            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        }

one more thing the error 100 you are getting is actually camera indicating native camera app is crashed somehow, if you have set the errorCallback to the camera instance you will be notified back about this event and what you can do according to the error documentation is start fresh i.e. re-initialize camera instance.

hope it helps somehow!

like image 31
dcool Avatar answered Nov 13 '22 04:11

dcool


Take a look at the android example here

or import the android examples in your IDE.

Hope this helps

like image 2
Maikel Bollemeijer Avatar answered Nov 13 '22 04:11

Maikel Bollemeijer