The DORIS marine mapping platform is taking shape. For this project, touch screens are not great for people wearing gloves in small fishing boats – so one of the things the android app needs to do is make use of physical keys. In order to do that for taking pictures, I’ve had to write my own camera android activity.
It seems that there are differences in underlying camera behaviour across devices – specifically the Acer E330 model we have to take out on the boats. It seemed that nearly every time takePicture() is called the supplied callback functions fail fire. I’ve tested callbacks for the shutter, raw and jpeg and error events and also tried turning off the preview callback beforehand as suggested elsewhere, no luck on the Acer, while it always works fine on HTC.
The only solution I have so far is to close and reopen the camera just before takePicture() is called which seems to work as intended. As it takes some seconds to complete, it’s also important (as this is bound to a key up event) to prevent the camera starting to take pictures before it’s finished processing the previous one as that causes further callback confusion.
import android.view.SurfaceHolder; import android.view.SurfaceView; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.PictureCallback; import android.util.Log; class PictureTaker { private Camera mCam; private Boolean mTakingPicture; public PictureTaker() { mTakingPicture=false; } public void Startup(SurfaceView view) { mTakingPicture=false; OpenCamera(view); } private void OpenCamera(SurfaceView view) { try { mCam = Camera.open(); if (mCam == null) { Log.i("DORIS","Camera is null!"); return; } mCam.setPreviewDisplay(view.getHolder()); mCam.startPreview(); } catch (Exception e) { Log.i("DORIS","Problem opening camera! " + e); return; } } private void CloseCamera() { mCam.stopPreview(); mCam.release(); mCam = null; } public void TakePicture(SurfaceView view, PictureCallback picture) { if (!mTakingPicture) { mTakingPicture=true; CloseCamera(); OpenCamera(view); try { mCam.takePicture(null, null, picture); } catch (Exception e) { Log.i("DORIS","Problem taking picture: " + e); } } else { Log.i("DORIS","Picture already being taken"); } } }