diff --git a/briar-android/AndroidManifest.xml b/briar-android/AndroidManifest.xml
index 51811047bad8ec2d63df5bad9b09469196264fae..f101a69da0f50dac6910a40ec5e76ee4891fbcde 100644
--- a/briar-android/AndroidManifest.xml
+++ b/briar-android/AndroidManifest.xml
@@ -42,7 +42,7 @@
 			</intent-filter>
 		</service>
 		<activity
-			android:name=".android.CrashReportActivity"
+			android:name=".android.DevReportActivity"
 			android:excludeFromRecents="true"
 			android:exported="false"
 			android:finishOnTaskLaunch="true"
diff --git a/briar-android/res/layout/activity_crash.xml b/briar-android/res/layout/activity_dev_report.xml
similarity index 79%
rename from briar-android/res/layout/activity_crash.xml
rename to briar-android/res/layout/activity_dev_report.xml
index bf68dc87a261cef879cc6ac9c52b46d4e4b912cf..2570255968fbcbd375cef3ca85ec5cb751ae8e14 100644
--- a/briar-android/res/layout/activity_crash.xml
+++ b/briar-android/res/layout/activity_dev_report.xml
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
+	xmlns:tools="http://schemas.android.com/tools"
 	android:layout_width="match_parent"
 	android:layout_height="match_parent"
 	android:orientation="vertical">
@@ -11,10 +12,11 @@
 		android:layout_height="wrap_content">
 
 		<TextView
+			android:id="@+id/title"
 			style="@style/TextAppearance.AppCompat.Large.Inverse"
 			android:layout_width="match_parent"
 			android:layout_height="wrap_content"
-			android:text="@string/crash_report_title"/>
+			tools:text="@string/crash_report_title"/>
 	</android.support.v7.widget.Toolbar>
 
 	<RelativeLayout
@@ -35,8 +37,8 @@
 				android:layout_marginLeft="@dimen/margin_large"
 				android:layout_marginRight="@dimen/margin_large"
 				android:layout_marginStart="@dimen/margin_large"
-				android:hint="@string/describe_crash"
-				android:inputType="textMultiLine|textCapSentences"/>
+				android:inputType="textMultiLine|textCapSentences"
+				tools:hint="@string/describe_crash"/>
 
 			<EditText
 				android:id="@+id/user_email"
@@ -51,13 +53,24 @@
 				android:inputType="textEmailAddress"
 				android:maxLines="1"/>
 
+			<CheckBox
+				android:id="@+id/include_debug_report"
+				android:layout_width="match_parent"
+				android:layout_height="wrap_content"
+				android:layout_marginEnd="@dimen/margin_large"
+				android:layout_marginLeft="@dimen/margin_large"
+				android:layout_marginRight="@dimen/margin_large"
+				android:layout_marginStart="@dimen/margin_large"
+				android:layout_marginTop="@dimen/margin_small"
+				android:text="@string/include_debug_report"/>
+
 			<ScrollView
 				android:layout_width="match_parent"
 				android:layout_height="wrap_content"
 				android:layout_marginTop="@dimen/margin_small">
 
 				<LinearLayout
-					android:id="@+id/crash_status"
+					android:id="@+id/report_content"
 					android:layout_width="match_parent"
 					android:layout_height="wrap_content"
 					android:gravity="center_horizontal"
@@ -78,10 +91,11 @@
 			android:layout_width="wrap_content"
 			android:layout_height="wrap_content"
 			android:layout_centerInParent="true"
-			android:indeterminate="true"/>
+			android:indeterminate="true"
+			android:visibility="gone"/>
 
 		<android.support.design.widget.FloatingActionButton
-			android:id="@+id/share_crash_report"
+			android:id="@+id/share_dev_report"
 			android:layout_width="wrap_content"
 			android:layout_height="wrap_content"
 			android:layout_alignParentBottom="true"
diff --git a/briar-android/res/layout/list_item_crash.xml b/briar-android/res/layout/list_item_crash.xml
index 8fff03f8ccdb24720296ce854943404e4ba055bd..305bee5a9ef04b88d8095d9fdf87c1fac62327a5 100644
--- a/briar-android/res/layout/list_item_crash.xml
+++ b/briar-android/res/layout/list_item_crash.xml
@@ -1,21 +1,35 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout
 	xmlns:android="http://schemas.android.com/apk/res/android"
+	xmlns:tools="http://schemas.android.com/tools"
 	android:layout_width="match_parent"
 	android:layout_height="match_parent"
 	android:orientation="vertical">
 
-	<TextView
-		android:id="@+id/title"
-		android:layout_width="wrap_content"
+	<LinearLayout
+		android:layout_width="match_parent"
 		android:layout_height="wrap_content"
-		android:layout_marginBottom="@dimen/margin_small"
-		android:textSize="@dimen/text_size_large"/>
+		android:orientation="horizontal">
+
+		<CheckBox
+			android:id="@+id/include_in_report"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"/>
+
+		<TextView
+			android:id="@+id/title"
+			android:layout_width="wrap_content"
+			android:layout_height="wrap_content"
+			android:layout_marginBottom="@dimen/margin_small"
+			android:textSize="@dimen/text_size_large"
+			tools:text="Crash log entry title"/>
+	</LinearLayout>
 
 	<TextView
 		android:id="@+id/content"
 		android:layout_width="wrap_content"
 		android:layout_height="wrap_content"
-		android:layout_marginBottom="@dimen/margin_medium"/>
+		android:layout_marginBottom="@dimen/margin_medium"
+		tools:text="Crash log entry value"/>
 
 </LinearLayout>
\ No newline at end of file
diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index 997d4d451d52ed15b1fc2d9fd1946339977380fa..d4d6ff74a9172d33816c2dbfe95bb5fef265e45e 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -4,11 +4,13 @@
 	<string name="nav_drawer_close_description">Close the navigation drawer</string>
 	<string name="app_name">Briar</string>
 	<string name="crash_report_title">Briar Crash Report</string>
+	<string name="feedback_title">Feedback</string>
 	<string name="describe_crash">Describe what happened</string>
+	<string name="enter_feedback">Enter your feedback</string>
 	<string name="optional_contact_email">Optional contact email</string>
-	<string name="could_not_load_crash_data">Could not load crash data.</string>
-	<string name="crash_report_saved">Crash report saved. It will be sent the next time you log into Briar.</string>
-	<string name="crash_report_not_saved">Could not save crash report to disk.</string>
+	<string name="include_debug_report">Include debug report?</string>
+	<string name="could_not_load_report_data">Could not load report data.</string>
+	<string name="dev_report_saved">Report saved. It will be sent the next time you log into Briar.</string>
 	<string name="ongoing_notification_title">Signed into Briar</string>
 	<string name="ongoing_notification_text">Touch to show the dashboard.</string>
 	<string name="setup_title">Briar Setup</string>
diff --git a/briar-android/res/xml/settings_debug.xml b/briar-android/res/xml/settings_debug.xml
index e977ac7f90e7fbc13ba26775262859ddef7f7d84..ebc397d5ee147247ab1f48ca63c4e2d41960ed82 100644
--- a/briar-android/res/xml/settings_debug.xml
+++ b/briar-android/res/xml/settings_debug.xml
@@ -14,6 +14,10 @@
 
 		</Preference>
 
+		<Preference
+			android:key="send_feedback"
+			android:title="Send feedback"/>
+
 	</PreferenceCategory>
 
 </PreferenceScreen>
\ No newline at end of file
diff --git a/briar-android/src/org/briarproject/android/AndroidComponent.java b/briar-android/src/org/briarproject/android/AndroidComponent.java
index fcb53c41cb7f3edabd1df6394f9829fee2bf97a6..534399af844580a79d51827df8f199278ba96c1a 100644
--- a/briar-android/src/org/briarproject/android/AndroidComponent.java
+++ b/briar-android/src/org/briarproject/android/AndroidComponent.java
@@ -38,7 +38,7 @@ import dagger.Component;
 })
 public interface AndroidComponent extends CoreEagerSingletons {
 
-	void inject(CrashReportActivity crashReportActivity);
+	void inject(DevReportActivity devReportActivity);
 
 	void inject(SplashScreenActivity activity);
 
diff --git a/briar-android/src/org/briarproject/android/BriarApplication.java b/briar-android/src/org/briarproject/android/BriarApplication.java
index 688dae84bfe9837c284f47c272726bc800f48dae..eec480309deb5f4ae863345868662f0a6d4d670c 100644
--- a/briar-android/src/org/briarproject/android/BriarApplication.java
+++ b/briar-android/src/org/briarproject/android/BriarApplication.java
@@ -18,8 +18,8 @@ import java.util.logging.Logger;
 		logcatArguments = {"-d", "-v", "time", "*:I"},
 		reportSenderFactoryClasses = {BriarReportSenderFactory.class},
 		mode = ReportingInteractionMode.DIALOG,
-		reportDialogClass = CrashReportActivity.class,
-		resDialogOkToast = R.string.crash_report_saved,
+		reportDialogClass = DevReportActivity.class,
+		resDialogOkToast = R.string.dev_report_saved,
 		deleteOldUnsentReportsOnApplicationStart = false
 )
 public class BriarApplication extends Application {
diff --git a/briar-android/src/org/briarproject/android/CrashReportActivity.java b/briar-android/src/org/briarproject/android/CrashReportActivity.java
deleted file mode 100644
index e93b7b53daa142818bd8fad3e770ef4745b4aa89..0000000000000000000000000000000000000000
--- a/briar-android/src/org/briarproject/android/CrashReportActivity.java
+++ /dev/null
@@ -1,210 +0,0 @@
-package org.briarproject.android;
-
-import android.content.DialogInterface;
-import android.content.SharedPreferences;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.support.v7.app.AlertDialog;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import org.acra.ACRA;
-import org.acra.ACRAConstants;
-import org.acra.ReportField;
-import org.acra.collector.CrashReportData;
-import org.acra.dialog.BaseCrashReportDialog;
-import org.acra.file.CrashReportPersister;
-import org.acra.prefs.SharedPreferencesFactory;
-import org.briarproject.R;
-import org.briarproject.api.reporting.DevReporter;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Map.Entry;
-import java.util.logging.Logger;
-
-import javax.inject.Inject;
-
-import static android.view.View.GONE;
-import static android.view.View.INVISIBLE;
-import static android.view.View.VISIBLE;
-import static java.util.logging.Level.WARNING;
-
-public class CrashReportActivity extends BaseCrashReportDialog
-		implements DialogInterface.OnClickListener,
-		DialogInterface.OnCancelListener {
-
-	private static final Logger LOG =
-			Logger.getLogger(CrashReportActivity.class.getName());
-
-	private static final String STATE_REVIEWING = "reviewing";
-
-	private SharedPreferencesFactory sharedPreferencesFactory;
-	private EditText userCommentView = null;
-	private EditText userEmailView = null;
-	private LinearLayout status = null;
-	private View progress = null;
-
-	@Inject
-	protected DevReporter reporter;
-
-	boolean reviewing;
-
-	@Override
-	public void onCreate(Bundle state) {
-		super.onCreate(state);
-		setContentView(R.layout.activity_crash);
-
-		((BriarApplication) getApplication()).getApplicationComponent()
-				.inject(this);
-
-		sharedPreferencesFactory =
-				new SharedPreferencesFactory(getApplicationContext(),
-						getConfig());
-
-		userCommentView = (EditText) findViewById(R.id.user_comment);
-		userEmailView = (EditText) findViewById(R.id.user_email);
-		status = (LinearLayout) findViewById(R.id.crash_status);
-		progress = findViewById(R.id.progress_wheel);
-
-		findViewById(R.id.share_crash_report).setOnClickListener(
-				new OnClickListener() {
-					@Override
-					public void onClick(View v) {
-						processReport();
-					}
-				});
-
-		final SharedPreferences prefs = sharedPreferencesFactory.create();
-		String userEmail = prefs.getString(ACRA.PREF_USER_EMAIL_ADDRESS, "");
-		userEmailView.setText(userEmail);
-
-		if (state != null)
-			reviewing = state.getBoolean(STATE_REVIEWING, false);
-	}
-
-	@Override
-	public void onResume() {
-		super.onResume();
-		if (!reviewing) showDialog();
-		refresh();
-	}
-
-	@Override
-	public void onSaveInstanceState(Bundle state) {
-		super.onSaveInstanceState(state);
-		state.putBoolean(STATE_REVIEWING, reviewing);
-	}
-
-	@Override
-	public void onBackPressed() {
-		// show home screen, otherwise we are crashing again
-		//Intent intent = new Intent(Intent.ACTION_MAIN);
-		//intent.addCategory(Intent.CATEGORY_HOME);
-		//startActivity(intent);
-		closeReport();
-	}
-
-	@Override
-	public void onClick(DialogInterface dialog, int which) {
-		if (which == DialogInterface.BUTTON_POSITIVE) {
-			dialog.dismiss();
-		} else {
-			dialog.cancel();
-		}
-	}
-
-	@Override
-	public void onCancel(DialogInterface dialog) {
-		closeReport();
-	}
-
-	private void showDialog() {
-		AlertDialog.Builder builder = new AlertDialog.Builder(this,
-				R.style.BriarDialogTheme);
-		builder.setTitle(R.string.dialog_title_share_crash_report)
-				.setIcon(R.drawable.ic_warning_black_24dp)
-				.setMessage(R.string.dialog_message_share_crash_report)
-				.setPositiveButton(R.string.dialog_button_ok, this)
-				.setNegativeButton(R.string.cancel_button, this);
-		AlertDialog dialog = builder.create();
-		dialog.setCanceledOnTouchOutside(false);
-		dialog.setOnCancelListener(this);
-		dialog.show();
-	}
-
-	private void refresh() {
-		status.setVisibility(INVISIBLE);
-		progress.setVisibility(VISIBLE);
-		status.removeAllViews();
-		new AsyncTask<Void, Void, CrashReportData>() {
-
-			@Override
-			protected CrashReportData doInBackground(Void... args) {
-				File reportFile = (File) getIntent().getSerializableExtra(
-						ACRAConstants.EXTRA_REPORT_FILE);
-				final CrashReportPersister persister =
-						new CrashReportPersister();
-				try {
-					return persister.load(reportFile);
-				} catch (IOException e) {
-					LOG.log(WARNING, "Could not load report file", e);
-					return null;
-				}
-			}
-
-			@Override
-			protected void onPostExecute(CrashReportData crashData) {
-				LayoutInflater inflater = getLayoutInflater();
-				if (crashData != null) {
-					for (Entry<ReportField, String> e : crashData.entrySet()) {
-						View v = inflater.inflate(R.layout.list_item_crash,
-								status, false);
-						((TextView) v.findViewById(R.id.title))
-								.setText(e.getKey().toString());
-						((TextView) v.findViewById(R.id.content))
-								.setText(e.getValue());
-						status.addView(v);
-					}
-				} else {
-					View v = inflater.inflate(
-							android.R.layout.simple_list_item_1, status, false);
-					((TextView) v.findViewById(android.R.id.text1))
-							.setText(R.string.could_not_load_crash_data);
-					status.addView(v);
-				}
-				status.setVisibility(VISIBLE);
-				progress.setVisibility(GONE);
-			}
-		}.execute();
-	}
-
-	private void processReport() {
-		// Retrieve user comment
-		final String comment = userCommentView != null ?
-				userCommentView.getText().toString() : "";
-
-		// Store the user email
-		final String userEmail;
-		final SharedPreferences prefs = sharedPreferencesFactory.create();
-		if (userEmailView != null) {
-			userEmail = userEmailView.getText().toString();
-			final SharedPreferences.Editor prefEditor = prefs.edit();
-			prefEditor.putString(ACRA.PREF_USER_EMAIL_ADDRESS, userEmail);
-			prefEditor.commit();
-		} else {
-			userEmail = prefs.getString(ACRA.PREF_USER_EMAIL_ADDRESS, "");
-		}
-		sendCrash(comment, userEmail);
-		finish();
-	}
-
-	private void closeReport() {
-		cancelReports();
-		finish();
-	}
-}
diff --git a/briar-android/src/org/briarproject/android/DevReportActivity.java b/briar-android/src/org/briarproject/android/DevReportActivity.java
new file mode 100644
index 0000000000000000000000000000000000000000..4c550b07f960e1ce3fdbc81affd6649dcbf8973b
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/DevReportActivity.java
@@ -0,0 +1,347 @@
+package org.briarproject.android;
+
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v7.app.AlertDialog;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import org.acra.ACRA;
+import org.acra.ACRAConstants;
+import org.acra.ReportField;
+import org.acra.collector.CrashReportData;
+import org.acra.dialog.BaseCrashReportDialog;
+import org.acra.file.CrashReportPersister;
+import org.acra.prefs.SharedPreferencesFactory;
+import org.briarproject.R;
+import org.briarproject.android.util.UserFeedback;
+import org.briarproject.api.reporting.DevReporter;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.inject.Inject;
+
+import static android.view.View.GONE;
+import static android.view.View.INVISIBLE;
+import static android.view.View.VISIBLE;
+import static java.util.logging.Level.WARNING;
+import static org.acra.ReportField.ANDROID_VERSION;
+import static org.acra.ReportField.APP_VERSION_CODE;
+import static org.acra.ReportField.APP_VERSION_NAME;
+import static org.acra.ReportField.PACKAGE_NAME;
+import static org.acra.ReportField.REPORT_ID;
+import static org.acra.ReportField.STACK_TRACE;
+
+public class DevReportActivity extends BaseCrashReportDialog
+		implements DialogInterface.OnClickListener,
+		DialogInterface.OnCancelListener,
+		CompoundButton.OnCheckedChangeListener {
+
+	private static final Logger LOG =
+			Logger.getLogger(DevReportActivity.class.getName());
+
+	private static final String PREF_EXCLUDED_FIELDS = "excludedReportFields";
+	private static final String STATE_REVIEWING = "reviewing";
+	private static final Set<ReportField> requiredFields = new HashSet<>();
+
+	static {
+		requiredFields.add(REPORT_ID);
+		requiredFields.add(APP_VERSION_CODE);
+		requiredFields.add(APP_VERSION_NAME);
+		requiredFields.add(PACKAGE_NAME);
+		requiredFields.add(ANDROID_VERSION);
+		requiredFields.add(STACK_TRACE);
+	}
+
+	@Inject
+	protected DevReporter reporter;
+
+	private SharedPreferencesFactory sharedPreferencesFactory;
+	private Set<ReportField> excludedFields;
+	private EditText userCommentView = null;
+	private EditText userEmailView = null;
+	private CheckBox includeDebugReport = null;
+	private LinearLayout report = null;
+	private View progress = null;
+	private View share = null;
+	private boolean reviewing = false;
+
+	@Override
+	public void onCreate(Bundle state) {
+		super.onCreate(state);
+		setContentView(R.layout.activity_dev_report);
+
+		((BriarApplication) getApplication()).getApplicationComponent()
+				.inject(this);
+
+		sharedPreferencesFactory =
+				new SharedPreferencesFactory(getApplicationContext(),
+						getConfig());
+
+		final SharedPreferences prefs = sharedPreferencesFactory.create();
+		excludedFields = new HashSet<>();
+		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+			for (String name : prefs.getStringSet(PREF_EXCLUDED_FIELDS,
+					new HashSet<String>())) {
+				excludedFields.add(ReportField.valueOf(name));
+			}
+		}
+
+		TextView title = (TextView) findViewById(R.id.title);
+		userCommentView = (EditText) findViewById(R.id.user_comment);
+		userEmailView = (EditText) findViewById(R.id.user_email);
+		includeDebugReport = (CheckBox) findViewById(R.id.include_debug_report);
+		report = (LinearLayout) findViewById(R.id.report_content);
+		progress = findViewById(R.id.progress_wheel);
+		share = findViewById(R.id.share_dev_report);
+
+		title.setText(isFeedback() ? R.string.feedback_title :
+				R.string.crash_report_title);
+		userCommentView.setHint(isFeedback() ? R.string.enter_feedback :
+				R.string.describe_crash);
+
+		includeDebugReport.setVisibility(isFeedback() ? VISIBLE : GONE);
+		report.setVisibility(isFeedback() ? GONE : VISIBLE);
+
+		includeDebugReport.setOnClickListener(new View.OnClickListener() {
+			@Override
+			public void onClick(View v) {
+				if (includeDebugReport.isChecked())
+					refresh();
+				else
+					report.setVisibility(GONE);
+			}
+		});
+		share.setOnClickListener(
+				new OnClickListener() {
+					@Override
+					public void onClick(View v) {
+						processReport();
+					}
+				});
+
+		String userEmail = prefs.getString(ACRA.PREF_USER_EMAIL_ADDRESS, "");
+		userEmailView.setText(userEmail);
+
+		if (state != null)
+			reviewing = state.getBoolean(STATE_REVIEWING, false);
+	}
+
+	@Override
+	public void onResume() {
+		super.onResume();
+		if (!isFeedback() && !reviewing) showCrashDialog();
+		if (!isFeedback() || includeDebugReport.isChecked()) refresh();
+	}
+
+	@Override
+	public void onSaveInstanceState(Bundle state) {
+		super.onSaveInstanceState(state);
+		state.putBoolean(STATE_REVIEWING, reviewing);
+	}
+
+	@Override
+	public void onBackPressed() {
+		closeReport();
+	}
+
+	@Override
+	public void onClick(DialogInterface dialog, int which) {
+		if (which == DialogInterface.BUTTON_POSITIVE) {
+			dialog.dismiss();
+		} else {
+			dialog.cancel();
+		}
+	}
+
+	@Override
+	public void onCancel(DialogInterface dialog) {
+		closeReport();
+	}
+
+	@Override
+	public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+		ReportField field = (ReportField) buttonView.getTag();
+		if (field != null) {
+			if (isChecked)
+				excludedFields.remove(field);
+			else
+				excludedFields.add(field);
+		}
+	}
+
+	@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
+	private boolean isFeedback() {
+		return getException() instanceof UserFeedback;
+	}
+
+	private void showCrashDialog() {
+		AlertDialog.Builder builder = new AlertDialog.Builder(this,
+				R.style.BriarDialogTheme);
+		builder.setTitle(R.string.dialog_title_share_crash_report)
+				.setIcon(R.drawable.ic_warning_black_24dp)
+				.setMessage(R.string.dialog_message_share_crash_report)
+				.setPositiveButton(R.string.dialog_button_ok, this)
+				.setNegativeButton(R.string.cancel_button, this);
+		AlertDialog dialog = builder.create();
+		dialog.setCanceledOnTouchOutside(false);
+		dialog.setOnCancelListener(this);
+		dialog.show();
+	}
+
+	private void refresh() {
+		report.setVisibility(INVISIBLE);
+		progress.setVisibility(VISIBLE);
+		report.removeAllViews();
+		new AsyncTask<Void, Void, CrashReportData>() {
+
+			@Override
+			protected CrashReportData doInBackground(Void... args) {
+				File reportFile = (File) getIntent().getSerializableExtra(
+						ACRAConstants.EXTRA_REPORT_FILE);
+				final CrashReportPersister persister =
+						new CrashReportPersister();
+				try {
+					return persister.load(reportFile);
+				} catch (IOException e) {
+					LOG.log(WARNING, "Could not load report file", e);
+					return null;
+				}
+			}
+
+			@Override
+			protected void onPostExecute(CrashReportData crashData) {
+				LayoutInflater inflater = getLayoutInflater();
+				if (crashData != null) {
+					for (Entry<ReportField, String> e : crashData.entrySet()) {
+						ReportField field = e.getKey();
+						boolean required = requiredFields.contains(field);
+						boolean excluded = excludedFields.contains(field);
+						View v = inflater.inflate(R.layout.list_item_crash,
+								report, false);
+						CheckBox cb = (CheckBox) v
+								.findViewById(R.id.include_in_report);
+						cb.setTag(field);
+						cb.setChecked(required || !excluded);
+						cb.setEnabled(!required);
+						cb.setOnCheckedChangeListener(DevReportActivity.this);
+						((TextView) v.findViewById(R.id.title))
+								.setText(e.getKey().toString());
+						((TextView) v.findViewById(R.id.content))
+								.setText(e.getValue());
+						report.addView(v);
+					}
+				} else {
+					View v = inflater.inflate(
+							android.R.layout.simple_list_item_1, report, false);
+					((TextView) v.findViewById(android.R.id.text1))
+							.setText(R.string.could_not_load_report_data);
+					report.addView(v);
+				}
+				report.setVisibility(VISIBLE);
+				progress.setVisibility(GONE);
+			}
+		}.execute();
+	}
+
+	private void processReport() {
+		userCommentView.setEnabled(false);
+		userEmailView.setEnabled(false);
+		share.setEnabled(false);
+		progress.setVisibility(VISIBLE);
+		final boolean includeReport =
+				!isFeedback() || includeDebugReport.isChecked();
+		new AsyncTask<Void, Void, Boolean>() {
+
+			@Override
+			protected Boolean doInBackground(Void... args) {
+				File reportFile = (File) getIntent().getSerializableExtra(
+						ACRAConstants.EXTRA_REPORT_FILE);
+				CrashReportPersister persister = new CrashReportPersister();
+				try {
+					CrashReportData data = persister.load(reportFile);
+					if (includeReport) {
+						for (ReportField field : excludedFields) {
+							LOG.info("Removing field " + field.name());
+							data.remove(field);
+						}
+					} else {
+						Iterator<Entry<ReportField, String>> iter =
+								data.entrySet().iterator();
+						while (iter.hasNext()) {
+							Entry<ReportField, String> e = iter.next();
+							if (!requiredFields.contains(e.getKey())) {
+								iter.remove();
+							}
+						}
+					}
+					persister.store(data, reportFile);
+					return true;
+				} catch (IOException e) {
+					LOG.log(WARNING, "Error processing report file", e);
+					return false;
+				}
+			}
+
+			@Override
+			protected void onPostExecute(Boolean success) {
+				final SharedPreferences prefs =
+						sharedPreferencesFactory.create();
+				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+					final SharedPreferences.Editor prefEditor =
+							prefs.edit();
+					Set<String> fields = new HashSet<>();
+					for (ReportField field : excludedFields) {
+						fields.add(field.name());
+					}
+					prefEditor.putStringSet(PREF_EXCLUDED_FIELDS, fields);
+					prefEditor.commit();
+				}
+
+				if (success) {
+					// Retrieve user comment
+					final String comment = userCommentView != null ?
+							userCommentView.getText().toString() : "";
+
+					// Store the user email
+					final String userEmail;
+					if (userEmailView != null) {
+						userEmail = userEmailView.getText().toString();
+						final SharedPreferences.Editor prefEditor =
+								prefs.edit();
+						prefEditor
+								.putString(ACRA.PREF_USER_EMAIL_ADDRESS,
+										userEmail);
+						prefEditor.commit();
+					} else {
+						userEmail =
+								prefs.getString(ACRA.PREF_USER_EMAIL_ADDRESS,
+										"");
+					}
+					sendCrash(comment, userEmail);
+				}
+				finish();
+			}
+		}.execute();
+	}
+
+	private void closeReport() {
+		cancelReports();
+		finish();
+	}
+}
diff --git a/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java b/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java
index e38eeff714232a4e8b699ddbddd05c796e9fb7db..462f0771b408357d6acb1cd4bc4b188f1a46b320 100644
--- a/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java
+++ b/briar-android/src/org/briarproject/android/fragment/SettingsFragment.java
@@ -15,9 +15,11 @@ import android.support.v7.widget.RecyclerView;
 import android.view.LayoutInflater;
 import android.view.ViewGroup;
 
+import org.acra.ACRA;
 import org.briarproject.R;
 import org.briarproject.android.SettingsActivity;
 import org.briarproject.android.util.AndroidUtils;
+import org.briarproject.android.util.UserFeedback;
 import org.briarproject.android.widget.PreferenceDividerDecoration;
 import org.briarproject.api.db.DbException;
 import org.briarproject.api.event.Event;
@@ -131,6 +133,14 @@ public class SettingsFragment extends PreferenceFragmentCompat
 
 		if (SHOW_TESTING_ACTIVITY) {
 			addPreferencesFromResource(R.xml.settings_debug);
+			findPreference("send_feedback").setOnPreferenceClickListener(
+					new Preference.OnPreferenceClickListener() {
+						@Override
+						public boolean onPreferenceClick(Preference preference) {
+							triggerFeedback();
+							return true;
+						}
+					});
 		}
 
 		loadSettings();
@@ -211,6 +221,16 @@ public class SettingsFragment extends PreferenceFragmentCompat
 		});
 	}
 
+	private void triggerFeedback() {
+		new Thread(new Runnable() {
+			@Override
+			public void run() {
+				ACRA.getErrorReporter()
+						.handleException(new UserFeedback(), false);
+			}
+		}).start();
+	}
+
 	@Override
 	public boolean onPreferenceChange(Preference preference, Object o) {
 		if (preference == enableBluetooth) {
diff --git a/briar-android/src/org/briarproject/android/util/BriarReportSender.java b/briar-android/src/org/briarproject/android/util/BriarReportSender.java
index 49507a6356526ca1ef5a898efbb8083ef65ba6ab..50b6fa2c54d4a1745989d8495ba4f2263f996567 100644
--- a/briar-android/src/org/briarproject/android/util/BriarReportSender.java
+++ b/briar-android/src/org/briarproject/android/util/BriarReportSender.java
@@ -39,7 +39,7 @@ public class BriarReportSender implements ReportSender {
 			throw new ReportSenderException("Couldn't create JSON", e);
 		}
 		try {
-			reporter.encryptCrashReportToFile(
+			reporter.encryptReportToFile(
 					AndroidUtils.getReportDir(context),
 					errorContent.getProperty(ReportField.REPORT_ID),
 					crashReport);
diff --git a/briar-android/src/org/briarproject/android/util/UserFeedback.java b/briar-android/src/org/briarproject/android/util/UserFeedback.java
new file mode 100644
index 0000000000000000000000000000000000000000..3c259458e51afe025ac0f2422e7d17d7b906a38d
--- /dev/null
+++ b/briar-android/src/org/briarproject/android/util/UserFeedback.java
@@ -0,0 +1,5 @@
+package org.briarproject.android.util;
+
+public class UserFeedback extends Exception {
+
+}
diff --git a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
index 0ba0a66604e2282faefa1f0297e9ba53d64ea4ff..043839d6f7b84ffc35a229af9653eeada9fb0329 100644
--- a/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
+++ b/briar-android/src/org/briarproject/plugins/tor/TorPlugin.java
@@ -365,7 +365,7 @@ class TorPlugin implements DuplexPlugin, EventHandler,
 		ioExecutor.execute(new Runnable() {
 			@Override
 			public void run() {
-				reporter.sendCrashReports(
+				reporter.sendReports(
 						AndroidUtils.getReportDir(appContext), SOCKS_PORT);
 			}
 		});
diff --git a/briar-api/src/org/briarproject/api/reporting/DevReporter.java b/briar-api/src/org/briarproject/api/reporting/DevReporter.java
index 6dc5f98023587132b4a0c1c387dffae22bfc8912..f4b17820c1a46394e20ae9e9769db0adc490f17b 100644
--- a/briar-api/src/org/briarproject/api/reporting/DevReporter.java
+++ b/briar-api/src/org/briarproject/api/reporting/DevReporter.java
@@ -2,6 +2,7 @@ package org.briarproject.api.reporting;
 
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 
 /**
  * A task for reporting back to the developers.
@@ -9,20 +10,20 @@ import java.io.FileNotFoundException;
 public interface DevReporter {
 
 	/**
-	 * Store a crash report encrypted on-disk to be sent later.
+	 * Store a report encrypted on-disk to be sent later.
 	 *
-	 * @param crashReportDir the directory where crash reports are stored.
-	 * @param crashReport    the crash report in the form expected by the server.
+	 * @param reportDir the directory where reports are stored.
+	 * @param report    the report in the form expected by the server.
 	 * @throws FileNotFoundException if the report could not be written.
 	 */
-	void encryptCrashReportToFile(File crashReportDir, String filename,
-			String crashReport) throws FileNotFoundException;
+	void encryptReportToFile(File reportDir, String filename,
+			String report) throws FileNotFoundException;
 
 	/**
-	 * Send crash reports previously stored on-disk.
+	 * Send reports previously stored on-disk.
 	 *
-	 * @param crashReportDir the directory where crash reports are stored.
-	 * @param socksPort      the SOCKS port of a Tor client.
+	 * @param reportDir the directory where reports are stored.
+	 * @param socksPort the SOCKS port of a Tor client.
 	 */
-	void sendCrashReports(File crashReportDir, int socksPort);
+	void sendReports(File reportDir, int socksPort);
 }
diff --git a/briar-core/src/org/briarproject/reporting/DevReporterImpl.java b/briar-core/src/org/briarproject/reporting/DevReporterImpl.java
index 7ca4b3b45daea6fc8299835a64244f5a894008a7..6d5c49f73a7a6917d385c10d8e535fa81a65f1a4 100644
--- a/briar-core/src/org/briarproject/reporting/DevReporterImpl.java
+++ b/briar-core/src/org/briarproject/reporting/DevReporterImpl.java
@@ -53,17 +53,17 @@ class DevReporterImpl implements DevReporter {
 	}
 
 	@Override
-	public void encryptCrashReportToFile(File crashReportDir, String filename,
-			String crashReport) throws FileNotFoundException {
+	public void encryptReportToFile(File reportDir, String filename,
+			String report) throws FileNotFoundException {
 		String encryptedReport =
 				crypto.encryptToKey(devConfig.getDevPublicKey(),
-						StringUtils.toUtf8(crashReport));
+						StringUtils.toUtf8(report));
 
-		File report = new File(crashReportDir, filename);
+		File f = new File(reportDir, filename);
 		PrintWriter writer = null;
 		try {
 			writer = new PrintWriter(
-					new OutputStreamWriter(new FileOutputStream(report)));
+					new OutputStreamWriter(new FileOutputStream(f)));
 			writer.append(encryptedReport);
 			writer.flush();
 		} finally {
@@ -73,10 +73,10 @@ class DevReporterImpl implements DevReporter {
 	}
 
 	@Override
-	public void sendCrashReports(File crashReportDir, int socksPort) {
-		File[] reports = crashReportDir.listFiles();
+	public void sendReports(File reportDir, int socksPort) {
+		File[] reports = reportDir.listFiles();
 		if (reports == null || reports.length == 0)
-			return; // No crash reports to send
+			return; // No reports to send
 
 		LOG.info("Connecting to developers");
 		Socket s;
@@ -88,7 +88,7 @@ class DevReporterImpl implements DevReporter {
 			return;
 		}
 
-		LOG.info("Sending crash reports to developers");
+		LOG.info("Sending reports to developers");
 		OutputStream output;
 		PrintWriter writer = null;
 		try {
@@ -106,7 +106,7 @@ class DevReporterImpl implements DevReporter {
 				writer.flush();
 				f.delete();
 			}
-			LOG.info("Crash reports sent");
+			LOG.info("Reports sent");
 		} catch (IOException e) {
 			if (LOG.isLoggable(WARNING))
 				LOG.log(WARNING, "Connection to developers failed", e);