package eu.tpmusielak.securephoto.camera;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.hardware.Camera;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import eu.tpmusielak.securephoto.R;
import java.util.LinkedList;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: Tomasz P. Musielak
* Date: 26/03/12
* Time: 21:33
*/
public class CameraHandler {
public static final String FLASH_MODE_PREF = "FLASH_MODE";
public static final String WHITE_BALANCE_PREF = "WHITE_BALANCE";
public static final String IMG_WIDTH_PREF = "IMG_WIDTH";
public static final String IMG_HEIGHT_PREF = "IMG_HEIGHT";
private final int PICTURE_SIZE = 0;
private final int FLASH_MODE = 1;
private final int WHITE_BALANCE = 2;
private FrameLayout cameraPreviewFrame = null;
private CameraPreview cameraPreview = null;
private int cameraCount = 0;
private int defaultCameraId = 0;
private Camera camera;
private int usedCamera;
private String cameraFocusMode;
private Camera.PictureCallback pictureCallback;
private Button shutter;
private CameraReceiver receiver;
private SharedPreferences preferences;
// Camera parameters:
private String flashMode;
private String wbMode;
private int imgWidth;
private int imgHeight;
public CameraHandler(CameraReceiver r) {
receiver = r;
pictureCallback = new mPictureCallback();
preferences = r.getContext().getSharedPreferences("CAMERA_PREFERENCES", Context.MODE_WORLD_READABLE);
}
public void setCameraPreviewFrame(FrameLayout frame) {
this.cameraPreviewFrame = frame;
}
public void setupCamera() {
cameraCount = Camera.getNumberOfCameras();
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < cameraCount; i++) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
defaultCameraId = i;
}
}
}
private void takePicture() {
shutter.setEnabled(false);
try {
camera.takePicture(null, null, null, pictureCallback);
} catch (RuntimeException ignore) {
/* If the shutter is pressed too often, the shutter button doesn't get disabled
and camera.takePicture fails */
shutter.setEnabled(true);
}
}
public void registerShutterButton(Button shutterButton) {
shutter = shutterButton;
shutter.setOnClickListener(new ShutterListener());
}
public void showCameraSettings() {
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> pictureSizes = parameters.getSupportedPictureSizes();
List<String> flashModes = parameters.getSupportedFlashModes();
List<String> whiteBalanceModes = parameters.getSupportedWhiteBalance();
AlertDialog.Builder builder = new AlertDialog.Builder(receiver.getContext());
builder.setCancelable(true);
builder.setItems(R.array.camera_parameters, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
displayParameterSetting(i);
}
});
AlertDialog alert = builder.create();
alert.show();
}
protected void displayParameterSetting(int setting) {
Camera.Parameters parameters = camera.getParameters();
List options = null;
List<String> optionNames = new LinkedList<String>();
switch (setting) {
case PICTURE_SIZE:
options = parameters.getSupportedPictureSizes();
break;
case FLASH_MODE:
options = parameters.getSupportedFlashModes();
break;
case WHITE_BALANCE:
options = parameters.getSupportedWhiteBalance();
break;
}
if (options == null) {
return; // Nothing to do
}
for (Object option : options) {
if (option instanceof String) {
String o = (String) option;
optionNames.add(o);
} else if (option instanceof Camera.Size) {
Camera.Size size = (Camera.Size) option;
optionNames.add(String.format("%d x %d", size.width, size.height));
} else {
return;
}
}
String[] optionNamesArray = new String[optionNames.size()];
optionNames.toArray(optionNamesArray);
AlertDialog.Builder builder = new AlertDialog.Builder(receiver.getContext());
builder.setCancelable(true);
builder.setItems(optionNamesArray, new CameraSettingListener(setting, options));
AlertDialog alert = builder.create();
alert.show();
}
private class CameraSettingListener implements DialogInterface.OnClickListener {
private final int setting;
private final List options;
private CameraSettingListener(int setting, List options) {
this.setting = setting;
this.options = options;
}
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Camera.Parameters parameters = camera.getParameters();
Object option = options.get(i);
if (setting == PICTURE_SIZE) {
Camera.Size size = (Camera.Size) option;
parameters.setPictureSize(size.width, size.height);
imgWidth = size.width;
imgHeight = size.height;
} else if (setting == FLASH_MODE) {
flashMode = (String) option;
parameters.setFlashMode(flashMode);
} else if (setting == WHITE_BALANCE) {
wbMode = (String) option;
parameters.setWhiteBalance(wbMode);
} else {
}
saveCameraParameters();
camera.setParameters(parameters);
}
}
private class mPictureCallback implements Camera.PictureCallback {
public void onPictureTaken(byte[] bytes, Camera camera) {
receiver.savePicture(bytes);
camera.startPreview();
shutter.setEnabled(true);
}
}
private class AFCallback implements Camera.AutoFocusCallback {
private boolean takePicture;
private AFCallback(boolean takePicture) {
this.takePicture = takePicture;
}
public void onAutoFocus(boolean success, Camera camera) {
if (takePicture) {
takePicture();
}
}
}
private boolean doAF() {
return cameraFocusMode.equals(Camera.Parameters.FOCUS_MODE_AUTO) ||
cameraFocusMode.equals(Camera.Parameters.FOCUS_MODE_MACRO);
}
public void pauseCamera() {
cameraPreview.setCamera(null);
camera.release();
}
public void resumeCamera() {
camera = Camera.open();
cameraPreview = new CameraPreview(receiver.getContext());
cameraFocusMode = camera.getParameters().getFocusMode();
cameraPreviewFrame.removeAllViews();
cameraPreviewFrame.addView(cameraPreview);
cameraPreview.setCamera(camera);
restoreCameraParameters();
}
private void restoreCameraParameters() {
Camera.Parameters parameters = camera.getParameters();
flashMode = preferences.getString(FLASH_MODE_PREF, null);
wbMode = preferences.getString(WHITE_BALANCE_PREF, null);
imgWidth = preferences.getInt(IMG_WIDTH_PREF, -1);
imgHeight = preferences.getInt(IMG_HEIGHT_PREF, -1);
if (flashMode != null)
parameters.setFlashMode(flashMode);
if (wbMode != null)
parameters.setWhiteBalance(wbMode);
if ((imgWidth > 0) && (imgHeight > 0)) {
parameters.setPictureSize(imgWidth, imgHeight);
}
camera.setParameters(parameters);
}
private void saveCameraParameters() {
SharedPreferences.Editor editor = preferences.edit();
editor.putString(FLASH_MODE_PREF, flashMode);
editor.putString(WHITE_BALANCE_PREF, wbMode);
editor.putInt(IMG_WIDTH_PREF, imgWidth);
editor.putInt(IMG_HEIGHT_PREF, imgHeight);
editor.commit();
}
private class ShutterListener implements View.OnClickListener {
public void onClick(View view) {
Camera.Parameters camParameters = camera.getParameters();
camParameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
camera.setParameters(camParameters);
if (doAF()) {
camera.autoFocus(new AFCallback(true));
} else {
takePicture();
}
}
}
}