Building my own camera application + Automatically capture the image

19,883

Solution 1

Ok I found a answer to take the picture automatically. Adding as a comment for the use of others.

final Timer t = new Timer();
t.schedule(new TimerTask() { 
@Override 
public void run() { 
mCamera.takePicture(null, null, mPicture); t.cancel(); 
} 
},5000);

Solution 2

the trick is to give the Camera Class a SurfaceView which is not part of the view hierarchy. The following code is from one of my apps where i used this technique to display my own

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        mCamera = Camera.open();
        startPreview();
    }

    private void startPreview() {
            if (mCamera != null) {
                mCamera.stopPreview();
                try {
                    mCamera.setPreviewDisplay(new SurfaceView(this).getHolder());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                mCamera.setPreviewCallbackWithBuffer(this);

                Camera.Parameters parameters = mCamera.getParameters();    
                parameters.setPreviewSize(IMAGE_W, IMAGE_H);
                mCamera.setParameters(parameters);
                PixelFormat p = new PixelFormat();
                PixelFormat.getPixelFormatInfo(parameters.getPreviewFormat(), p);
                int bufSize = (IMAGE_W * IMAGE_H * p.bitsPerPixel) / 8;
                mCamera.addCallbackBuffer(new byte[bufSize]);
                mCamera.startPreview();
            }
        }
    public void onPreviewFrame(final byte[] data, Camera camera) {
        if (mCamera == null) {
            return;
        }
        mCamera.addCallbackBuffer(data);
    }
}
Share:
19,883
9T9
Author by

9T9

C++ Software Engineer

Updated on June 18, 2022

Comments

  • 9T9
    9T9 almost 2 years

    I have created my own camera application. And when I click the button it takes the picture and saves it in the galary. What I want to do is to take the picture without a preview and without clicking any button.

    My main activity class.

    package themiya.camera.android;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Date;
    
    import android.app.Activity;
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.hardware.Camera;
    import android.hardware.Camera.PictureCallback;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Environment;
    import android.provider.MediaStore;
    import android.view.View;
    import android.widget.Button;
    import android.widget.FrameLayout;
    import android.widget.Toast;
    
    public class CameraActivity extends Activity {
    
    private Camera mCamera;
    private CameraPreview mPreview;
    public static final int MEDIA_TYPE_IMAGE = 1;
    
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button captureButton = (Button) findViewById(R.id.button_capture);
        System.out.println("Starting!");
    
        // Create an instance of Camera
        mCamera = getCameraInstance();
        // Create our Preview view and set it as the content of our activity.
        mPreview = new CameraPreview(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
    
        final PictureCallback mPicture = new PictureCallback() {
    
            public void onPictureTaken(byte[] data, Camera camera) {
    
                File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
    
                if (pictureFile == null){
                    return;
                }
    
                try {
                    FileOutputStream fos = new FileOutputStream(pictureFile);
                    fos.write(data);
                    fos.close();
                    MediaStore.Images.Media.insertImage(getContentResolver(), pictureFile.getAbsolutePath(), pictureFile.getName(), pictureFile.getName());
                } catch (FileNotFoundException e) {
    
                } catch (IOException e) {
    
                }
              }
            };
    
    
    
    
    
         // Add a listener to the Capture button
            captureButton.setOnClickListener(
    
                new View.OnClickListener() {
    
                    public void onClick(View v) {
                        // get an image from the camera   
    
                        System.out.println("Photo Taking!");
                        mCamera.takePicture(null, null, mPicture);
    
    
    
                    }
                }
            );
    
    
    
    
    }
    
    
    
    
    /** A safe way to get an instance of the Camera object. */
    public static Camera getCameraInstance(){
        Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance
        }
        catch (Exception e){
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        releaseCamera();              // release the camera immediately on pause event
    }
    
    
    
    private void releaseCamera(){
        if (mCamera != null){
            mCamera.release();        // release the camera for other applications
            mCamera = null;
        }
    }
    
    
    
    /** Create a File for saving an image or video */
    private  File getOutputMediaFile(int type){
        // To be safe, you should check that the SDCard is mounted
        // using Environment.getExternalStorageState() before doing this.
    
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                  Environment.DIRECTORY_PICTURES), "MyCameraApp");
    
    
        // This location works best if you want the created images to be shared
        // between applications and persist after your app has been uninstalled.
    
        // Create the storage directory if it does not exist
        if (! mediaStorageDir.exists()){
            if (! mediaStorageDir.mkdirs()){
                return null;
            }
        }
    
        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE){
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
            "IMG_"+ timeStamp + ".jpg");
        } else {
            return null;
        }
    
        return mediaFile;
    }
    }
    

    And the preview class.

    package themiya.camera.android;
    
    import android.content.Context;
    import android.hardware.Camera;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    
    public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{
    
        private SurfaceHolder mHolder;
        private Camera mCamera;
    
        public CameraPreview(Context context,Camera camera) {
            super(context);
            mCamera = camera;
    
            /*SurfaceView view = new SurfaceView(this);
            c.setPreviewDisplay(view.getHolder());
            c.startPreview();
            c.takePicture(shutterCallback, rawPictureCallback, jpegPictureCallback);
             * */
    
            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();
    
            mHolder.addCallback(this);
            // deprecated setting, but required on Android versions prior to 3.0
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);   
    
    
        }
    
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {
            // TODO Auto-generated method stub
    
            if (mHolder.getSurface() == null){
                // preview surface does not exist
                return;
              }
    
              // stop preview before making changes
              try {
                  mCamera.stopPreview();
              } catch (Exception e){
                // ignore: tried to stop a non-existent preview
              }
    
              // set preview size and make any resize, rotate or
              // reformatting changes here
    
              // start preview with new settings
              try {
                  mCamera.setPreviewDisplay(mHolder);
                  mCamera.startPreview();
    
              } catch (Exception e){
    
              }
    
        }
    
        public void surfaceCreated(SurfaceHolder holder) {
            // TODO Auto-generated method stub
    
        }
    
        public void surfaceDestroyed(SurfaceHolder holder) {
            // TODO Auto-generated method stub
    
        }
    
    }
    

    In the activity class the on click method is like this.

    captureButton.setOnClickListener(
    
                new View.OnClickListener() {
    
                    public void onClick(View v) {
                            // get an image from the camera   
    
                        System.out.println("Photo Taking!");
                        mCamera.takePicture(null, null, mPicture);
    
    
    
                    }
                }
            );
    

    And when I remove that listener part and put only the

    mCamera.takePicture(null, null, mPicture);
    

    part application crashes. I think that may be due to the delay that the application takes to open the camera. So code try to get the photo before opening the camera. Also wait(10000); didn't work for me.

    And also I want to take the picture without the preview. According to my knowledge I have to change the preview class to do that. But I don't know the correct way to do it.

    Can anyone help me with this asp.