Android Tutorial - Hardware : Camera

Camera preview

   



<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <SurfaceView
    android:id="@+id/preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
  />
</RelativeLayout>


import java.util.List;

import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class PreviewActivity extends Activity implements SurfaceHolder.Callback {

    Camera mCamera;
    SurfaceView mPreview;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mPreview = (SurfaceView)findViewById(R.id.preview);
        mPreview.getHolder().addCallback(this);
        mPreview.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        
        mCamera = Camera.open();
    }
    
    @Override
    public void onPause() {
        super.onPause();
        mCamera.stopPreview();
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        mCamera.release();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Camera.Parameters params = mCamera.getParameters();
        List<Camera.Size> sizes = params.getSupportedPreviewSizes();
        Camera.Size selected = sizes.get(0);
        params.setPreviewSize(selected.width,selected.height);
        mCamera.setParameters(params);

        mCamera.startPreview();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            mCamera.setPreviewDisplay(mPreview.getHolder());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.i("PREVIEW","surfaceDestroyed");
    } 

}

Camera With Intent

   
package app.test;

import java.io.File;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.View;

public class Test extends Activity {
  Uri myPicture = null;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }
    public void captureImage(View view){
      ContentValues values = new ContentValues();
        values.put(Media.TITLE, "My demo image");
        values.put(Media.DESCRIPTION, "Image Captured by Camera via an Intent");
        myPicture = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
        Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        i.putExtra(MediaStore.EXTRA_OUTPUT, myPicture);
        startActivityForResult(i, 0);
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode==0 && resultCode==Activity.RESULT_OK)
        {
             Intent inn = new Intent(Intent.ACTION_VIEW);
             inn.setData(myPicture);
             startActivity(inn);
        }
    }
} 

Camera Intent

   
package app.test;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.widget.ImageView;

public class Test extends Activity {
  final static int CAMERA_RESULT = 0;
  ImageView imv;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(i, CAMERA_RESULT);
  }

  protected void onActivityResult(int requestCode, int resultCode,
      Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    if (resultCode == RESULT_OK) {
      Bundle extras = intent.getExtras();
      Bitmap bmp = (Bitmap) extras.get("data");
      imv = (ImageView) findViewById(R.id.ReturnedImageView);
      imv.setImageBitmap(bmp);
    }
  }
}
//main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <ImageView 
     android:id="@+id/ReturnedImageView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content">
  </ImageView>
</LinearLayout> 

Media Store Camera Intent

   
package app.test;

import java.io.FileNotFoundException;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.provider.MediaStore.Images.Media;
import android.content.ContentValues;

public class Test extends Activity {

  final static int CAMERA_RESULT = 0;

  Uri imageFileUri;

  ImageView returnedImageView;
  Button takePictureButton;
  Button saveDataButton;
  TextView titleTextView;
  TextView descriptionTextView;
  EditText titleEditText;
  EditText descriptionEditText;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    returnedImageView = (ImageView) findViewById(R.id.ReturnedImageView);
    takePictureButton = (Button) findViewById(R.id.TakePictureButton);
    saveDataButton = (Button) findViewById(R.id.SaveDataButton);
    titleTextView = (TextView) findViewById(R.id.TitleTextView);
    descriptionTextView = (TextView) findViewById(R.id.DescriptionTextView);
    titleEditText = (EditText) findViewById(R.id.TitleEditText);
    descriptionEditText = (EditText) findViewById(R.id.DescriptionEditText);

    returnedImageView.setVisibility(View.GONE);
    saveDataButton.setVisibility(View.GONE);
    titleTextView.setVisibility(View.GONE);
    descriptionTextView.setVisibility(View.GONE);
    titleEditText.setVisibility(View.GONE);
    descriptionEditText.setVisibility(View.GONE);

    takePictureButton.setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        imageFileUri = getContentResolver().insert(
            Media.EXTERNAL_CONTENT_URI, new ContentValues());
        Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
            imageFileUri);
        startActivityForResult(i, CAMERA_RESULT);
      }
    });

    saveDataButton.setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
        ContentValues contentValues = new ContentValues(3);
        contentValues.put(Media.DISPLAY_NAME, titleEditText.getText().toString());
        contentValues.put(Media.DESCRIPTION, descriptionEditText.getText().toString());
        getContentResolver().update(imageFileUri, contentValues, null,null);
        Toast bread = Toast.makeText(Test.this,"Record Updated", Toast.LENGTH_SHORT);
        bread.show();
        takePictureButton.setVisibility(View.VISIBLE);
        returnedImageView.setVisibility(View.GONE);
        saveDataButton.setVisibility(View.GONE);
        titleTextView.setVisibility(View.GONE);
        descriptionTextView.setVisibility(View.GONE);
        titleEditText.setVisibility(View.GONE);
        descriptionEditText.setVisibility(View.GONE);
      }
    });
  }

  protected void onActivityResult(int requestCode, int resultCode,
      Intent intent) {
    super.onActivityResult(requestCode, resultCode, intent);

    if (resultCode == RESULT_OK) {
      takePictureButton.setVisibility(View.GONE);
      saveDataButton.setVisibility(View.VISIBLE);
      returnedImageView.setVisibility(View.VISIBLE);
      titleTextView.setVisibility(View.VISIBLE);
      descriptionTextView.setVisibility(View.VISIBLE);
      titleEditText.setVisibility(View.VISIBLE);
      descriptionEditText.setVisibility(View.VISIBLE);

      int dw = 200; // Make it at most 200 pixels wide
      int dh = 200; // Make it at most 200 pixels tall

      try {
        BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
        bmpFactoryOptions.inJustDecodeBounds = true;
        Bitmap bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
                imageFileUri), null, bmpFactoryOptions);

        int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight/ (float) dh);
        int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth/ (float) dw);
        if (heightRatio > 1 && widthRatio > 1) {
          if (heightRatio > widthRatio) {
            bmpFactoryOptions.inSampleSize = heightRatio;
          } else {
            bmpFactoryOptions.inSampleSize = widthRatio;
          }
        }
        bmpFactoryOptions.inJustDecodeBounds = false;
        bmp = BitmapFactory.decodeStream(getContentResolver().openInputStream(
                imageFileUri), null, bmpFactoryOptions);

        returnedImageView.setImageBitmap(bmp);
      } catch (FileNotFoundException e) {
        Log.v("ERROR", e.toString());
      }
    }
  }
}
//layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <ImageView android:id="@+id/ReturnedImageView" 
             android:layout_width="wrap_content" 
             android:layout_height="wrap_content">
    </ImageView>
    <TextView android:layout_width="wrap_content" 
              android:layout_height="wrap_content" 
              android:text="Title:" 
              android:id="@+id/TitleTextView">
    </TextView>
    <EditText android:layout_height="wrap_content" 
              android:id="@+id/TitleEditText" 
              android:layout_width="fill_parent">
    </EditText>
    <TextView android:layout_width="wrap_content" 
              android:layout_height="wrap_content" 
              android:text="Description" 
              android:id="@+id/DescriptionTextView">
    </TextView>
    <EditText android:layout_height="wrap_content" 
              android:layout_width="fill_parent" 
              android:id="@+id/DescriptionEditText">
    </EditText>
    <Button android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:id="@+id/TakePictureButton" 
            android:text="Take Picture">
    </Button>
    <Button android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:id="@+id/SaveDataButton" 
            android:text="Save Data">
    </Button> 

</LinearLayout>

Using Timer to control Camera

   
package app.test;

import java.io.IOException;
import java.io.OutputStream;
import android.app.Activity;
import android.content.ContentValues;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore.Images.Media;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class Test extends Activity implements OnClickListener,
    SurfaceHolder.Callback, Camera.PictureCallback {
  SurfaceView cameraView;
  SurfaceHolder surfaceHolder;
  Camera camera;

  Button startStopButton;
  TextView countdownTextView;
  Handler timerUpdateHandler;
  boolean timelapseRunning = false;
  int currentTime = 0;
  final int SECONDS_BETWEEN_PHOTOS = 60; 
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    cameraView = (SurfaceView) this.findViewById(R.id.CameraView);
    surfaceHolder = cameraView.getHolder();
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    surfaceHolder.addCallback(this);

    countdownTextView = (TextView) findViewById(R.id.CountDownTextView);
    startStopButton = (Button) findViewById(R.id.CountDownButton);
    startStopButton.setOnClickListener(this);
    timerUpdateHandler = new Handler();
  }

  public void onClick(View v) {
    if (!timelapseRunning) {
      startStopButton.setText("Stop");
      timelapseRunning = true;
      timerUpdateHandler.post(timerUpdateTask);
    } else {
      startStopButton.setText("Start");
      timelapseRunning = false;
      timerUpdateHandler.removeCallbacks(timerUpdateTask);
    }
  }

  private Runnable timerUpdateTask = new Runnable() {
    public void run() {
      if (currentTime < SECONDS_BETWEEN_PHOTOS) {
        currentTime++;
      } else {
        camera.takePicture(null, null, null, Test.this);
        currentTime = 0;
      }

      timerUpdateHandler.postDelayed(timerUpdateTask, 1000);
      countdownTextView.setText("" + currentTime);
    }
  };

  public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    camera.startPreview();
  }

  public void surfaceCreated(SurfaceHolder holder) {
    camera = Camera.open();
    try {
      camera.setPreviewDisplay(holder);
      Camera.Parameters parameters = camera.getParameters();
      if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
        parameters.set("orientation", "portrait");
        camera.setDisplayOrientation(90);
      }
      camera.setParameters(parameters);
    } catch (IOException exception) {
      camera.release();
    }
  }

  public void surfaceDestroyed(SurfaceHolder holder) {
    camera.stopPreview();
    camera.release();
  }

  public void onPictureTaken(byte[] data, Camera camera) {
    Uri imageFileUri = getContentResolver().insert(
        Media.EXTERNAL_CONTENT_URI, new ContentValues());
    try {
      OutputStream imageFileOS = getContentResolver().openOutputStream(
          imageFileUri);
      imageFileOS.write(data);
      imageFileOS.flush();
      imageFileOS.close();

      Toast t = Toast.makeText(this, "Saved JPEG!", Toast.LENGTH_SHORT);
      t.show();
    } catch (Exception e) {
      Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
      t.show();
    }
    camera.startPreview();
  }
}


//layout/main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >    
    <FrameLayout android:id="@+id/FrameLayout01" 
                 android:layout_width="wrap_content" 
                 android:layout_height="wrap_content">
        <SurfaceView android:id="@+id/CameraView" 
                     android:layout_width="fill_parent" 
                     android:layout_height="fill_parent"></SurfaceView>
        <LinearLayout android:id="@+id/LinearLayout01" 
                      android:layout_width="wrap_content" 
                      android:layout_height="wrap_content">
            <TextView android:id="@+id/CountDownTextView" 
                      android:text="10" 
                      android:textSize="100dip" 
                      android:layout_width="fill_parent" 
                      android:layout_height="wrap_content" 
                      android:layout_gravity="center_vertical|center_horizontal|center"></TextView>
            <Button android:layout_width="wrap_content" 
                    android:layout_height="wrap_content" 
                    android:id="@+id/CountDownButton" 
                    android:text="Start Timer"></Button>
        </LinearLayout>
    </FrameLayout>
</LinearLayout> 

Camera orientation

   
package app.test;

import java.io.IOException;
import java.io.OutputStream;
import android.app.Activity;
import android.content.ContentValues;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore.Images.Media;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class Test extends Activity implements OnClickListener,
    SurfaceHolder.Callback, Camera.PictureCallback {
  SurfaceView cameraView;
  SurfaceHolder surfaceHolder;
  Camera camera;

  Button startButton;
  TextView countdownTextView;

  Handler timerUpdateHandler;
  boolean timerRunning = false;
  int currentTime = 10;

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

    cameraView = (SurfaceView) this.findViewById(R.id.CameraView);
    surfaceHolder = cameraView.getHolder();
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    surfaceHolder.addCallback(this);

    countdownTextView = (TextView) findViewById(R.id.CountDownTextView);
    startButton = (Button) findViewById(R.id.CountDownButton);
    startButton.setOnClickListener(this);

    timerUpdateHandler = new Handler();
  }

  public void onClick(View v) {
    if (!timerRunning) {
      timerRunning = true;
      timerUpdateHandler.post(timerUpdateTask);
    }
  }

  private Runnable timerUpdateTask = new Runnable() {
    public void run() {
      if (currentTime > 1) {
        currentTime--;
        timerUpdateHandler.postDelayed(timerUpdateTask, 1000);
      } else {
        camera.takePicture(null, null, Test.this);
        timerRunning = false;
        currentTime = 10;
      }
      countdownTextView.setText("" + currentTime);
    }
  };

  public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    camera.startPreview();
  }

  public void surfaceCreated(SurfaceHolder holder) {
    camera = Camera.open();
    try {
      camera.setPreviewDisplay(holder);
      Camera.Parameters parameters = camera.getParameters();
      if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
        parameters.set("orientation", "portrait");
        camera.setDisplayOrientation(90);
      }
      camera.setParameters(parameters);
    } catch (IOException exception) {
      camera.release();
    }
  }

  public void surfaceDestroyed(SurfaceHolder holder) {
    camera.stopPreview();
    camera.release();
  }

  public void onPictureTaken(byte[] data, Camera camera) {
    Uri imageFileUri = getContentResolver().insert(
        Media.EXTERNAL_CONTENT_URI, new ContentValues());
    try {
      OutputStream imageFileOS = getContentResolver().openOutputStream(
          imageFileUri);
      imageFileOS.write(data);
      imageFileOS.flush();
      imageFileOS.close();
      Toast t = Toast.makeText(this, "Saved JPEG!", Toast.LENGTH_SHORT);
      t.show();
    } catch (Exception e) {
      Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
      t.show();
    }
    camera.startPreview();
  }
}

//layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >    
    <FrameLayout android:id="@+id/FrameLayout01" 
                 android:layout_width="wrap_content" 
                 android:layout_height="wrap_content">
        <SurfaceView android:id="@+id/CameraView" 
                     android:layout_width="fill_parent" 
                     android:layout_height="fill_parent"></SurfaceView>
        <LinearLayout android:id="@+id/LinearLayout01" 
                      android:layout_width="wrap_content" 
                      android:layout_height="wrap_content">
            <TextView android:id="@+id/CountDownTextView" 
                      android:text="10" 
                      android:textSize="100dip" 
                      android:layout_width="fill_parent" 
                      android:layout_height="wrap_content" 
                      android:layout_gravity="center_vertical|center_horizontal|center"></TextView>
            <Button android:layout_width="wrap_content" 
                    android:layout_height="wrap_content" 
                    android:id="@+id/CountDownButton" 
                    android:text="Start Timer"></Button>
        </LinearLayout>
    </FrameLayout> 

</LinearLayout>

Camera Preview and Camera.getNumberOfCameras()

package app.test;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import java.io.IOException;
import java.util.List;

// ----------------------------------------------------------------------

public class Test extends Activity {
    private Preview mPreview;
    Camera mCamera;
    int numberOfCameras;
    int cameraCurrentlyLocked;

    // The first rear facing camera
    int defaultCameraId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Hide the window title.
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

        // Create a RelativeLayout container that will hold a SurfaceView,
        // and set it as the content of our activity.
        mPreview = new Preview(this);
        setContentView(mPreview);

        // Find the total number of cameras available
        numberOfCameras = Camera.getNumberOfCameras();

        // Find the ID of the default camera
        CameraInfo cameraInfo = new CameraInfo();
            for (int i = 0; i < numberOfCameras; i++) {
                Camera.getCameraInfo(i, cameraInfo);
                if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
                    defaultCameraId = i;
                }
            }
    }

    @Override
    protected void onResume() {
        super.onResume();

        // Open the default i.e. the first rear facing camera.
        mCamera = Camera.open();
        cameraCurrentlyLocked = defaultCameraId;
        mPreview.setCamera(mCamera);
    }

    @Override
    protected void onPause() {
        super.onPause();

        // Because the Camera object is a shared resource, it's very
        // important to release it when the activity is paused.
        if (mCamera != null) {
            mPreview.setCamera(null);
            mCamera.release();
            mCamera = null;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate our menu which can gather user input for switching camera
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.camera_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case R.id.switch_cam:
            // check for availability of multiple cameras
            if (numberOfCameras == 1) {
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setMessage("camera_alert")
                       .setNeutralButton("Close", null);
                AlertDialog alert = builder.create();
                alert.show();
                return true;
            }

            // OK, we have multiple cameras.
            // Release this camera -> cameraCurrentlyLocked
            if (mCamera != null) {
                mCamera.stopPreview();
                mPreview.setCamera(null);
                mCamera.release();
                mCamera = null;
            }

            // Acquire the next camera and request Preview to reconfigure
            // parameters.
            mCamera = Camera
                    .open((cameraCurrentlyLocked + 1) % numberOfCameras);
            cameraCurrentlyLocked = (cameraCurrentlyLocked + 1)
                    % numberOfCameras;
            mPreview.switchCamera(mCamera);

            // Start the preview
            mCamera.startPreview();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }
}

// ----------------------------------------------------------------------


class Preview extends ViewGroup implements SurfaceHolder.Callback {
    private final String TAG = "Preview";

    SurfaceView mSurfaceView;
    SurfaceHolder mHolder;
    Size mPreviewSize;
    List<Size> mSupportedPreviewSizes;
    Camera mCamera;

    Preview(Context context) {
        super(context);

        mSurfaceView = new SurfaceView(context);
        addView(mSurfaceView);

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = mSurfaceView.getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void setCamera(Camera camera) {
        mCamera = camera;
        if (mCamera != null) {
            mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
            requestLayout();
        }
    }

    public void switchCamera(Camera camera) {
       setCamera(camera);
       try {
           camera.setPreviewDisplay(mHolder);
       } catch (IOException exception) {
           Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
       }
       Camera.Parameters parameters = camera.getParameters();
       parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
       requestLayout();

       camera.setParameters(parameters);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // We purposely disregard child measurements because act as a
        // wrapper to a SurfaceView that centers the camera preview instead
        // of stretching it.
        final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        setMeasuredDimension(width, height);

        if (mSupportedPreviewSizes != null) {
            mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if (changed && getChildCount() > 0) {
            final View child = getChildAt(0);

            final int width = r - l;
            final int height = b - t;

            int previewWidth = width;
            int previewHeight = height;
            if (mPreviewSize != null) {
                previewWidth = mPreviewSize.width;
                previewHeight = mPreviewSize.height;
            }

            // Center the child SurfaceView within the parent.
            if (width * previewHeight > height * previewWidth) {
                final int scaledChildWidth = previewWidth * height / previewHeight;
                child.layout((width - scaledChildWidth) / 2, 0,
                        (width + scaledChildWidth) / 2, height);
            } else {
                final int scaledChildHeight = previewHeight * width / previewWidth;
                child.layout(0, (height - scaledChildHeight) / 2,
                        width, (height + scaledChildHeight) / 2);
            }
        }
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, acquire the camera and tell it where
        // to draw.
        try {
            if (mCamera != null) {
                mCamera.setPreviewDisplay(holder);
            }
        } catch (IOException exception) {
            Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // Surface will be destroyed when we return, so stop the preview.
        if (mCamera != null) {
            mCamera.stopPreview();
        }
    }


    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) w / h;
        if (sizes == null) return null;

        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find the one match the aspect ratio, ignore the requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // Now that the size is known, set up the camera parameters and begin
        // the preview.
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        requestLayout();

        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }

}

//menu/camera_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/switch_cam"
          android:title="@string/switch_cam" />
</menu>

 Take a snapshot

   

package app.test;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.List;

import android.app.Activity;
import android.content.ContentValues;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore.Images.Media;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

public class Test extends Activity implements OnClickListener,
    SurfaceHolder.Callback, Camera.PictureCallback {
  SurfaceView cameraView;
  SurfaceHolder surfaceHolder;
  Camera camera;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    cameraView = (SurfaceView) this.findViewById(R.id.CameraView);
    surfaceHolder = cameraView.getHolder();
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    surfaceHolder.addCallback(this);
    cameraView.setFocusable(true);
    cameraView.setFocusableInTouchMode(true);
    cameraView.setClickable(true);
    cameraView.setOnClickListener(this);
  }
  public void onClick(View v) {
    camera.takePicture(null, null, this);
  }
  public void onPictureTaken(byte[] data, Camera camera) {
    Uri imageFileUri = getContentResolver().insert(
        Media.EXTERNAL_CONTENT_URI, new ContentValues());
    try {
      OutputStream imageFileOS = getContentResolver().openOutputStream(
          imageFileUri);
      imageFileOS.write(data);
      imageFileOS.flush();
      imageFileOS.close();
    } catch (Exception e) {
      Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
      t.show();
    }
    camera.startPreview();
  }

  public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    camera.startPreview();
  }

  public void surfaceCreated(SurfaceHolder holder) {
    camera = Camera.open();
    try {
      camera.setPreviewDisplay(holder);
      Camera.Parameters parameters = camera.getParameters();
      if (this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
        parameters.set("orientation", "portrait");
        camera.setDisplayOrientation(90);
      }
      List<String> colorEffects = parameters.getSupportedColorEffects();
      Iterator<String> cei = colorEffects.iterator();
      while (cei.hasNext()) {
        String currentEffect = cei.next();
        if (currentEffect.equals(Camera.Parameters.EFFECT_SOLARIZE)) {
          parameters.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE);
          break;
        }
      }
      camera.setParameters(parameters);
    } catch (IOException exception) {
      camera.release();
    }
  }
  public void surfaceDestroyed(SurfaceHolder holder) {
    camera.stopPreview();
    camera.release();
  }
}

//layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<SurfaceView android:id="@+id/CameraView" 
             android:layout_width="fill_parent" 
             android:layout_height="fill_parent">
</SurfaceView>
</LinearLayout>

Take and preview Photo

   

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <SurfaceView
    android:id="@+id/preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
  />
  <RelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="100dip"
    android:layout_alignParentBottom="true"
    android:gravity="center_vertical"
    android:background="#A000">
    <Button
      android:layout_width="100dip"
      android:layout_height="wrap_content"
      android:text="Cancel"
      android:onClick="onCancelClick"
    />
    <Button
      android:layout_width="100dip"
      android:layout_height="wrap_content"
      android:layout_alignParentRight="true"
      android:text="Snap Photo"
      android:onClick="onSnapClick"
    />
  </RelativeLayout>
</RelativeLayout>
package app.test;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;


public class PreviewActivity extends Activity implements SurfaceHolder.Callback, Camera.ShutterCallback, Camera.PictureCallback {

    Camera mCamera;
    SurfaceView mPreview;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mPreview = (SurfaceView)findViewById(R.id.preview);
        mPreview.getHolder().addCallback(this);
        mPreview.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        
        mCamera = Camera.open();
    }
    
    @Override
    public void onPause() {
        super.onPause();
        mCamera.stopPreview();
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        mCamera.release();
        Log.d("CAMERA","Destroy");
    }
    
    public void onCancelClick(View v) {
        finish();
    }
    
    public void onSnapClick(View v) {
        mCamera.takePicture(this, null, null, this);
    }

    @Override
    public void onShutter() {
        Toast.makeText(this, "Click!", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        //Here, we chose internal storage
        try {
            FileOutputStream out = openFileOutput("picture.jpg", Activity.MODE_PRIVATE);
            out.write(data);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        camera.startPreview();
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Camera.Parameters params = mCamera.getParameters();
        List<Camera.Size> sizes = params.getSupportedPreviewSizes();
        Camera.Size selected = sizes.get(0);
        params.setPreviewSize(selected.width,selected.height);
        mCamera.setParameters(params);
        
        mCamera.setDisplayOrientation(90);
        mCamera.startPreview();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            mCamera.setPreviewDisplay(mPreview.getHolder());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.i("PREVIEW","surfaceDestroyed");
    }
}