diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
index 4b79ce4389c2e29951ba8b05f10b055fcab7c2f7..0e1678edbe89c3eef6ace473e53846628cff41bc 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java
@@ -331,11 +331,21 @@ public class ConversationActivity extends BriarActivity
 				finishOnUiThread();
 			}
 		} else if (e instanceof MessageAddedEvent) {
-			GroupId g = ((MessageAddedEvent) e).getGroupId();
+			MessageAddedEvent mEvent = (MessageAddedEvent) e;
+			GroupId g = mEvent.getGroupId();
 			if (g.equals(groupId)) {
+				// mark new incoming messages as read directly
+				if (mEvent.getContactId() != null) {
+					ConversationItem item = adapter.getLastItem();
+					if (item != null) {
+						markIncomingMessageRead(mEvent.getMessage(),
+								item.getHeader().getTimestamp());
+					}
+				}
+
 				LOG.info("Message added, reloading");
-				// TODO: find a way of not needing to reload the entire
-				// conversation just because one message was added
+				// TODO: get and add the ConversationItem here to prevent
+				//       reloading the entire conversation
 				loadHeaders();
 			}
 		} else if (e instanceof MessagesSentEvent) {
@@ -384,7 +394,41 @@ public class ConversationActivity extends BriarActivity
 		});
 	}
 
+	private void markIncomingMessageRead(final Message m,
+			final long lastMsgTime) {
+
+		// stop here if message is older than latest message we have
+		long newMsgTime = m.getTimestamp();
+		if (newMsgTime < lastMsgTime) return;
+
+		runOnDbThread(new Runnable() {
+			public void run() {
+				try {
+					// mark messages as read, because is latest
+					messagingManager.setReadFlag(m.getId(), true);
+					showIncomingMessageRead();
+				} catch (DbException e) {
+					if (LOG.isLoggable(WARNING))
+						LOG.log(WARNING, e.toString(), e);
+				}
+			}
+			// TODO else: smooth-scroll up to unread messages if out of view
+		});
+	}
+
+	private void showIncomingMessageRead() {
+		runOnUiThread(new Runnable() {
+			public void run() {
+				// this is only called from markIncomingMessageRead()
+				// so we can assume that it was the last message that changed
+				adapter.notifyItemChanged(adapter.getItemCount() - 1);
+			}
+		});
+	}
+
 	public void onClick(View view) {
+		markMessagesRead();
+
 		String message = content.getText().toString();
 		if (message.equals("")) return;
 		long timestamp = System.currentTimeMillis();
@@ -397,10 +441,9 @@ public class ConversationActivity extends BriarActivity
 	private long getMinTimestampForNewMessage() {
 		// Don't use an earlier timestamp than the newest message
 		long timestamp = 0;
-		int count = adapter.getItemCount();
-		for (int i = 0; i < count; i++) {
-			long t = adapter.getItem(i).getHeader().getTimestamp();
-			if (t > timestamp) timestamp = t;
+		ConversationItem item = adapter.getLastItem();
+		if (item != null) {
+			timestamp = item.getHeader().getTimestamp();
 		}
 		return timestamp + 1;
 	}
diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java
index 0e183a63b571f706e403cf2b81d6ae9cc9c9f158..6b0c1aac62fd50392a13840f824b10edc6ccb768 100644
--- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java
+++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java
@@ -159,6 +159,14 @@ class ConversationAdapter extends
 		return messages.get(position);
 	}
 
+	public ConversationItem getLastItem() {
+		if (messages.size() > 0) {
+			return messages.get(messages.size() - 1);
+		} else {
+			return null;
+		}
+	}
+
 	public void add(final ConversationItem message) {
 		this.messages.add(message);
 	}
diff --git a/briar-api/src/org/briarproject/api/event/MessageAddedEvent.java b/briar-api/src/org/briarproject/api/event/MessageAddedEvent.java
index a557d008570563ba25d8ea228ce107e391eb12d0..5e08c9b20b9f7930383ee829aeca306015405524 100644
--- a/briar-api/src/org/briarproject/api/event/MessageAddedEvent.java
+++ b/briar-api/src/org/briarproject/api/event/MessageAddedEvent.java
@@ -2,21 +2,27 @@ package org.briarproject.api.event;
 
 import org.briarproject.api.contact.ContactId;
 import org.briarproject.api.sync.GroupId;
+import org.briarproject.api.sync.Message;
 
 /** An event that is broadcast when a message is added to the database. */
 public class MessageAddedEvent extends Event {
 
-	private final GroupId groupId;
+	private final Message message;
 	private final ContactId contactId;
 
-	public MessageAddedEvent(GroupId groupId, ContactId contactId) {
-		this.groupId = groupId;
+	public MessageAddedEvent(Message message, ContactId contactId) {
+		this.message = message;
 		this.contactId = contactId;
 	}
 
+	/** Returns the message that was added. */
+	public Message getMessage() {
+		return message;
+	}
+
 	/** Returns the ID of the group to which the message belongs. */
 	public GroupId getGroupId() {
-		return groupId;
+		return message.getGroup().getId();
 	}
 
 	/**
diff --git a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
index 2447b3844c43e80db1e592724a312e90852aae66..795fb41365d64f92b11fbdd2173e050ee5a51565 100644
--- a/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
+++ b/briar-core/src/org/briarproject/db/DatabaseComponentImpl.java
@@ -223,8 +223,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 			lock.writeLock().unlock();
 		}
 		if (!duplicate && subscribed) {
-			GroupId g = m.getGroup().getId();
-			eventBus.broadcast(new MessageAddedEvent(g, null));
+			eventBus.broadcast(new MessageAddedEvent(m, null));
 		}
 	}
 
@@ -1053,8 +1052,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
 		}
 		if (visible) {
 			if (!duplicate) {
-				GroupId g = m.getGroup().getId();
-				eventBus.broadcast(new MessageAddedEvent(g, c));
+				eventBus.broadcast(new MessageAddedEvent(m, c));
 			}
 			eventBus.broadcast(new MessageToAckEvent(c));
 		}