diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index 632d4b8f38f2bbb0170934df54cfd9168a1d76e9..00f0a325f816e349963bfceda01eca6ef6a766f4 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -58,7 +58,7 @@
 	<string name="groups_title">Groups</string>
 	<plurals name="groups_available">
 	    <item quantity="one">%1$d group available from contacts</item>
-	    <item quantity="two">$1$d groups available from contacts</item>
+	    <item quantity="other">$1$d groups available from contacts</item>
 	</plurals>
 	<string name="no_posts">No posts</string>
 	<string name="subscribe_to_this_group">Subscribe to this group</string>
@@ -71,7 +71,7 @@
 	<string name="blogs_title">Blogs</string>
 	<plurals name="blogs_available">
 	    <item quantity="one">%1$d blog available from contacts</item>
-	    <item quantity="two">$1$d blogs available from contacts</item>
+	    <item quantity="other">$1$d blogs available from contacts</item>
 	</plurals>
 	<string name="manage_subscriptions_title">Manage Subscriptions</string>
 	<string name="subscribed_all">Subscribed, shared with all contacts</string>
diff --git a/briar-android/src/net/sf/briar/android/blogs/ConfigureBlogActivity.java b/briar-android/src/net/sf/briar/android/blogs/ConfigureBlogActivity.java
index f004a77e3de4afda952ad2496cc77457f06af26e..5b67799e22fd011b0f56de7ffb954762d7487ad1 100644
--- a/briar-android/src/net/sf/briar/android/blogs/ConfigureBlogActivity.java
+++ b/briar-android/src/net/sf/briar/android/blogs/ConfigureBlogActivity.java
@@ -26,6 +26,7 @@ import net.sf.briar.api.ContactId;
 import net.sf.briar.api.android.DatabaseUiExecutor;
 import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
+import net.sf.briar.api.messaging.Group;
 import net.sf.briar.api.messaging.GroupId;
 import android.content.Intent;
 import android.os.Bundle;
@@ -60,7 +61,7 @@ SelectContactsDialog.Listener {
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
 	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	private volatile GroupId groupId = null;
+	private volatile Group group = null;
 	private volatile Collection<ContactId> selected = Collections.emptyList();
 
 	@Override
@@ -70,10 +71,13 @@ SelectContactsDialog.Listener {
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra("net.sf.briar.GROUP_ID");
 		if(b == null) throw new IllegalStateException();
-		groupId = new GroupId(b);
-		String groupName = i.getStringExtra("net.sf.briar.GROUP_NAME");
-		if(groupName == null) throw new IllegalArgumentException();
-		setTitle(groupName);
+		GroupId id = new GroupId(b);
+		String name = i.getStringExtra("net.sf.briar.GROUP_NAME");
+		if(name == null) throw new IllegalStateException();
+		setTitle(name);
+		byte[] publicKey = i.getByteArrayExtra("net.sf.briar.PUBLIC_KEY");
+		if(publicKey == null) throw new IllegalStateException();
+		group = new Group(id, name, publicKey);
 		wasSubscribed = i.getBooleanExtra("net.sf.briar.SUBSCRIBED", false);
 		boolean all = i.getBooleanExtra("net.sf.briar.VISIBLE_TO_ALL", false);
 
@@ -90,17 +94,18 @@ SelectContactsDialog.Listener {
 
 		radioGroup = new RadioGroup(this);
 		radioGroup.setOrientation(VERTICAL);
-		radioGroup.setEnabled(wasSubscribed);
 
 		visibleToAll = new RadioButton(this);
 		visibleToAll.setId(1);
 		visibleToAll.setText(R.string.blog_visible_to_all);
+		visibleToAll.setEnabled(wasSubscribed);
 		visibleToAll.setOnClickListener(this);
 		radioGroup.addView(visibleToAll);
 
 		visibleToSome = new RadioButton(this);
 		visibleToSome.setId(2);
 		visibleToSome.setText(R.string.blog_visible_to_some);
+		visibleToSome.setEnabled(wasSubscribed);
 		visibleToSome.setOnClickListener(this);
 		radioGroup.addView(visibleToSome);
 
@@ -135,7 +140,9 @@ SelectContactsDialog.Listener {
 
 	public void onClick(View view) {
 		if(view == subscribeCheckBox) {
-			radioGroup.setEnabled(subscribeCheckBox.isChecked());
+			boolean subscribe = subscribeCheckBox.isChecked();
+			visibleToAll.setEnabled(subscribe);
+			visibleToSome.setEnabled(subscribe);
 		} else if(view == visibleToSome) {
 			loadContacts();
 		} else if(view == doneButton) {
@@ -203,11 +210,11 @@ SelectContactsDialog.Listener {
 					serviceConnection.waitForStartup();
 					long now = System.currentTimeMillis();
 					if(subscribe) {
-						if(!wasSubscribed) db.subscribe(db.getGroup(groupId));
-						db.setVisibleToAll(groupId, all);
-						if(!all) db.setVisibility(groupId, visible);
+						if(!wasSubscribed) db.subscribe(group);
+						db.setVisibleToAll(group.getId(), all);
+						if(!all) db.setVisibility(group.getId(), visible);
 					} else if(wasSubscribed) {
-						db.unsubscribe(db.getGroup(groupId));
+						db.unsubscribe(group);
 					}
 					long duration = System.currentTimeMillis() - now;
 					if(LOG.isLoggable(INFO))
diff --git a/briar-android/src/net/sf/briar/android/blogs/ManageBlogsActivity.java b/briar-android/src/net/sf/briar/android/blogs/ManageBlogsActivity.java
index f18ba0ee314c8d05a054f9db4914890f32f502dc..e464217cabf0580cb7728b355cc2d2ab3f288904 100644
--- a/briar-android/src/net/sf/briar/android/blogs/ManageBlogsActivity.java
+++ b/briar-android/src/net/sf/briar/android/blogs/ManageBlogsActivity.java
@@ -14,8 +14,8 @@ import java.util.logging.Logger;
 
 import net.sf.briar.android.BriarFragmentActivity;
 import net.sf.briar.android.BriarService;
-import net.sf.briar.android.ManageGroupsAdapter;
 import net.sf.briar.android.BriarService.BriarServiceConnection;
+import net.sf.briar.android.ManageGroupsAdapter;
 import net.sf.briar.api.android.DatabaseUiExecutor;
 import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
@@ -147,9 +147,11 @@ implements DatabaseListener, OnItemClickListener {
 	public void onItemClick(AdapterView<?> parent, View view, int position,
 			long id) {
 		GroupStatus item = adapter.getItem(position);
+		Group g = item.getGroup();
 		Intent i = new Intent(this, ConfigureBlogActivity.class);
-		i.putExtra("net.sf.briar.GROUP_ID", item.getGroup().getId().getBytes());
-		i.putExtra("net.sf.briar.GROUP_NAME", item.getGroup().getName());
+		i.putExtra("net.sf.briar.GROUP_ID", g.getId().getBytes());
+		i.putExtra("net.sf.briar.GROUP_NAME", g.getName());
+		i.putExtra("net.sf.briar.PUBLIC_KEY", g.getPublicKey());
 		i.putExtra("net.sf.briar.SUBSCRIBED", item.isSubscribed());
 		i.putExtra("net.sf.briar.VISIBLE_TO_ALL", item.isVisibleToAll());
 		startActivity(i);
diff --git a/briar-android/src/net/sf/briar/android/groups/ConfigureGroupActivity.java b/briar-android/src/net/sf/briar/android/groups/ConfigureGroupActivity.java
index 1fca60001339f83c8e94550cc9ce358ff8e052b3..7102b1c5fc4904af632137df247b2ea11197a6cd 100644
--- a/briar-android/src/net/sf/briar/android/groups/ConfigureGroupActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/ConfigureGroupActivity.java
@@ -26,6 +26,7 @@ import net.sf.briar.api.ContactId;
 import net.sf.briar.api.android.DatabaseUiExecutor;
 import net.sf.briar.api.db.DatabaseComponent;
 import net.sf.briar.api.db.DbException;
+import net.sf.briar.api.messaging.Group;
 import net.sf.briar.api.messaging.GroupId;
 import android.content.Intent;
 import android.os.Bundle;
@@ -60,7 +61,7 @@ SelectContactsDialog.Listener {
 	// Fields that are accessed from background threads must be volatile
 	@Inject private volatile DatabaseComponent db;
 	@Inject @DatabaseUiExecutor private volatile Executor dbUiExecutor;
-	private volatile GroupId groupId = null;
+	private volatile Group group = null;
 	private volatile Collection<ContactId> selected = Collections.emptyList();
 
 	@Override
@@ -70,10 +71,11 @@ SelectContactsDialog.Listener {
 		Intent i = getIntent();
 		byte[] b = i.getByteArrayExtra("net.sf.briar.GROUP_ID");
 		if(b == null) throw new IllegalStateException();
-		groupId = new GroupId(b);
-		String groupName = i.getStringExtra("net.sf.briar.GROUP_NAME");
-		if(groupName == null) throw new IllegalArgumentException();
-		setTitle(groupName);
+		GroupId id = new GroupId(b);
+		String name = i.getStringExtra("net.sf.briar.GROUP_NAME");
+		if(name == null) throw new IllegalStateException();
+		setTitle(name);
+		group = new Group(id, name, null);
 		wasSubscribed = i.getBooleanExtra("net.sf.briar.SUBSCRIBED", false);
 		boolean all = i.getBooleanExtra("net.sf.briar.VISIBLE_TO_ALL", false);
 
@@ -90,17 +92,18 @@ SelectContactsDialog.Listener {
 
 		radioGroup = new RadioGroup(this);
 		radioGroup.setOrientation(VERTICAL);
-		radioGroup.setEnabled(wasSubscribed);
 
 		visibleToAll = new RadioButton(this);
 		visibleToAll.setId(1);
 		visibleToAll.setText(R.string.group_visible_to_all);
+		visibleToAll.setEnabled(wasSubscribed);
 		visibleToAll.setOnClickListener(this);
 		radioGroup.addView(visibleToAll);
 
 		visibleToSome = new RadioButton(this);
 		visibleToSome.setId(2);
 		visibleToSome.setText(R.string.group_visible_to_some);
+		visibleToSome.setEnabled(wasSubscribed);
 		visibleToSome.setOnClickListener(this);
 		radioGroup.addView(visibleToSome);
 
@@ -135,7 +138,9 @@ SelectContactsDialog.Listener {
 
 	public void onClick(View view) {
 		if(view == subscribeCheckBox) {
-			radioGroup.setEnabled(subscribeCheckBox.isChecked());
+			boolean subscribe = subscribeCheckBox.isChecked();
+			visibleToAll.setEnabled(subscribe);
+			visibleToSome.setEnabled(subscribe);
 		} else if(view == visibleToSome) {
 			loadContacts();
 		} else if(view == doneButton) {
@@ -203,11 +208,11 @@ SelectContactsDialog.Listener {
 					serviceConnection.waitForStartup();
 					long now = System.currentTimeMillis();
 					if(subscribe) {
-						if(!wasSubscribed) db.subscribe(db.getGroup(groupId));
-						db.setVisibleToAll(groupId, all);
-						if(!all) db.setVisibility(groupId, visible);
+						if(!wasSubscribed) db.subscribe(group);
+						db.setVisibleToAll(group.getId(), all);
+						if(!all) db.setVisibility(group.getId(), visible);
 					} else if(wasSubscribed) {
-						db.unsubscribe(db.getGroup(groupId));
+						db.unsubscribe(group);
 					}
 					long duration = System.currentTimeMillis() - now;
 					if(LOG.isLoggable(INFO))
diff --git a/briar-android/src/net/sf/briar/android/groups/ManageGroupsActivity.java b/briar-android/src/net/sf/briar/android/groups/ManageGroupsActivity.java
index ced4d15da86af602cd3e326dbf1d1f4a49db906c..421086dbb32faf9e4eca00468420bca80ef0e7d9 100644
--- a/briar-android/src/net/sf/briar/android/groups/ManageGroupsActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/ManageGroupsActivity.java
@@ -147,9 +147,10 @@ implements DatabaseListener, OnItemClickListener {
 	public void onItemClick(AdapterView<?> parent, View view, int position,
 			long id) {
 		GroupStatus item = adapter.getItem(position);
+		Group g = item.getGroup();
 		Intent i = new Intent(this, ConfigureGroupActivity.class);
-		i.putExtra("net.sf.briar.GROUP_ID", item.getGroup().getId().getBytes());
-		i.putExtra("net.sf.briar.GROUP_NAME", item.getGroup().getName());
+		i.putExtra("net.sf.briar.GROUP_ID", g.getId().getBytes());
+		i.putExtra("net.sf.briar.GROUP_NAME", g.getName());
 		i.putExtra("net.sf.briar.SUBSCRIBED", item.isSubscribed());
 		i.putExtra("net.sf.briar.VISIBLE_TO_ALL", item.isVisibleToAll());
 		startActivity(i);