I have implemented a custom camera and it works well on all other smartphones but when i take photo in Nexus smartphones the image stored is good but the preview of the image shown to user on surface view is very dark but not the photo that is stored.

My classes are below

Preview.java

```
package com.custom.customcamera;

import java.io.IOException;
import java.util.List;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.Size;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;

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

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

@SuppressWarnings("deprecation")
Preview(Context context, SurfaceView sv) {
    super(context);

    mSurfaceView = sv;
//        addView(mSurfaceView);

    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().getSupportedPictureSizes();
        requestLayout();

        // get Camera parameters
        Camera.Parameters params = mCamera.getParameters();

        List<String> focusModes = params.getSupportedFocusModes();
        if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
            // set the focus mode
            params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
            // set Camera parameters
            mCamera.setParameters(params);
        }

        params.setWhiteBalance(Parameters.WHITE_BALANCE_AUTO);
        params.setSceneMode(Parameters.SCENE_MODE_AUTO);
        //params.setPreviewFormat(256);
        int index = params.getExposureCompensation ();
        params.setExposureCompensation(index);
        mCamera.setParameters(params);
    }
}

@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=maxSize();

    }
}

public Size maxSize(){

//      heightmax =0;
//      widthmax =0;
    Size sizeMax=mSupportedPreviewSizes.get(0);
    //long totalsize = heightmax*widthmax;
    //long maxsize=mSupportedPreviewSizes.get(0).height*mSupportedPreviewSizes.get(0).width;

    for(Size size:mSupportedPreviewSizes){
        if(size.height*size.width>sizeMax.width*sizeMax.height){
            sizeMax = size;

        }
    }

    return sizeMax;     
}
@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(final SurfaceHolder holder) {
    // The Surface has been created, acquire the camera and tell it where
    // to draw.
    try {
        if (mCamera != null) {
            mCamera.setPreviewDisplay(holder);
        }
    } catch (Exception 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.release();
        //mCamera.stopPreview();
        mCamera = null;
    }
}

Camera.AutoFocusCallback mnAutoFocusCallback = new Camera.AutoFocusCallback() {
    @Override
    public void onAutoFocus(boolean success, Camera camera) {
    }
};

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    if(mCamera != null) {
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPictureSize(mPreviewSize.width, mPreviewSize.height);
        requestLayout();

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

    }
}

}

```

CameraActivity.java

```
package com.custom.customcamera;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
import android.util.Base64;
import com.kut.kutcamera.R;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.ErrorCallback;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.media.ExifInterface;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.FrameLayout;
import android.widget.ImageView;

public class CameraActivity extends Activity {
Activity context;
Preview preview;
Camera camera;
ImageView fotoButton;
//ImageView foto;
ImageView CancelButton;
ImageView ConfirmButton;
//SurfaceView surfaceView;
String path = "";
static CameraListener listener;

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

    context=this;

    Intent intent = getIntent();
    String tempPath = intent.getStringExtra("Path");

    this.path = tempPath;

    fotoButton = (ImageView) findViewById(R.id.imageView_foto);
    ConfirmButton = (ImageView) findViewById(R.id.imageView_confirm);
    CancelButton = (ImageView) findViewById(R.id.imageView_cancel);
    //foto =    (ImageView) findViewById(R.id.imageView_photoTaken);

    //surfaceView=(SurfaceView)findViewById(R.id.CustomCameraFragment);
    ConfirmButton.setVisibility(View.INVISIBLE);
    CancelButton.setVisibility(View.INVISIBLE);
    //foto.setVisibility(View.INVISIBLE);

    preview = new Preview(this,
            (SurfaceView) findViewById(R.id.CustomCameraFragment));
    FrameLayout frame = (FrameLayout) findViewById(R.id.preview);
    frame.addView(preview);
    preview.setKeepScreenOn(true);
    fotoButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                fotoButton.setImageResource(R.drawable.camera_focused);
                takeFocusedPicture();
            } catch (Exception e) {
            }
            fotoButton.setClickable(false);
        }
    });
}

public void initializeListener(CameraListener listener)
{   
    this.listener = listener;
}

private int cameraId = 0;

@Override
protected void onResume() {
    super.onResume();
    // TODO Auto-generated method stub
    try
    {
        if(camera==null){
            cameraId = findFrontFacingCamera();
            camera = Camera.open(cameraId);

            Camera.Parameters params = camera.getParameters();
            params.setWhiteBalance(Parameters.WHITE_BALANCE_AUTO);
            params.setSceneMode(Parameters.SCENE_MODE_AUTO);
            //params.setPreviewFormat(256);         
            int index = params.getExposureCompensation ();
            params.setExposureCompensation(index);
            camera.setParameters(params);
            camera.startPreview();
            camera.setErrorCallback(new ErrorCallback() {
                public void onError(int error, Camera mcamera) {
                    camera.release();
                    camera = Camera.open();
                    Log.d("Camera died", "error camera");
                }
            });
        }

        if (camera != null) {
            if (Build.VERSION.SDK_INT >= 14)
                setCameraDisplayOrientation(context, CameraInfo.CAMERA_FACING_FRONT, camera);
            preview.setCamera(camera);
        }
    }

    catch(Exception ex)
    {
        String s = ex.toString();
    }
}

private int findFrontFacingCamera() {
    int cameraId = -1;
    // Search for the front facing camera
    int numberOfCameras = Camera.getNumberOfCameras();
    for (int i = 0; i < numberOfCameras; i++) {
        CameraInfo info = new CameraInfo();
        Camera.getCameraInfo(i, info);
        if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
            cameraId = i;
            break;
        }
    }
    return cameraId;
}

private void setCameraDisplayOrientation(Activity activity, int cameraId,
        android.hardware.Camera camera) {
    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(cameraId, info);
    int rotation = activity.getWindowManager().getDefaultDisplay()
            .getRotation();
    int degrees = 0;
    switch (rotation) {
    case Surface.ROTATION_0:
        degrees = 0;
        break;
    case Surface.ROTATION_90:
        degrees = 90;
        break;
    case Surface.ROTATION_180:
        degrees = 180;
        break;
    case Surface.ROTATION_270:
        degrees = 270;
        break;
    }

    int result;
    if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        result = (info.orientation + degrees) % 360;
        result = (360 - result) % 360; // compensate the mirror
    } else { // back-facing
        result = (info.orientation - degrees + 360) % 360;
    }
    camera.setDisplayOrientation(result);
}

Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {
    @Override
    public void onAutoFocus(boolean success, final Camera camera) {

        try{
            Camera.Parameters params = camera.getParameters();
            //params.setWhiteBalance(Parameters.WHITE_BALANCE_AUTO);
            //params.setSceneMode(Parameters.SCENE_MODE_AUTO);
            //params.setPreviewFormat(256);
            //int index = params.getExposureCompensation ();
            //params.setExposureCompensation(index);
            //camera.setParameters(params);
            //camera.autoFocus(null);
            camera.takePicture(mShutterCallback, null, jpegCallback);

        }catch(Exception e){
                String err = e.getMessage();
        }

    }
};

Camera.ShutterCallback mShutterCallback = new ShutterCallback() {

    @Override
    public void onShutter() {
        // TODO Auto-generated method stub

    }
};
public void takeFocusedPicture() {
    camera.autoFocus(mAutoFocusCallback);
}

PictureCallback rawCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
    }
};

String ImagePath = "";

PictureCallback jpegCallback = new PictureCallback() {
    public void onPictureTaken(final byte[] data, final Camera cameraSec) {
        camera.stopPreview();
        //Bitmap image = BitmapFactory.decodeByteArray(data, 0, data.length);
        fotoButton.setVisibility(View.INVISIBLE);

        ConfirmButton.setVisibility(View.VISIBLE);
        CancelButton.setVisibility(View.VISIBLE);
        //surfaceView.setVisibility(SurfaceView.GONE);
        //foto.setVisibility(View.VISIBLE);
        //foto.setVisibility(ImageView.VISIBLE);
        //foto.setImageBitmap(image);
        ConfirmButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View paramView, MotionEvent paramMotionEvent) {
                try
                {
                    ConfirmButton.setImageResource(R.drawable.confirmfocused);

                    FileOutputStream outStream = null;
                    Calendar c = Calendar.getInstance();
                    File videoDirectory = new File(path);

                    if (!videoDirectory.exists()) {
                        videoDirectory.mkdirs();
                    }

                    ImagePath = path + "/" + UUID.randomUUID().toString() + "_" +new Date().getTime() + ".jpg";
                    outStream = new FileOutputStream(ImagePath);
                    outStream.write(data);
                    outStream.close();

                    Bitmap realImage;
                    ExifInterface exif = new ExifInterface(ImagePath);

                    int rotation = (int)exifOrientationToDegrees(
                            exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                                    ExifInterface.ORIENTATION_NORMAL));

                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = 2;

                    realImage = BitmapFactory.decodeFile(ImagePath, options);

                    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
                    realImage.compress(Bitmap.CompressFormat.JPEG, 100, baos); //bm is the bitmap object   
                    byte[] byteArrayImage = baos.toByteArray(); 

                    String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);
                    if(listener != null)
                        listener.PictureTaken(encodedImage,ImagePath,ImagePath.substring(ImagePath.lastIndexOf("/")+1));

                    Intent LaunchIntent =    getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
                    LaunchIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
                    startActivity(LaunchIntent);

                    finish();
                }
                catch(Exception ex){}
                return false;
            }
        });

        CancelButton.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View paramView, MotionEvent paramMotionEvent) {

                //surfaceView.setVisibility(SurfaceView.VISIBLE);
                CancelButton.setImageResource(R.drawable.cancelfocused);

                ConfirmButton.setVisibility(View.INVISIBLE);
                CancelButton.setVisibility(View.INVISIBLE);
                //foto.setVisibility(View.INVISIBLE);

                CancelButton.setImageResource(R.drawable.cancel);
                ConfirmButton.setImageResource(R.drawable.confirm);

                fotoButton.setVisibility(View.VISIBLE);

                fotoButton.setClickable(true);
                fotoButton.setImageResource(R.drawable.camera);
                cameraSec.startPreview();

                return false;
            }
        });
    }
};

private  float exifOrientationToDegrees(int exifOrientation) {
    if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
        return 90;
    } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
        return 180;
    } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
        return 270;
    }
    return 0;
}

public static Bitmap rotate(Bitmap source, float angle) {
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
            source.getHeight(), matrix, false);
}

}

```