diff --git a/briar-android/AndroidManifest.xml b/briar-android/AndroidManifest.xml
index ac262a3c2067cc6abebc478b0e2b751b87305546..e5e660ddd4700c84bbe043260c7aa7478f124280 100644
--- a/briar-android/AndroidManifest.xml
+++ b/briar-android/AndroidManifest.xml
@@ -194,6 +194,11 @@
 		<activity
 			android:name=".android.panic.PanicPreferencesActivity"
 			android:label="@string/panic_setting" >
+			<intent-filter>
+				<action android:name="info.guardianproject.panic.action.CONNECT" />
+				<action android:name="info.guardianproject.panic.action.DISCONNECT" />
+				<category android:name="android.intent.category.DEFAULT" />
+			</intent-filter>
 		</activity>
 		<activity
 			android:name=".android.panic.PanicResponderActivity"
diff --git a/briar-android/build.gradle b/briar-android/build.gradle
index 4c3835102e719748bff27bcce6c47a1eab04dc03..b52c0c52177a6818226ee7be439efe4575698443 100644
--- a/briar-android/build.gradle
+++ b/briar-android/build.gradle
@@ -17,6 +17,7 @@ dependencies {
     compile "com.android.support:preference-v14:23.1.1"
     compile "com.android.support:design:23.1.1"
     compile "info.guardianproject.panic:panic:0.5"
+    compile "info.guardianproject.trustedintents:trustedintents:0.2"
 }
 
 dependencyVerification {
@@ -29,6 +30,7 @@ dependencyVerification {
             'com.android.support:support-annotations:f347a35b9748a4103b39a6714a77e2100f488d623fd6268e259c177b200e9d82',
             'com.android.support:recyclerview-v7:7606373da0931a1e62588335465a0e390cd676c98117edab29220317495faefd',
             'info.guardianproject.panic:panic:a7ed9439826db2e9901649892cf9afbe76f00991b768d8f4c26332d7c9406cb2',
+            'info.guardianproject.trustedintents:trustedintents:6221456d8821a8d974c2acf86306900237cf6afaaa94a4c9c44e161350f80f3e',
     ]
 }
 
diff --git a/briar-android/res/xml/panic_preferences.xml b/briar-android/res/xml/panic_preferences.xml
index 3b40f0e3dfed14616a4015f1374e60ae436493a0..af9bbeca501b78bac1abd2115e0a3279ebd089d3 100644
--- a/briar-android/res/xml/panic_preferences.xml
+++ b/briar-android/res/xml/panic_preferences.xml
@@ -8,4 +8,22 @@
 		android:summary="@string/lock_setting_summary"
 		android:defaultValue="true"/>
 
+	<PreferenceCategory
+		android:title="Destructive Actions">
+
+		<ListPreference
+			android:key="pref_key_panic_app"
+			android:title="@string/panic_app_setting_title"
+			android:summary="@string/panic_app_setting_summary"
+			android:icon="@android:drawable/ic_menu_close_clear_cancel"/>
+
+		<CheckBoxPreference
+			android:key="pref_key_purge"
+			android:title="@string/purge_setting_title"
+			android:summary="@string/purge_setting_summary"
+			android:enabled="false"
+			android:defaultValue="false"/>
+
+	</PreferenceCategory>
+
 </PreferenceScreen>
\ No newline at end of file
diff --git a/briar-android/src/org/briarproject/android/panic/PanicPreferencesFragment.java b/briar-android/src/org/briarproject/android/panic/PanicPreferencesFragment.java
index 7fd096213c379dc4f1efeb28502a46d746092da0..3ee8915c25d976609029bbdc189ffa64eea406c3 100644
--- a/briar-android/src/org/briarproject/android/panic/PanicPreferencesFragment.java
+++ b/briar-android/src/org/briarproject/android/panic/PanicPreferencesFragment.java
@@ -1,14 +1,240 @@
 package org.briarproject.android.panic;
 
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
 import android.os.Bundle;
+import android.support.v7.app.AlertDialog;
+import android.support.v7.preference.CheckBoxPreference;
+import android.support.v7.preference.ListPreference;
+import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceFragmentCompat;
+import android.text.TextUtils;
 
 import org.briarproject.R;
 
-public class PanicPreferencesFragment extends PreferenceFragmentCompat {
+import java.util.ArrayList;
+import java.util.logging.Logger;
+
+import info.guardianproject.panic.Panic;
+import info.guardianproject.panic.PanicResponder;
+
+public class PanicPreferencesFragment extends PreferenceFragmentCompat
+		implements SharedPreferences.OnSharedPreferenceChangeListener {
+
+	private static final Logger LOG =
+			Logger.getLogger(PanicPreferencesFragment.class.getName());
+
+	private PackageManager pm;
+	private CheckBoxPreference lockPref;
+	private ListPreference panicAppPref;
+	private CheckBoxPreference purgePref;
 
 	@Override
 	public void onCreatePreferences(Bundle bundle, String s) {
 		addPreferencesFromResource(R.xml.panic_preferences);
+
+		pm = getActivity().getPackageManager();
+
+		lockPref = (CheckBoxPreference) findPreference("pref_key_lock");
+		panicAppPref = (ListPreference) findPreference("pref_key_panic_app");
+		purgePref = (CheckBoxPreference) findPreference("pref_key_purge");
+
+		// check for connect/disconnect intents from panic trigger apps
+		if (PanicResponder.checkForDisconnectIntent(getActivity())) {
+			LOG.info("Received DISCONNECT intent from Panic Trigger App.");
+			// the necessary action should have been performed by the check
+			getActivity().finish();
+		} else {
+			// check if we got a connect intent from a not yet connected app
+			String packageName =
+					PanicResponder.getConnectIntentSender(getActivity());
+			if (!TextUtils.isEmpty((packageName)) &&
+					!TextUtils.equals(packageName,
+							PanicResponder
+									.getTriggerPackageName(getActivity()))) {
+
+				// A new panic trigger app asks us to connect
+				LOG.info("Received CONNECT intent from new Panic Trigger App.");
+
+				// Show dialog allowing the user to opt-in
+				showOptInDialog();
+			}
+		}
+
+		ArrayList<CharSequence> entries = new ArrayList<CharSequence>();
+		ArrayList<CharSequence> entryValues = new ArrayList<CharSequence>();
+		entries.add(0, getString(R.string.panic_app_setting_none));
+		entryValues.add(0, Panic.PACKAGE_NAME_NONE);
+
+		for (ResolveInfo resolveInfo : PanicResponder.resolveTriggerApps(pm)) {
+			if (resolveInfo.activityInfo == null)
+				continue;
+			entries.add(resolveInfo.activityInfo.loadLabel(pm));
+			entryValues.add(resolveInfo.activityInfo.packageName);
+		}
+
+		panicAppPref.setEntries(
+				entries.toArray(new CharSequence[entries.size()]));
+		panicAppPref.setEntryValues(
+				entryValues.toArray(new CharSequence[entryValues.size()]));
+		panicAppPref.setDefaultValue(Panic.PACKAGE_NAME_NONE);
+
+		panicAppPref.setOnPreferenceChangeListener(
+				new Preference.OnPreferenceChangeListener() {
+					@Override
+					public boolean onPreferenceChange(Preference preference,
+							Object newValue) {
+						String packageName = (String) newValue;
+						PanicResponder.setTriggerPackageName(getActivity(),
+								packageName);
+						showPanicApp(packageName);
+
+						if (packageName.equals(Panic.PACKAGE_NAME_NONE)) {
+							purgePref.setChecked(false);
+							purgePref.setEnabled(false);
+							getActivity().setResult(Activity.RESULT_CANCELED);
+						} else {
+							purgePref.setEnabled(true);
+						}
+
+						return true;
+					}
+				});
+
+		if (entries.size() <= 1) {
+			panicAppPref.setOnPreferenceClickListener(
+					new Preference.OnPreferenceClickListener() {
+						@Override
+						public boolean onPreferenceClick(
+								Preference preference) {
+							Intent intent = new Intent(Intent.ACTION_VIEW);
+							intent.setData(Uri.parse(
+									"market://details?id=info.guardianproject.ripple"));
+							getActivity().startActivity(intent);
+							return true;
+						}
+					});
+		}
 	}
+
+	@Override
+	public void onResume() {
+		super.onResume();
+		getPreferenceScreen().getSharedPreferences()
+				.registerOnSharedPreferenceChangeListener(this);
+		showPanicApp(PanicResponder.getTriggerPackageName(getActivity()));
+	}
+
+	@Override
+	public void onPause() {
+		super.onPause();
+		getPreferenceScreen().getSharedPreferences()
+				.unregisterOnSharedPreferenceChangeListener(this);
+	}
+
+	@Override
+	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+			String key) {
+		// enable locking if purging gets enabled
+		if (key.equals("pref_key_purge")
+				&& sharedPreferences.getBoolean("pref_key_purge", false)) {
+			lockPref.setChecked(true);
+		}
+		// disable purging if locking gets disabled
+		if (key.equals("pref_key_lock")
+				&& !sharedPreferences.getBoolean("pref_key_lock",  true)
+				&&  sharedPreferences.getBoolean("pref_key_purge", false)) {
+			purgePref.setChecked(false);
+		}
+	}
+
+	private void showPanicApp(String triggerPackageName) {
+		if (TextUtils.isEmpty(triggerPackageName)
+				|| triggerPackageName.equals(Panic.PACKAGE_NAME_NONE)) {
+			// no panic app set
+			panicAppPref.setValue(Panic.PACKAGE_NAME_NONE);
+			panicAppPref
+					.setSummary(getString(R.string.panic_app_setting_summary));
+			panicAppPref.setIcon(
+					android.R.drawable.ic_menu_close_clear_cancel);
+			purgePref.setEnabled(false);
+		} else {
+			// display connected panic app
+			try {
+				panicAppPref.setValue(triggerPackageName);
+				panicAppPref.setSummary(pm.getApplicationLabel(
+						pm.getApplicationInfo(triggerPackageName, 0)));
+				panicAppPref.setIcon(
+						pm.getApplicationIcon(triggerPackageName));
+				purgePref.setEnabled(true);
+			} catch (PackageManager.NameNotFoundException e) {
+				// revert back to no app, just to be safe
+				PanicResponder.setTriggerPackageName(getActivity(),
+						Panic.PACKAGE_NAME_NONE);
+				showPanicApp(Panic.PACKAGE_NAME_NONE);
+			}
+		}
+	}
+
+	private void showOptInDialog() {
+		DialogInterface.OnClickListener okListener =
+				new DialogInterface.OnClickListener() {
+					@Override
+					public void onClick(DialogInterface dialog,
+							int which) {
+						PanicResponder.setTriggerPackageName(getActivity());
+						showPanicApp(PanicResponder
+								.getTriggerPackageName(getActivity()));
+						getActivity().setResult(Activity.RESULT_OK);
+					}
+				};
+		DialogInterface.OnClickListener cancelListener =
+				new DialogInterface.OnClickListener() {
+					@Override
+					public void onClick(DialogInterface dialog,
+							int which) {
+						getActivity().setResult(Activity.RESULT_CANCELED);
+						getActivity().finish();
+					}
+				};
+
+		AlertDialog.Builder builder =
+				new AlertDialog.Builder(getContext());
+		builder.setTitle(
+				getString(R.string.dialog_title_connect_panic_app));
+
+		CharSequence app = getString(R.string.unknown_app);
+		String packageName = getCallingPackageName();
+		if (packageName != null) {
+			try {
+				app = pm.getApplicationLabel(
+						pm.getApplicationInfo(packageName, 0));
+			} catch (PackageManager.NameNotFoundException e) {
+				LOG.warning(e.toString());
+			}
+		}
+
+		String text = String.format(
+				getString(R.string.dialog_message_connect_panic_app), app);
+		builder.setMessage(text);
+		builder.setPositiveButton(android.R.string.ok, okListener);
+		builder.setNegativeButton(android.R.string.cancel, cancelListener);
+		builder.show();
+	}
+
+	private String getCallingPackageName() {
+		ComponentName componentName = getActivity().getCallingActivity();
+		String packageName = null;
+		if (componentName != null) {
+			packageName = componentName.getPackageName();
+		}
+		return packageName;
+	}
+
 }
diff --git a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java
index df758e295e1065ce0bd3ae2566a1c13e04a6ccd5..1643767af005cd0d3332e7fb5898c02b93375e64 100644
--- a/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java
+++ b/briar-android/src/org/briarproject/android/panic/PanicResponderActivity.java
@@ -7,25 +7,78 @@ import android.os.Bundle;
 import android.support.v7.preference.PreferenceManager;
 
 import org.briarproject.android.BriarActivity;
+import org.briarproject.api.db.DatabaseConfig;
+import org.briarproject.util.FileUtils;
+import org.iilab.IilabEngineeringRSA2048Pin;
 
 import java.util.logging.Logger;
 
+import javax.inject.Inject;
+
+import info.guardianproject.GuardianProjectRSA4096;
+import info.guardianproject.panic.Panic;
+import info.guardianproject.panic.PanicResponder;
+import info.guardianproject.trustedintents.TrustedIntents;
+
 public class PanicResponderActivity extends BriarActivity {
 
 	private static final Logger LOG =
 			Logger.getLogger(PanicResponderActivity.class.getName());
+	@Inject private DatabaseConfig databaseConfig;
 
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 
-		SharedPreferences sharedPref = PreferenceManager
-				.getDefaultSharedPreferences(this);
+		TrustedIntents trustedIntents = TrustedIntents.get(this);
+		// Guardian Project Ripple
+		trustedIntents.addTrustedSigner(GuardianProjectRSA4096.class);
+		// Amnesty International's Panic Button, made by iilab.org
+		trustedIntents.addTrustedSigner(IilabEngineeringRSA2048Pin.class);
+
+		Intent intent = trustedIntents.getIntentFromTrustedSender(this);
+		if (intent != null) {
+			// received intent from trusted app
+			if (Panic.isTriggerIntent(intent)) {
+				SharedPreferences sharedPref = PreferenceManager
+						.getDefaultSharedPreferences(this);
+
+				LOG.info("Received Panic Trigger...");
+
+				if (PanicResponder.receivedTriggerFromConnectedApp(this)) {
+					LOG.info("Panic Trigger came from connected app.");
+					LOG.info("Performing destructive responses...");
+
+					// Performing destructive panic responses
+					if (sharedPref.getBoolean("pref_key_purge", false)) {
+						LOG.info("Purging all data...");
+						deleteAllData();
+					}
+					// still sign out if enabled
+					else if (sharedPref.getBoolean("pref_key_lock", true)) {
+						LOG.info("Signing out...");
+						signOut(true);
+					}
 
-		Intent intent = getIntent();
-		if (intent != null && sharedPref.getBoolean("pref_key_lock", true)) {
-			LOG.info("Signing out...");
-			signOut(true);
+					// TODO add other panic behavior such as:
+					// * send a pre-defined message to certain contacts (#212)
+					// * uninstall the app (#211)
+
+				}
+				// Performing non-destructive default panic response
+				else if (sharedPref.getBoolean("pref_key_lock", true)) {
+					LOG.info("Signing out...");
+					signOut(true);
+				}
+			}
+		}
+		// received intent from non-trusted app
+		else {
+			intent = getIntent();
+			if (intent != null && Panic.isTriggerIntent(intent)) {
+				LOG.info("Signing out...");
+				signOut(true);
+			}
 		}
 
 		if (Build.VERSION.SDK_INT >= 21) {
@@ -34,4 +87,23 @@ public class PanicResponderActivity extends BriarActivity {
 			finish();
 		}
 	}
+
+	private void deleteAllData() {
+		runOnDbThread(new Runnable() {
+			@Override
+			public void run() {
+				// TODO somehow delete/shred the database more thoroughly
+				FileUtils
+						.deleteFileOrDir(
+								databaseConfig.getDatabaseDirectory());
+				clearSharedPrefs();
+				PanicResponder.deleteAllAppData(PanicResponderActivity.this);
+
+				// nothing left to do after everything is deleted,
+				// so still sign out
+				LOG.info("Signing out...");
+				signOut(true);
+			}
+		});
+	}
 }
\ No newline at end of file