Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Android

Building my own camera application + Automatically capture the image

I have created my own camera application. And when I click the button it takes the picture and saves it in the gallery. 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 asap.

1 Answer

Ben Jakuben
STAFF
Ben Jakuben
Treehouse Teacher

Hi @Akul,

The teaching staff doesn't officially support personal projects, but the forum is still a great place to come ask for assistance from other members. I'm afraid I can't envision how your app is supposed to work, though. If you don't wait for the camera to load properly then the image would likely be out of focus. It seems like a weird user experience, especially without a preview, which is a pretty standard user experience.