diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index cd77033b992acec9c6cb8b52f4b3b0af3d76f3f5..496fd0c59828632959755e4116791c77c0af6df7 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -93,6 +93,7 @@
 	<string name="searching_format">Searching for contact with invitation code %06d\u2026</string>
 	<string name="connection_failed">Connection failed</string>
 	<string name="could_not_find_contact">Briar could not find your contact nearby</string>
+	<string name="could_not_open_camera">Could not access your camera. Please try again!</string>
 	<string name="try_again_button">Try Again</string>
 	<string name="connected_to_contact">Connected to contact</string>
 	<string name="calculating_confirmation_code">Calculating confirmation code\u2026</string>
diff --git a/briar-android/src/org/briarproject/android/BriarFragmentActivity.java b/briar-android/src/org/briarproject/android/BriarFragmentActivity.java
index e797dd80095dc7f20cfc5d9b148c34146596e2b5..0a9f22a2e4b93da6f1816da5e332b40690fbf15e 100644
--- a/briar-android/src/org/briarproject/android/BriarFragmentActivity.java
+++ b/briar-android/src/org/briarproject/android/BriarFragmentActivity.java
@@ -53,7 +53,6 @@ public abstract class BriarFragmentActivity extends BriarActivity {
 			as in Gmail/Inbox.
 			 */
 			startFragment(ContactListFragment.newInstance());
-
 		} else {
 			super.onBackPressed();
 		}
@@ -80,7 +79,7 @@ public abstract class BriarFragmentActivity extends BriarActivity {
 		dialog.show();
 	}
 
-	private void startFragment(BaseFragment fragment,
+	public void startFragment(BaseFragment fragment,
 			boolean isAddedToBackStack) {
 		startFragment(fragment, 0, 0, isAddedToBackStack);
 	}
diff --git a/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java b/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java
index e64ad7fa70e57649a47578b3637981bb6b31d9ab..3eb7f7bba94d3eeaef3b8fbd75aa65fa41246c3a 100644
--- a/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java
+++ b/briar-android/src/org/briarproject/android/keyagreement/KeyAgreementActivity.java
@@ -2,6 +2,7 @@ package org.briarproject.android.keyagreement;
 
 import android.os.Bundle;
 import android.support.v7.widget.Toolbar;
+import android.view.MenuItem;
 import android.view.View;
 import android.widget.TextView;
 import android.widget.Toast;
@@ -9,7 +10,8 @@ import android.widget.Toast;
 import org.briarproject.R;
 import org.briarproject.android.ActivityComponent;
 import org.briarproject.android.BriarFragmentActivity;
-import org.briarproject.android.fragment.BaseFragment;
+import org.briarproject.android.fragment.BaseFragment.BaseFragmentListener;
+import org.briarproject.android.keyagreement.ChooseIdentityFragment.IdentitySelectedListener;
 import org.briarproject.android.util.CustomAnimations;
 import org.briarproject.api.contact.ContactExchangeListener;
 import org.briarproject.api.contact.ContactExchangeTask;
@@ -32,8 +34,7 @@ import static android.widget.Toast.LENGTH_LONG;
 import static java.util.logging.Level.WARNING;
 
 public class KeyAgreementActivity extends BriarFragmentActivity implements
-		BaseFragment.BaseFragmentListener,
-		ChooseIdentityFragment.IdentitySelectedListener, EventListener,
+		BaseFragmentListener, IdentitySelectedListener, EventListener,
 		ContactExchangeListener {
 
 	private static final Logger LOG =
@@ -43,7 +44,6 @@ public class KeyAgreementActivity extends BriarFragmentActivity implements
 
 	private static final int STEP_ID = 1;
 	private static final int STEP_QR = 2;
-	private static final int STEPS = 2;
 
 	@Inject
 	protected EventBus eventBus;
@@ -87,15 +87,14 @@ public class KeyAgreementActivity extends BriarFragmentActivity implements
 		showStep(localAuthorId == null ? STEP_ID : STEP_QR);
 	}
 
-	@SuppressWarnings("ConstantConditions")
 	private void showStep(int step) {
 		switch (step) {
 			case STEP_QR:
-				startFragment(ShowQrCodeFragment.newInstance());
+				startFragment(ShowQrCodeFragment.newInstance(), true);
 				break;
 			case STEP_ID:
 			default:
-				startFragment(ChooseIdentityFragment.newInstance());
+				startFragment(ChooseIdentityFragment.newInstance(), true);
 				break;
 		}
 	}
@@ -121,6 +120,26 @@ public class KeyAgreementActivity extends BriarFragmentActivity implements
 		}
 	}
 
+	@Override
+	public boolean onOptionsItemSelected(final MenuItem item) {
+		switch (item.getItemId()) {
+			case android.R.id.home:
+				onBackPressed();
+				return true;
+			default:
+				return super.onOptionsItemSelected(item);
+		}
+	}
+
+	@Override
+	public void onBackPressed() {
+		if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
+			supportFinishAfterTransition();
+		} else {
+			super.onBackPressed();
+		}
+	}
+
 	@Override
 	public void showLoadingScreen(boolean isBlocking, int stringId) {
 		if (isBlocking) {
diff --git a/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java b/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java
index 8f508b33c59783244e8bd45df4e11f04186d1e07..2ea18075dc29ee444884047e1914b2f16c4181b3 100644
--- a/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java
+++ b/briar-android/src/org/briarproject/android/keyagreement/ShowQrCodeFragment.java
@@ -6,7 +6,6 @@ import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.hardware.Camera;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.support.annotation.Nullable;
 import android.util.Base64;
@@ -53,7 +52,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
 import static android.widget.Toast.LENGTH_LONG;
 import static java.util.logging.Level.WARNING;
 
-@SuppressWarnings("deprecation")
 public class ShowQrCodeFragment extends BaseEventFragment
 		implements QrCodeDecoder.ResultCallback {
 
@@ -195,44 +193,24 @@ public class ShowQrCodeFragment extends BaseEventFragment
 		});
 	}
 
+	@SuppressWarnings("deprecation")
 	private void openCamera() {
-		AsyncTask<Void, Void, Camera> openTask =
-				new AsyncTask<Void, Void, Camera>() {
-					@Override
-					protected Camera doInBackground(Void... unused) {
-						LOG.info("Opening camera");
-						try {
-							return Camera.open();
-						} catch (RuntimeException e) {
-							LOG.log(WARNING,
-									"Error opening camera, trying again", e);
-							try {
-								Thread.sleep(1000);
-							} catch (InterruptedException e2) {
-								LOG.info("Interrupted before second attempt");
-								return null;
-							}
-							try {
-								return Camera.open();
-							} catch (RuntimeException e2) {
-								LOG.log(WARNING, "Error opening camera", e2);
-								return null;
-							}
-						}
-					}
-
-					@Override
-					protected void onPostExecute(Camera camera) {
-						if (camera == null) {
-							// TODO better solution?
-							LOG.info("No Camera found, finishing...");
-							getActivity().finish();
-						} else {
-							cameraView.start(camera, decoder, 0);
-						}
-					}
-				};
-		openTask.execute();
+		LOG.info("Opening camera");
+		Camera camera;
+		try {
+			camera = Camera.open();
+		} catch (RuntimeException e) {
+			LOG.log(WARNING, e.toString(), e);
+			camera = null;
+		}
+		if (camera == null) {
+			LOG.log(WARNING, "Error opening camera");
+			Toast.makeText(getActivity(), R.string.could_not_open_camera,
+					LENGTH_LONG).show();
+			finish();
+			return;
+		}
+		cameraView.start(camera, decoder, 0);
 	}
 
 	private void releaseCamera() {
@@ -242,7 +220,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
 		} catch (RuntimeException e) {
 			LOG.log(WARNING, "Error releasing camera", e);
 			// TODO better solution
-			getActivity().finish();
+			finish();
 		}
 	}
 
@@ -295,7 +273,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
 				String input = Base64.encodeToString(
 						payloadEncoder.encode(localPayload), 0);
 				qrCode.setImageBitmap(
-						QrCodeUtils.createQrCode(getActivity(), input));
+						QrCodeUtils.createQrCode((Context) listener, input));
 				// Simple fade-in animation
 				AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
 				anim.setDuration(200);
@@ -365,6 +343,10 @@ public class ShowQrCodeFragment extends BaseEventFragment
 		});
 	}
 
+	private void finish() {
+		getActivity().getSupportFragmentManager().popBackStack();
+	}
+
 	private class BluetoothStateReceiver extends BroadcastReceiver {
 
 		@Override
diff --git a/briar-android/src/org/briarproject/android/util/QrCodeUtils.java b/briar-android/src/org/briarproject/android/util/QrCodeUtils.java
index ef8ff6ec6714e4c6a8f444d6c26a011053a9f21d..8a09d2cd8536dcb4a82dbeb5b9f81f67968257ad 100644
--- a/briar-android/src/org/briarproject/android/util/QrCodeUtils.java
+++ b/briar-android/src/org/briarproject/android/util/QrCodeUtils.java
@@ -1,6 +1,6 @@
 package org.briarproject.android.util;
 
-import android.app.Activity;
+import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.util.DisplayMetrics;
@@ -19,10 +19,9 @@ public class QrCodeUtils {
 	private static final Logger LOG =
 			Logger.getLogger(QrCodeUtils.class.getName());
 
-	public static Bitmap createQrCode(Activity activity, String input) {
+	public static Bitmap createQrCode(Context context, String input) {
 		// Get narrowest screen dimension
-		DisplayMetrics dm = new DisplayMetrics();
-		activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
+		DisplayMetrics dm = context.getResources().getDisplayMetrics();
 		int smallestDimen = Math.min(dm.widthPixels, dm.heightPixels);
 		try {
 			// Generate QR code