Android camera features do not work on multiple phones

I just realized that my camera activity in the surface mount does not work on some devices. Some branded and secure DROID phones. It still works on all Google phones with the standard version of Android.

I have a short moment for debugging the device at 2.2 (I don’t know exactly which model of phone it was, but it was overlaid), and I saw what the debugger said (ICamera failed) (Camera Error 100)

but I didn’t have the opportunity to find out exactly where this is happening, but I see that others have encountered this problem (something about getting the size of the preview before starting the preview), but no obvious answers or anything intuitive to what I have, but here is my camera code, what would make this work more universal?

//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 life cycle 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 an OnResume value

  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 wh 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(); }*/ 
+7
source share
3 answers

I would remove the onResume() logic, since it duplicates what you have in surfaceChanged() , and it may be unsafe to do this work until the time onResume() is called, since the surface cannot be ready yet.

In addition, you blindly ask for FLASH_MODE_AUTO without seeing if this device is supported.

These are two places to start.

+4
source

the first question is where is your onPause method, I assume that you are freeing all resources related to the camera, since you cannot hold it until your application is paused.

secondly, to have a variable to track the state of the surface, regardless of whether it was destroyed or not based on what you should decide what to do in onResume. Something like that

 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); } 

another error you get is actually a camera indicating that the application for the native camera is broken somehow, if you set errorCallback to the camera instance, you will be notified about this event and what you can do according to the error The documentation starts fresh, i.e. reinitializes the camera instance.

hope this helps somehow!

+4
source

Take a look at the android example here

or import Android examples into your development environment.

Hope this helps

+2
source

All Articles