diff --git a/briar-android/src/org/briarproject/android/view/CameraView.java b/briar-android/src/org/briarproject/android/view/CameraView.java
index 0ce1ad13627837ac2a3bda936a99ff8bc3eb16b0..f0b3d6a7a8769de3c6e5af231c18391629c7ceef 100644
--- a/briar-android/src/org/briarproject/android/view/CameraView.java
+++ b/briar-android/src/org/briarproject/android/view/CameraView.java
@@ -8,24 +8,24 @@ import android.hardware.Camera.Parameters;
 import android.hardware.Camera.Size;
 import android.os.Build;
 import android.util.AttributeSet;
-import android.util.DisplayMetrics;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 
 import org.briarproject.android.util.PreviewConsumer;
 
 import java.io.IOException;
-import java.util.Collections;
 import java.util.List;
 import java.util.logging.Logger;
 
 import static android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT;
+import static android.hardware.Camera.Parameters.FLASH_MODE_OFF;
 import static android.hardware.Camera.Parameters.FOCUS_MODE_AUTO;
 import static android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE;
 import static android.hardware.Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO;
 import static android.hardware.Camera.Parameters.FOCUS_MODE_EDOF;
 import static android.hardware.Camera.Parameters.FOCUS_MODE_FIXED;
 import static android.hardware.Camera.Parameters.FOCUS_MODE_MACRO;
+import static android.hardware.Camera.Parameters.SCENE_MODE_AUTO;
 import static android.hardware.Camera.Parameters.SCENE_MODE_BARCODE;
 import static java.util.logging.Level.INFO;
 import static java.util.logging.Level.WARNING;
@@ -75,10 +75,23 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 		this.camera = camera;
 		this.previewConsumer = previewConsumer;
 		setDisplayOrientation(rotationDegrees);
+		// Use barcode scene mode if it's available
 		Parameters params = camera.getParameters();
-		setFocusMode(params);
-		setPreviewSize(params);
-		applyParameters(params);
+		params = setSceneMode(camera, params);
+		if (SCENE_MODE_BARCODE.equals(params.getSceneMode())) {
+			// If the scene mode enabled the flash, try to disable it
+			if (!FLASH_MODE_OFF.equals(params.getFlashMode()))
+				params = disableFlash(camera, params);
+			// If the flash is still enabled, disable the scene mode
+			if (!FLASH_MODE_OFF.equals(params.getFlashMode()))
+				params = disableSceneMode(camera, params);
+		}
+		// Use the best available focus mode, preview size and other options
+		params = setBestParameters(camera, params);
+		// Enable auto focus if the selected focus mode uses it
+		enableAutoFocus(params.getFocusMode());
+		// Log the parameters that are being used (maybe not what we asked for)
+		logCameraParameters();
 		if (surfaceExists) startPreview(getHolder());
 	}
 
@@ -145,55 +158,67 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 		displayOrientation = orientation;
 	}
 
-	private void setFocusMode(Parameters params) {
+	private Parameters setSceneMode(Camera camera, Parameters params) {
+		List<String> sceneModes = params.getSupportedSceneModes();
+		if (sceneModes == null) return params;
+		if (LOG.isLoggable(INFO)) LOG.info("Scene modes: " + sceneModes);
+		if (sceneModes.contains(SCENE_MODE_BARCODE)) {
+			params.setSceneMode(SCENE_MODE_BARCODE);
+			camera.setParameters(params);
+			return camera.getParameters();
+		}
+		return params;
+	}
+
+	private Parameters disableFlash(Camera camera, Parameters params) {
+		params.setFlashMode(FLASH_MODE_OFF);
+		camera.setParameters(params);
+		return camera.getParameters();
+	}
+
+	private Parameters disableSceneMode(Camera camera, Parameters params) {
+		params.setSceneMode(SCENE_MODE_AUTO);
+		camera.setParameters(params);
+		return camera.getParameters();
+	}
+
+	private Parameters setBestParameters(Camera camera, Parameters params) {
+		setVideoStabilisation(params);
+		setFocusMode(params);
+		params.setFlashMode(FLASH_MODE_OFF);
+		setPreviewSize(params);
+		camera.setParameters(params);
+		return camera.getParameters();
+	}
+
+	private void setVideoStabilisation(Parameters params) {
 		if (Build.VERSION.SDK_INT >= 15 &&
 				params.isVideoStabilizationSupported()) {
-			LOG.info("Enabling video stabilisation");
 			params.setVideoStabilization(true);
 		}
-		// This returns null on the HTC Wildfire S
-		List<String> sceneModes = params.getSupportedSceneModes();
-		if (sceneModes == null) sceneModes = Collections.emptyList();
+	}
+
+	private void setFocusMode(Parameters params) {
 		List<String> focusModes = params.getSupportedFocusModes();
-		if (LOG.isLoggable(INFO)) {
-			LOG.info("Scene modes: " + sceneModes);
-			LOG.info("Focus modes: " + focusModes);
-		}
-		if (sceneModes.contains(SCENE_MODE_BARCODE)) {
-			LOG.info("Setting scene mode to barcode");
-			params.setSceneMode(SCENE_MODE_BARCODE);
-		}
+		if (LOG.isLoggable(INFO)) LOG.info("Focus modes: " + focusModes);
 		if (focusModes.contains(FOCUS_MODE_CONTINUOUS_PICTURE)) {
-			LOG.info("Setting focus mode to continuous picture");
 			params.setFocusMode(FOCUS_MODE_CONTINUOUS_PICTURE);
 		} else if (focusModes.contains(FOCUS_MODE_CONTINUOUS_VIDEO)) {
-			LOG.info("Setting focus mode to continuous video");
 			params.setFocusMode(FOCUS_MODE_CONTINUOUS_VIDEO);
 		} else if (focusModes.contains(FOCUS_MODE_EDOF)) {
-			LOG.info("Setting focus mode to EDOF");
 			params.setFocusMode(FOCUS_MODE_EDOF);
 		} else if (focusModes.contains(FOCUS_MODE_MACRO)) {
-			LOG.info("Setting focus mode to macro");
 			params.setFocusMode(FOCUS_MODE_MACRO);
-			autoFocus = true;
 		} else if (focusModes.contains(FOCUS_MODE_AUTO)) {
-			LOG.info("Setting focus mode to auto");
 			params.setFocusMode(FOCUS_MODE_AUTO);
-			autoFocus = true;
 		} else if (focusModes.contains(FOCUS_MODE_FIXED)) {
-			LOG.info("Setting focus mode to fixed");
 			params.setFocusMode(FOCUS_MODE_FIXED);
-		} else {
-			LOG.info("No suitable focus mode");
 		}
-		params.setZoom(0);
 	}
 
 	private void setPreviewSize(Parameters params) {
 		if (surfaceWidth == 0 || surfaceHeight == 0) return;
 		float idealRatio = (float) surfaceWidth / surfaceHeight;
-		DisplayMetrics screen = getContext().getResources().getDisplayMetrics();
-		int screenMax = Math.max(screen.widthPixels, screen.heightPixels);
 		boolean rotatePreview = displayOrientation % 180 == 90;
 		List<Size> sizes = params.getSupportedPreviewSizes();
 		Size bestSize = null;
@@ -204,7 +229,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 			float ratio = (float) width / height;
 			float stretch = Math.max(ratio / idealRatio, idealRatio / ratio);
 			int pixels = width * height;
-			float score = width * height / stretch;
+			float score = pixels / stretch;
 			if (LOG.isLoggable(INFO)) {
 				LOG.info("Size " + size.width + "x" + size.height
 						+ ", stretch " + stretch + ", pixels " + pixels
@@ -222,20 +247,34 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 		}
 	}
 
-	private void applyParameters(Parameters params) {
-		try {
-			camera.setParameters(params);
-		} catch (RuntimeException e) {
-			LOG.log(WARNING, "Error setting camera parameters", e);
+	private void enableAutoFocus(String focusMode) {
+		autoFocus = FOCUS_MODE_AUTO.equals(focusMode) ||
+				FOCUS_MODE_MACRO.equals(focusMode);
+	}
+
+	private void logCameraParameters() {
+		if (LOG.isLoggable(INFO)) {
+			Parameters params = camera.getParameters();
+			if (Build.VERSION.SDK_INT >= 15) {
+				LOG.info("Video stabilisation enabled: "
+						+ params.getVideoStabilization());
+			}
+			LOG.info("Scene mode: " + params.getSceneMode());
+			LOG.info("Focus mode: " + params.getFocusMode());
+			LOG.info("Flash mode: " + params.getFlashMode());
+			Size size = params.getPreviewSize();
+			LOG.info("Preview size: " + size.width + "x" + size.height);
 		}
 	}
 
+	@Override
 	public void surfaceCreated(SurfaceHolder holder) {
 		LOG.info("Surface created");
 		surfaceExists = true;
 		if (camera != null) startPreview(holder);
 	}
 
+	@Override
 	public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
 		if (LOG.isLoggable(INFO)) LOG.info("Surface changed: " + w + "x" + h);
 		surfaceWidth = w;
@@ -245,21 +284,25 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
 		try {
 			Parameters params = camera.getParameters();
 			setPreviewSize(params);
-			applyParameters(params);
+			camera.setParameters(params);
+			logCameraParameters();
 		} catch (RuntimeException e) {
-			LOG.log(WARNING, "Error getting camera parameters", e);
+			LOG.log(WARNING, "Error setting preview size", e);
 		}
 		startPreview(holder);
 	}
 
+	@Override
 	public void surfaceDestroyed(SurfaceHolder holder) {
 		LOG.info("Surface destroyed");
 		surfaceExists = false;
 	}
 
+	@Override
 	public void onAutoFocus(boolean success, final Camera camera) {
 		LOG.info("Auto focus succeeded: " + success);
 		postDelayed(new Runnable() {
+			@Override
 			public void run() {
 				retryAutoFocus();
 			}