How do you get a simple camera program working for Android?
<p>I just started programming in Java, and I need to get a simple application up that shows the camera, takes a picture, and sends that picture data somewhere.</p>

<p>I have been searching all over the web trying to find a good camera tutorial that worked as expected, but apparently they all require some inner knowledge that I do not have yet.</p>

<p>On <a href="http://stackoverflow.com/questions/2713165/take-and-save-picture-on-button-press">this</a> page, commonsWare pointed to code that had some sample code in it for using the camera. I have taken the PictureDemo code and got it running with no errors. However, it only brings up a black screen. I assume this is because the program is not actually activating the preview, or camera in the main function, but every time I try adding the code I think I need, I am getting exceptions.</p>

<p>So my question is, what do I need to add in the main function to get the camera going? Or is there a better tutorial somewhere that I can see simple basic code for getting the camera up?</p>

<pre><code>package assist.core;

import android.app.Activity;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class MainActivity extends Activity
{
    private SurfaceView preview = null;
    private SurfaceHolder previewHolder = null;
    private Camera camera = null;
    private boolean inPreview = false;

    /**
     * 
     */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        //Call the parent class
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        preview = (SurfaceView) findViewById(R.id.preview);
        previewHolder = preview.getHolder();
        previewHolder.addCallback(surfaceCallback);
        previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void onResume() {
        super.onResume();
        //Get the camera instance
        camera = CameraFinder.INSTANCE.open();
    }

    @Override
    public void onPause() {
        if (inPreview) {
            camera.stopPreview();
        }

        camera.release();
        camera = null;
        inPreview = false;

        super.onPause();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_CAMERA || keyCode == KeyEvent.KEYCODE_SEARCH) {
            if (inPreview) {
                camera.takePicture(null, null, photoCallback);
                inPreview = false;
            }

            return(true);
        }

        return(super.onKeyDown(keyCode, event));
    }

    private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
        Camera.Size result = null;

        for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
            if (size.width &lt;= width &amp;&amp; size.height &lt;= height) {
                if (result == null) {
                  result=size;
                }
                else {
                    int resultArea = result.width * result.height;
                    int newArea = size.width * size.height;

                    if (newArea &gt; resultArea) {
                        result = size;
                    }
                }
            }
        }

        return(result);
    }

    SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                camera.setPreviewDisplay(previewHolder);
            }
            catch (Throwable t) {
                Log.e("MainActivity-surfaceCallback", "Exception in setPreviewDisplay()", t);
                Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_LONG).show();
            }
        }

        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);
                parameters.setPictureFormat(PixelFormat.JPEG);

                camera.setParameters(parameters);
                camera.startPreview();
                inPreview = true;
            }
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            // no-op
        }
    };

    Camera.PictureCallback photoCallback = new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            new SavePhotoTask().execute(data);
            camera.startPreview();
            inPreview = true;
        }
    };

    class SavePhotoTask extends AsyncTask&lt;byte[], String, String&gt; {
        @Override
        protected String doInBackground(byte[]... jpeg) {
            File photo = new File(Environment.getExternalStorageDirectory(), "photo.jpg");
            if(photo.exists()) {
                photo.delete();
            }

            try {
                FileOutputStream fos = new FileOutputStream(photo.getPath());
                fos.write(jpeg[0]);
                fos.close();
            }
            catch (java.io.IOException e) {
                Log.e("MainActivity", "Exception in photoCallback", e);
            }

            return(null);
        }
    }
}
</code></pre>

<p><strong>Update</strong></p>

<p>As for the exceptions I was getting, if I tried making the main function like the code below,</p>

<pre><code>public void onCreate(Bundle savedInstanceState)
{
    //Call the parent class
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    preview = (SurfaceView) findViewById(R.id.preview);
    previewHolder = preview.getHolder();
    previewHolder.addCallback(surfaceCallback);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    Camera.Parameters parameters = camera.getParameters();
    parameters.setPictureFormat(PixelFormat.JPEG);
    camera.setParameters(parameters);

    try {
        //Start the camera preview display
        camera.setPreviewDisplay(previewHolder);
        camera.startPreview();
    } 
    catch (IOException ex) {
        Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex);
    }
}
</code></pre>

<p>I get "The application has stopped unexpectedly. Please Try again." I was basically trying to follow the steps that the <a href="http://developer.android.com/reference/android/hardware/Camera.html#setPreviewDisplay(android.view.SurfaceHolder)" rel="nofollow">android documention</a> specifies. I also tried putting this code into the onResume function after the camera object is retrieved, and then calling this.onResume.</p>
