diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index 93f292b471626885d06bcd5c13cd32333789e72f..c7aa5a7d6ed19fa2b7cce7760dc612c59bce87a7 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -53,4 +53,9 @@
 	<string name="create_identity_title">Create an Identity</string>
 	<string name="choose_nickname">Choose your nickname:</string>
 	<string name="create_button">Create</string>
+	<string name="no_contacts">You don\'t have any contacts. Add a contact now?</string>
+	<string name="add_contact_button">Add a contact</string>
+	<string name="cancel_button">Cancel</string>
+	<string name="no_groups">You aren\'t subscribed to any groups. Create a group now?</string>
+	<string name="create_group_button">Create a group</string>
 </resources>
diff --git a/briar-android/src/net/sf/briar/android/BriarFragmentActivity.java b/briar-android/src/net/sf/briar/android/BriarFragmentActivity.java
new file mode 100644
index 0000000000000000000000000000000000000000..44809a3bf2343da4d1ebf65423e132b9daff8248
--- /dev/null
+++ b/briar-android/src/net/sf/briar/android/BriarFragmentActivity.java
@@ -0,0 +1,36 @@
+package net.sf.briar.android;
+
+import roboguice.activity.RoboFragmentActivity;
+import android.os.Bundle;
+
+/**
+ * An abstract superclass for activities that overrides the default behaviour
+ * to prevent sensitive state from being saved unless the subclass explicitly
+ * saves it.
+ */
+public class BriarFragmentActivity extends RoboFragmentActivity {
+
+	@Override
+	public void onCreate(Bundle state) {
+		// Don't pass state through to the superclass
+		super.onCreate(null);
+	}
+
+	@Override
+	public void onRestoreInstanceState(Bundle state) {
+		// Don't pass state through to the superclass
+	}
+
+	@Override
+	public void onSaveInstanceState(Bundle state) {
+		// Don't allow the superclass to save state
+	}
+
+	protected void finishOnUiThread() {
+		runOnUiThread(new Runnable() {
+			public void run() {
+				finish();
+			}
+		});
+	}
+}
diff --git a/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java b/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java
index 0d7b970145d5fe1a3b5a083ff51befea3e203c3d..f13fce4f69fddc6279479d109aaa4a8b1ef22544 100644
--- a/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java
@@ -18,7 +18,7 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarActivity;
+import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
 import net.sf.briar.android.widgets.HorizontalBorder;
@@ -45,8 +45,8 @@ import android.widget.ListView;
 
 import com.google.inject.Inject;
 
-public class GroupListActivity extends BriarActivity
-implements OnClickListener, DatabaseListener {
+public class GroupListActivity extends BriarFragmentActivity
+implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener {
 
 	private static final Logger LOG =
 			Logger.getLogger(GroupListActivity.class.getName());
@@ -62,6 +62,7 @@ implements OnClickListener, DatabaseListener {
 	@Inject private volatile DatabaseComponent db;
 	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
 	private volatile boolean restricted = false;
+	private volatile boolean noGroups = true;
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -135,6 +136,7 @@ implements OnClickListener, DatabaseListener {
 					for(Group g : db.getSubscriptions()) {
 						// Filter out restricted/unrestricted groups
 						if(g.isRestricted() != restricted) continue;
+						noGroups = false;
 						try {
 							// Load the headers from the database
 							Collection<GroupMessageHeader> headers =
@@ -217,9 +219,15 @@ implements OnClickListener, DatabaseListener {
 		if(view == newGroupButton) {
 			// FIXME: Hook this button up to an activity
 		} else if(view == composeButton) {
-			Intent i = new Intent(this, WriteGroupMessageActivity.class);
-			i.putExtra("net.sf.briar.RESTRICTED", restricted);
-			startActivity(i);
+			if(noGroups) {
+				NoGroupsDialog dialog = new NoGroupsDialog();
+				dialog.setListener(this);
+				dialog.show(getSupportFragmentManager(), "NoGroupsDialog");
+			} else {
+				Intent i = new Intent(this, WriteGroupMessageActivity.class);
+				i.putExtra("net.sf.briar.RESTRICTED", restricted);
+				startActivity(i);
+			}
 		}
 	}
 
@@ -282,6 +290,14 @@ implements OnClickListener, DatabaseListener {
 		});
 	}
 
+	public void createGroupButtonClicked() {
+		// FIXME: Hook this button up to an activity
+	}
+
+	public void cancelButtonClicked() {
+		// That's nice dear
+	}
+
 	private static class GroupComparator implements Comparator<GroupListItem> {
 
 		private static final GroupComparator INSTANCE = new GroupComparator();
diff --git a/briar-android/src/net/sf/briar/android/groups/NoGroupsDialog.java b/briar-android/src/net/sf/briar/android/groups/NoGroupsDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..59cd5c270c22a48d2869d35c2b3b3d907b06d425
--- /dev/null
+++ b/briar-android/src/net/sf/briar/android/groups/NoGroupsDialog.java
@@ -0,0 +1,43 @@
+package net.sf.briar.android.groups;
+
+import net.sf.briar.R;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+
+public class NoGroupsDialog extends DialogFragment {
+
+	private Listener listener = null;
+
+	void setListener(Listener listener) {
+		this.listener = listener;
+	}
+
+	@Override
+	public Dialog onCreateDialog(Bundle state) {
+		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+		builder.setMessage(R.string.no_groups);
+		builder.setPositiveButton(R.string.create_group_button,
+				new DialogInterface.OnClickListener() {
+			public void onClick(DialogInterface dialog, int id) {
+				listener.createGroupButtonClicked();
+			}
+		});
+		builder.setNegativeButton(R.string.cancel_button,
+				new DialogInterface.OnClickListener() {
+			public void onClick(DialogInterface dialog, int id) {
+				listener.cancelButtonClicked();
+			}
+		});
+		return builder.create();
+	}
+
+	interface Listener {
+
+		void createGroupButtonClicked();
+
+		void cancelButtonClicked();
+	}
+}
diff --git a/briar-android/src/net/sf/briar/android/groups/WriteGroupMessageActivity.java b/briar-android/src/net/sf/briar/android/groups/WriteGroupMessageActivity.java
index e887fc6561a2b142c649fb9b96014cc19ccd22e6..976bbb84b77b9d6c1ed14416cb1b4ca3782ae6c7 100644
--- a/briar-android/src/net/sf/briar/android/groups/WriteGroupMessageActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/WriteGroupMessageActivity.java
@@ -213,6 +213,7 @@ implements OnItemSelectedListener, OnClickListener {
 	private void displayGroups(final Collection<Group> groups) {
 		runOnUiThread(new Runnable() {
 			public void run() {
+				if(groups.isEmpty()) finish();
 				int index = -1;
 				for(Group g : groups) {
 					if(g.getId().equals(groupId)) {
diff --git a/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java b/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java
index 8fdc82aa3388d23eabafc01d10d1dbc03cbc24d6..950afba1c8e9755869893f363733d4492229c40d 100644
--- a/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java
+++ b/briar-android/src/net/sf/briar/android/messages/ConversationListActivity.java
@@ -15,9 +15,10 @@ import java.util.concurrent.Executor;
 import java.util.logging.Logger;
 
 import net.sf.briar.R;
-import net.sf.briar.android.BriarActivity;
+import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
+import net.sf.briar.android.invitation.AddContactActivity;
 import net.sf.briar.android.widgets.HorizontalBorder;
 import net.sf.briar.api.Contact;
 import net.sf.briar.api.ContactId;
@@ -41,8 +42,8 @@ import android.widget.ListView;
 
 import com.google.inject.Inject;
 
-public class ConversationListActivity extends BriarActivity
-implements OnClickListener, DatabaseListener {
+public class ConversationListActivity extends BriarFragmentActivity
+implements OnClickListener, DatabaseListener, NoContactsDialog.Listener {
 
 	private static final Logger LOG =
 			Logger.getLogger(ConversationListActivity.class.getName());
@@ -56,6 +57,7 @@ implements OnClickListener, DatabaseListener {
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
 	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
+	private volatile boolean noContacts = true;
 
 	@Override
 	public void onCreate(Bundle state) {
@@ -103,7 +105,9 @@ implements OnClickListener, DatabaseListener {
 					serviceConnection.waitForStartup();
 					// Load the contact list from the database
 					long now = System.currentTimeMillis();
-					for(Contact c : db.getContacts()) {
+					Collection<Contact> contacts = db.getContacts();
+					noContacts = contacts.isEmpty();
+					for(Contact c : contacts) {
 						try {
 							// Load the headers from the database
 							Collection<PrivateMessageHeader> headers =
@@ -183,7 +187,13 @@ implements OnClickListener, DatabaseListener {
 	}
 
 	public void onClick(View view) {
-		startActivity(new Intent(this, WritePrivateMessageActivity.class));
+		if(noContacts) {
+			NoContactsDialog dialog = new NoContactsDialog();
+			dialog.setListener(this);
+			dialog.show(getSupportFragmentManager(), "NoContactsDialog");
+		} else {
+			startActivity(new Intent(this, WritePrivateMessageActivity.class));
+		}
 	}
 
 	public void eventOccurred(DatabaseEvent e) {
@@ -240,6 +250,14 @@ implements OnClickListener, DatabaseListener {
 		});
 	}
 
+	public void addContactButtonClicked() {
+		startActivity(new Intent(this, AddContactActivity.class));
+	}
+
+	public void cancelButtonClicked() {
+		// That's nice dear
+	}
+
 	private static class ConversationComparator
 	implements Comparator<ConversationListItem> {
 
diff --git a/briar-android/src/net/sf/briar/android/messages/NoContactsDialog.java b/briar-android/src/net/sf/briar/android/messages/NoContactsDialog.java
new file mode 100644
index 0000000000000000000000000000000000000000..d04aa9e84fcf956291dcfc5fb244ea94d8442b3c
--- /dev/null
+++ b/briar-android/src/net/sf/briar/android/messages/NoContactsDialog.java
@@ -0,0 +1,43 @@
+package net.sf.briar.android.messages;
+
+import net.sf.briar.R;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.support.v4.app.DialogFragment;
+
+public class NoContactsDialog extends DialogFragment {
+
+	private Listener listener = null;
+
+	void setListener(Listener listener) {
+		this.listener = listener;
+	}
+
+	@Override
+	public Dialog onCreateDialog(Bundle state) {
+		AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+		builder.setMessage(R.string.no_contacts);
+		builder.setPositiveButton(R.string.add_contact_button,
+				new DialogInterface.OnClickListener() {
+			public void onClick(DialogInterface dialog, int id) {
+				listener.addContactButtonClicked();
+			}
+		});
+		builder.setNegativeButton(R.string.cancel_button,
+				new DialogInterface.OnClickListener() {
+			public void onClick(DialogInterface dialog, int id) {
+				listener.cancelButtonClicked();
+			}
+		});
+		return builder.create();
+	}
+
+	interface Listener {
+
+		void addContactButtonClicked();
+
+		void cancelButtonClicked();
+	}
+}
diff --git a/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java b/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java
index c6480e0ac4231c0b13c81ebba45c518985178cd3..f3d714e07078217c7e058c3be2117c87115a7263 100644
--- a/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java
+++ b/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java
@@ -164,6 +164,7 @@ implements OnItemSelectedListener, OnClickListener {
 	private void displayContacts(final Collection<Contact> contacts) {
 		runOnUiThread(new Runnable() {
 			public void run() {
+				if(contacts.isEmpty()) finish();
 				int index = -1;
 				for(Contact c : contacts) {
 					if(c.getId().equals(contactId)) index = adapter.getCount();