save in messages provider message incoming/outgoing.
authorVincent V.<marseille@beem-project.com>
Sun, 06 Nov 2011 00:15:35 +0100
changeset 916 d697250668af
parent 915 3039eca6adab
child 917 f7cfc4a68225
save in messages provider message incoming/outgoing. update ui chat.java
default.properties
src/com/beem/project/beem/service/BeemChatManager.java
src/com/beem/project/beem/service/XmppConnectionAdapter.java
src/com/beem/project/beem/ui/Chat.java
src/com/beem/project/beem/ui/ContactList.java
--- a/default.properties	Thu Nov 03 14:45:56 2011 +0100
+++ b/default.properties	Sun Nov 06 00:15:35 2011 +0100
@@ -1,2 +1,2 @@
 # Project target.
-target=android-14
+target=android-7
--- a/src/com/beem/project/beem/service/BeemChatManager.java	Thu Nov 03 14:45:56 2011 +0100
+++ b/src/com/beem/project/beem/service/BeemChatManager.java	Sun Nov 06 00:15:35 2011 +0100
@@ -81,263 +81,248 @@
  */
 public class BeemChatManager extends IChatManager.Stub {
 
-	private static final String TAG = "BeemChatManager";
-	private final ChatManager mAdaptee;
-	private final Map<String, ChatAdapter> mChats = new HashMap<String, ChatAdapter>();
-	private final ChatListener mChatListener = new ChatListener();
-	private final RemoteCallbackList<IChatManagerListener> mRemoteChatCreationListeners = new RemoteCallbackList<IChatManagerListener>();
-	private final BeemService mService;
+    private static final String TAG = "BeemChatManager";
+    private final ChatManager mAdaptee;
+    private final Map<String, ChatAdapter> mChats = new HashMap<String, ChatAdapter>();
+    private final ChatListener mChatListener = new ChatListener();
+    private final RemoteCallbackList<IChatManagerListener> mRemoteChatCreationListeners = new RemoteCallbackList<IChatManagerListener>();
+    private final BeemService mService;
+
+    /**
+     * Constructor.
+     * @param chatManager the smack ChatManager to adapt
+     * @param service the service which runs the chat manager
+     */
+    public BeemChatManager(final ChatManager chatManager, final BeemService service) {
+	mService = service;
+	mAdaptee = chatManager;
+	//mAdaptee.addChatListener(mChatListener);
+    }
+
+    @Override
+    public void addChatCreationListener(IChatManagerListener listener) throws RemoteException {
+	if (listener != null)
+	    mRemoteChatCreationListeners.register(listener);
+    }
+
+    /**
+     * Create a chat session.
+     * @param contact the contact you want to chat with
+     * @param listener listener to use for chat events on this chat session
+     * @return the chat session
+     */
+    @Override
+    public IChat createChat(Contact contact, IMessageListener listener) {
+	String jid = contact.getJIDWithRes();
+	Log.d(TAG, "Get chat key1 = ");
+
+	return createChat(jid, listener);
+    }
+
+    /**
+     * Create a chat session.
+     * @param jid the jid of the contact you want to chat with
+     * @param listener listener to use for chat events on this chat session
+     * @return the chat session
+     */
+    public IChat createChat(String jid, IMessageListener listener) {
+	String key = jid;
+	ChatAdapter result;
+	Log.d(TAG, "Get chat key2 = ");
+	if (mChats.containsKey(key)) {
+	    result = mChats.get(key);
+	    result.addMessageListener(listener);
+	    return result;
+	}
+	Chat c = mAdaptee.createChat(key, null);
+	// maybe a little probleme of thread synchronization
+	// if so use an HashTable instead of a HashMap for mChats
+	result = getChat(c);
+	result.addMessageListener(listener);
+	return result;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void destroyChat(IChat chat) throws RemoteException {
+	// Can't remove it. otherwise we will lose all futur message in this chat
+	// chat.removeMessageListener(mChatListener);
+	if (chat == null)
+	    return;
+	deleteChatNotification(chat);
+	mChats.remove(chat.getParticipant().getJID());
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void deleteChatNotification(IChat chat) {
+	//		try {
+	//			//TODO: BeemNotification.BindNotification(BeemChatManager.this).deleteNotification(chat.getParticipant().getJID().hashCode());
+	//		} catch (RemoteException e) {
+	//			Log.v(TAG, "Remote exception ", e);
+	//		}
+    }
+
+    /**
+     * Get an existing ChatAdapter or create it if necessary.
+     * @param chat The real instance of smack chat
+     * @return a chat adapter register in the manager
+     */
+    private ChatAdapter getChat(Chat chat) {
+	String key = chat.getParticipant();
+	if (mChats.containsKey(key)) {
+	    return mChats.get(key);
+	}
+	ChatAdapter res = new ChatAdapter(chat);
+	boolean history = PreferenceManager.getDefaultSharedPreferences(mService.getBaseContext()).getBoolean(
+	    "settings_key_history", false);
+	String accountUser = PreferenceManager.getDefaultSharedPreferences(mService.getBaseContext()).getString(
+	    BeemApplication.ACCOUNT_USERNAME_KEY, "");
+	String historyPath = PreferenceManager.getDefaultSharedPreferences(mService.getBaseContext()).getString(
+	    BeemApplication.CHAT_HISTORY_KEY, "");
+	if ("".equals(historyPath))
+	    historyPath = "/Android/data/com.beem.project.beem/chat/";
+	res.setHistory(history);
+	res.setAccountUser(accountUser);
+	res.setHistoryPath(new File(Environment.getExternalStorageDirectory(), historyPath));
+	Log.d(TAG, "getChat put " + key);
+	mChats.put(key, res);
+	return res;
+    }
+
+    @Override
+    public ChatAdapter getChat(Contact contact) {
+	String key = contact.getJIDWithRes();
+	return mChats.get(key);
+    }
+
+    /**
+     * This methods permits to retrieve the list of contacts who have an opened chat session with us.
+     * @return An List containing Contact instances.
+     * @throws RemoteException If a Binder remote-invocation error occurred.
+     */
+    public List<Contact> getOpenedChatList() throws RemoteException {
+	List<Contact> openedChats = new ArrayList<Contact>();
+	IRoster mRoster = mService.getBind().getRoster();
+
+	for (ChatAdapter chat : mChats.values()) {
+	    if (chat.getMessages().size() > 0) {
+		Contact t = mRoster.getContact(chat.getParticipant().getJID());
+		if (t == null)
+		    t = new Contact(chat.getParticipant().getJID());
+		openedChats.add(t);
+	    }
+	}
+	return openedChats;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void removeChatCreationListener(IChatManagerListener listener) throws RemoteException {
+	if (listener != null)
+	    mRemoteChatCreationListeners.unregister(listener);
+    }
+
+    /**
+     * A listener for all the chat creation event that happens on the connection.
+     * @author darisk
+     */
+    private class ChatListener extends IMessageListener.Stub implements ChatManagerListener {
 
 	/**
 	 * Constructor.
-	 * @param chatManager the smack ChatManager to adapt
-	 * @param service the service which runs the chat manager
 	 */
-	public BeemChatManager(final ChatManager chatManager, final BeemService service) {
-		mService = service;
-		mAdaptee = chatManager;
-		mAdaptee.addChatListener(mChatListener);		
-	}
-
-	@Override
-	public void addChatCreationListener(IChatManagerListener listener) throws RemoteException {
-		if (listener != null)
-			mRemoteChatCreationListeners.register(listener);
-	}
-
-	/**
-	 * Create a chat session.
-	 * @param contact the contact you want to chat with
-	 * @param listener listener to use for chat events on this chat session
-	 * @return the chat session
-	 */
-	@Override
-	public IChat createChat(Contact contact, IMessageListener listener) {
-		String jid = contact.getJIDWithRes();
-		Log.d(TAG, "Get chat key1 = ");
-
-		return createChat(jid, listener);
-	}
-
-	/**
-	 * Create a chat session.
-	 * @param jid the jid of the contact you want to chat with
-	 * @param listener listener to use for chat events on this chat session
-	 * @return the chat session
-	 */
-	public IChat createChat(String jid, IMessageListener listener) {
-		String key = jid;
-		ChatAdapter result;
-		Log.d(TAG, "Get chat key2 = ");
-		if (mChats.containsKey(key)) {
-			result = mChats.get(key);
-			result.addMessageListener(listener);
-			return result;
-		}
-		Chat c = mAdaptee.createChat(key, null);
-		// maybe a little probleme of thread synchronization
-		// if so use an HashTable instead of a HashMap for mChats
-		result = getChat(c);
-		result.addMessageListener(listener);
-		return result;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void destroyChat(IChat chat) throws RemoteException {
-		// Can't remove it. otherwise we will lose all futur message in this chat
-		// chat.removeMessageListener(mChatListener);
-		if (chat == null)
-			return;
-		deleteChatNotification(chat);
-		mChats.remove(chat.getParticipant().getJID());
+	public ChatListener() {
 	}
 
 	/**
 	 * {@inheritDoc}
 	 */
 	@Override
-	public void deleteChatNotification(IChat chat) {
-//		try {
-//			//TODO: BeemNotification.BindNotification(BeemChatManager.this).deleteNotification(chat.getParticipant().getJID().hashCode());
-//		} catch (RemoteException e) {
-//			Log.v(TAG, "Remote exception ", e);
-//		}
+	public void chatCreated(Chat chat, boolean locally) {
+	    IChat newchat = getChat(chat);
+	    Log.d(TAG, "Chat" + chat.toString() + " created locally " + locally + "with " + chat.getParticipant());
+	    try {
+		newchat.addMessageListener(mChatListener);
+		final int n = mRemoteChatCreationListeners.beginBroadcast();
+
+		for (int i = 0; i < n; i++) {
+		    IChatManagerListener listener = mRemoteChatCreationListeners.getBroadcastItem(i);
+		    listener.chatCreated(newchat, locally);
+		}
+		mRemoteChatCreationListeners.finishBroadcast();
+	    } catch (RemoteException e) {
+		// The RemoteCallbackList will take care of removing the
+		// dead listeners.
+		Log.w(TAG, " Error while triggering remote connection listeners in chat creation", e);
+	    }
 	}
 
 	/**
-	 * Get an existing ChatAdapter or create it if necessary.
-	 * @param chat The real instance of smack chat
-	 * @return a chat adapter register in the manager
+	 * Create the PendingIntent to launch our activity if the user select this chat notification.
+	 * @param chat A ChatAdapter instance
+	 * @return A Chat activity PendingIntent
 	 */
-	private ChatAdapter getChat(Chat chat) {
-		String key = chat.getParticipant();
-		if (mChats.containsKey(key)) {
-			return mChats.get(key);
-		}
-		ChatAdapter res = new ChatAdapter(chat);
-		boolean history = PreferenceManager.getDefaultSharedPreferences(mService.getBaseContext()).getBoolean(
-			"settings_key_history", false);
-		String accountUser = PreferenceManager.getDefaultSharedPreferences(mService.getBaseContext()).getString(
-			BeemApplication.ACCOUNT_USERNAME_KEY, "");
-		String historyPath = PreferenceManager.getDefaultSharedPreferences(mService.getBaseContext()).getString(
-			BeemApplication.CHAT_HISTORY_KEY, "");
-		if ("".equals(historyPath))
-			historyPath = "/Android/data/com.beem.project.beem/chat/";
-		res.setHistory(history);
-		res.setAccountUser(accountUser);
-		res.setHistoryPath(new File(Environment.getExternalStorageDirectory(), historyPath));
-		Log.d(TAG, "getChat put " + key);
-		mChats.put(key, res);
-		return res;
-	}
-
-	@Override
-	public ChatAdapter getChat(Contact contact) {
-		String key = contact.getJIDWithRes();
-		return mChats.get(key);
+	private PendingIntent makeChatIntent(IChat chat) {
+	    Intent chatIntent = new Intent(mService, com.beem.project.beem.ui.Chat.class);
+	    chatIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP
+		| Intent.FLAG_ACTIVITY_NEW_TASK);
+	    try {
+		chatIntent.setData(chat.getParticipant().toUri());
+	    } catch (RemoteException e) {
+		Log.e(TAG, e.getMessage());
+	    }
+	    PendingIntent contentIntent = PendingIntent.getActivity(mService, 0, chatIntent,
+		PendingIntent.FLAG_UPDATE_CURRENT);
+	    return contentIntent;
 	}
 
 	/**
-	 * This methods permits to retrieve the list of contacts who have an opened chat session with us.
-	 * @return An List containing Contact instances.
-	 * @throws RemoteException If a Binder remote-invocation error occurred.
+	 * Set a notification of a new chat.
+	 * @param chat The chat to access by the notification
+	 * @param msgBody the body of the new message
 	 */
-	public List<Contact> getOpenedChatList() throws RemoteException {
-		List<Contact> openedChats = new ArrayList<Contact>();
-		IRoster mRoster = mService.getBind().getRoster();
-
-		for (ChatAdapter chat : mChats.values()) {
-			if (chat.getMessages().size() > 0) {
-				Contact t = mRoster.getContact(chat.getParticipant().getJID());
-				if (t == null)
-					t = new Contact(chat.getParticipant().getJID());
-				openedChats.add(t);
-			}
-		}
-		return openedChats;
+	private void notifyNewChat(IChat chat, String msgBody) {
+	    SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(mService);
+	    try {
+		CharSequence tickerText = mService.getBind().getRoster().getContact(chat.getParticipant().getJID())
+		    .getName();
+		Notification notification = new Notification(android.R.drawable.stat_notify_chat, tickerText, System
+		    .currentTimeMillis());
+		notification.flags = Notification.FLAG_AUTO_CANCEL;
+		notification.setLatestEventInfo(mService, tickerText, msgBody, makeChatIntent(chat));
+		mService.sendNotification(chat.getParticipant().getJID().hashCode(), notification);
+	    } catch (RemoteException e) {
+		Log.e(TAG, e.getMessage());
+	    }
 	}
 
 	/**
 	 * {@inheritDoc}
 	 */
 	@Override
-	public void removeChatCreationListener(IChatManagerListener listener) throws RemoteException {
-		if (listener != null)
-			mRemoteChatCreationListeners.unregister(listener);
+	public void processMessage(final IChat chat, Message message) {
+	    try {
+		String body = message.getBody();
+		if (!chat.isOpen() && body != null) {
+		    if (chat instanceof ChatAdapter) {
+			mChats.put(chat.getParticipant().getJID(), (ChatAdapter) chat);
+		    }
+		    notifyNewChat(chat, body);
+		}
+	    } catch (RemoteException e) {
+		Log.e(TAG, e.getMessage());
+	    }
 	}
 
-	/**
-	 * A listener for all the chat creation event that happens on the connection.
-	 * @author darisk
-	 */
-	private class ChatListener extends IMessageListener.Stub implements ChatManagerListener {
-
-		/**
-		 * Constructor.
-		 */
-		public ChatListener() {
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void chatCreated(Chat chat, boolean locally) {
-			IChat newchat = getChat(chat);
-			Log.d(TAG, "Chat" + chat.toString() + " created locally " + locally + "with " + chat.getParticipant());
-			try {
-				newchat.addMessageListener(mChatListener);
-				final int n = mRemoteChatCreationListeners.beginBroadcast();
-
-				for (int i = 0; i < n; i++) {
-					IChatManagerListener listener = mRemoteChatCreationListeners.getBroadcastItem(i);
-					listener.chatCreated(newchat, locally);
-				}
-				mRemoteChatCreationListeners.finishBroadcast();
-			} catch (RemoteException e) {
-				// The RemoteCallbackList will take care of removing the
-				// dead listeners.
-				Log.w(TAG, " Error while triggering remote connection listeners in chat creation", e);
-			}
-		}
-
-		/**
-		 * Create the PendingIntent to launch our activity if the user select this chat notification.
-		 * @param chat A ChatAdapter instance
-		 * @return A Chat activity PendingIntent
-		 */
-		private PendingIntent makeChatIntent(IChat chat) {
-			Intent chatIntent = new Intent(mService, com.beem.project.beem.ui.Chat.class);
-			chatIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP
-				| Intent.FLAG_ACTIVITY_NEW_TASK);
-			try {
-				chatIntent.setData(chat.getParticipant().toUri());
-			} catch (RemoteException e) {
-				Log.e(TAG, e.getMessage());
-			}
-			PendingIntent contentIntent = PendingIntent.getActivity(mService, 0, chatIntent,
-				PendingIntent.FLAG_UPDATE_CURRENT);
-			return contentIntent;
-		}
-
-		/**
-		 * Set a notification of a new chat.
-		 * @param chat The chat to access by the notification
-		 * @param msgBody the body of the new message
-		 */
-		private void notifyNewChat(IChat chat, String msgBody) {
-			SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(mService);
-			try {
-				CharSequence tickerText = mService.getBind().getRoster().getContact(chat.getParticipant().getJID())
-					.getName();
-				Notification notification = new Notification(android.R.drawable.stat_notify_chat, tickerText, System
-					.currentTimeMillis());
-				notification.flags = Notification.FLAG_AUTO_CANCEL;
-				notification.setLatestEventInfo(mService, tickerText, msgBody, makeChatIntent(chat));
-				mService.sendNotification(chat.getParticipant().getJID().hashCode(), notification);
-			} catch (RemoteException e) {
-				Log.e(TAG, e.getMessage());
-			}
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		@Override
-		public void processMessage(final IChat chat, Message message) {
-			try {
-								SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-				// note that we don't have to add an id as our table set id as autoincrement
-				ContentValues values = new ContentValues();
-				values.put(Messages.FROM, message.getFrom());
-				values.put(Messages.MESSAGE_ID, "message id");
-				values.put(Messages.TO, message.getTo());
-				values.put(Messages.TYPE, message.getType());
-				values.put(Messages.SUBJECT, "SUBJECT");
-				values.put(Messages.BODY, message.getBody());
-				values.put(Messages.THREAD, "THREAD");
-				values.put(Messages.EXTRAS, "EXTRAS");
-				values.put(Messages.IS_RECEIVE, true);
-				values.put(Messages.DATE_RECEIVE, dateFormat.format(new Date()));
-				values.put(Messages.DATE_READ, dateFormat.format(message.getTimestamp()));
-				mService.getContentResolver().insert(Messages.CONTENT_URI, values);
-				String body = message.getBody();
-				if (!chat.isOpen() && body != null) {
-					if (chat instanceof ChatAdapter) {
-						mChats.put(chat.getParticipant().getJID(), (ChatAdapter) chat);
-					}
-					notifyNewChat(chat, body);
-				}
-			} catch (RemoteException e) {
-				Log.e(TAG, e.getMessage());
-			}
-		}
-
-		@Override
-		public void stateChanged(final IChat chat) {
-		}
+	@Override
+	public void stateChanged(final IChat chat) {
 	}
+    }
 }
--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Thu Nov 03 14:45:56 2011 +0100
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Sun Nov 06 00:15:35 2011 +0100
@@ -43,6 +43,8 @@
  */
 package com.beem.project.beem.service;
 
+import java.text.SimpleDateFormat;
+import java.util.Date;
 import java.util.Iterator;
 
 import org.jivesoftware.smack.ConnectionConfiguration;
@@ -53,6 +55,7 @@
 import org.jivesoftware.smack.XMPPConnection;
 import org.jivesoftware.smack.XMPPException;
 import org.jivesoftware.smack.filter.PacketFilter;
+import org.jivesoftware.smack.packet.Message;
 import org.jivesoftware.smack.packet.Packet;
 import org.jivesoftware.smack.packet.Presence;
 import org.jivesoftware.smack.util.StringUtils;
@@ -62,6 +65,7 @@
 
 import android.app.Notification;
 import android.app.PendingIntent;
+import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -71,8 +75,10 @@
 import android.util.Log;
 
 import com.beem.project.beem.BeemApplication;
+import com.beem.project.beem.BeemIntent;
 import com.beem.project.beem.BeemService;
 import com.beem.project.beem.R;
+import com.beem.project.beem.providers.Messages;
 import com.beem.project.beem.service.aidl.IBeemConnectionListener;
 import com.beem.project.beem.service.aidl.IChatManager;
 import com.beem.project.beem.service.aidl.IRoster;
@@ -80,7 +86,6 @@
 import com.beem.project.beem.smack.avatar.AvatarCache;
 import com.beem.project.beem.smack.avatar.AvatarManager;
 import com.beem.project.beem.smack.pep.PepSubManager;
-import com.beem.project.beem.ui.ChangeStatus;
 import com.beem.project.beem.ui.Subscription;
 import com.beem.project.beem.utils.BeemBroadcastReceiver;
 import com.beem.project.beem.utils.Status;
@@ -228,6 +233,8 @@
 			Presence pres = (Presence) packet;
 			if (pres.getType() == Presence.Type.subscribe)
 			    return true;
+		    } else if (packet instanceof Message) {
+			return true;
 		    }
 		    return false;
 		}
@@ -442,8 +449,39 @@
     public void handleMessage(android.os.Message msg) {
 	Log.e(TAG, "HANDLEMESSAGE");
 	Bundle b = (Bundle) msg.obj;
-	switch (msg.what) {
+	com.beem.project.beem.service.Message message = b.getParcelable(BeemIntent.EXTRA_MESSAGE);
+	switch (message.getType()) {
+	    case com.beem.project.beem.service.Message.MSG_TYPE_CHAT:
 
+		org.jivesoftware.smack.packet.Message send = new org.jivesoftware.smack.packet.Message();
+		send.setTo(message.getTo());
+		send.setBody(message.getBody());
+		send.setThread(message.getThread());
+		send.setSubject(message.getSubject());
+		send.setType(org.jivesoftware.smack.packet.Message.Type.chat);
+		// TODO gerer les messages contenant des XMPPError
+		// send.set
+		try {
+		    mAdaptee.sendPacket(send);
+		} catch (IllegalStateException e) {
+		    Log.e(TAG, "Message not send", e);
+		    break;
+		}
+		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		ContentValues values = new ContentValues();
+		values.put(Messages.FROM, "me"); //TODO: Get current account name
+		values.put(Messages.MESSAGE_ID, "message id");
+		values.put(Messages.TO, message.getTo());
+		values.put(Messages.TYPE, message.getType());
+		values.put(Messages.SUBJECT, "SUBJECT");
+		values.put(Messages.BODY, message.getBody());
+		values.put(Messages.THREAD, "THREAD");
+		values.put(Messages.EXTRAS, "EXTRAS");
+		values.put(Messages.IS_RECEIVE, true);
+		values.put(Messages.DATE_RECEIVE, dateFormat.format(new Date()));
+		values.put(Messages.DATE_READ, dateFormat.format(message.getTimestamp()));
+		mService.getContentResolver().insert(Messages.CONTENT_URI, values);
+		break;
 	    default:
 		Log.w(TAG, "Unknown message " + msg);
 	}
@@ -521,6 +559,45 @@
 	/**
 	 * {@inheritDoc}
 	 */
+	/**
+	 * // * Listener. //
+	 */
+	//	    private class MsgListener implements ChatStateListener {
+	//		/**
+	//		 * Constructor.
+	//		 */
+	//		public MsgListener() {
+	//		}
+	//
+	//		@Override
+	//		public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) {
+	//		    Message msg = new Message(message);
+	//		    Log.e(TAG, "Message : " + msg.getBody());
+	//		    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+	//		    // note that we don't have to add an id as our table set id as autoincrement
+	//		    ContentValues values = new ContentValues();
+	//		    values.put(Messages.FROM, msg.getFrom());
+	//		    values.put(Messages.MESSAGE_ID, "message id");
+	//		    values.put(Messages.TO, msg.getTo());
+	//		    values.put(Messages.TYPE, msg.getType());
+	//		    values.put(Messages.SUBJECT, "SUBJECT");
+	//		    values.put(Messages.BODY, msg.getBody());
+	//		    values.put(Messages.THREAD, "THREAD");
+	//		    values.put(Messages.EXTRAS, "EXTRAS");
+	//		    values.put(Messages.IS_RECEIVE, true);
+	//		    values.put(Messages.DATE_RECEIVE, dateFormat.format(new Date()));
+	//		    values.put(Messages.DATE_READ, dateFormat.format(msg.getTimestamp()));
+	//		    mService.getContentResolver().insert(Messages.CONTENT_URI, values);
+	//		}
+	//
+	//		/**
+	//		 * {@inheritDoc}
+	//		 */
+	//		@Override
+	//		public void stateChanged(Chat chat, ChatState state) {
+	//		}
+	//
+	//	    }
 	@Override
 	public void connectionClosed() {
 	    Log.d(TAG, "closing connection");
@@ -645,9 +722,9 @@
 		    notif.flags = Notification.FLAG_AUTO_CANCEL;
 		    Intent intent = new Intent(mService, Subscription.class);
 		    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).putExtra("from", from);
-		    notif.setLatestEventInfo(mService, from,
-			mService.getString(R.string.AcceptContactRequestFrom, from),
-			PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT));
+		    notif.setLatestEventInfo(mService, from, mService
+			.getString(R.string.AcceptContactRequestFrom, from), PendingIntent.getActivity(mService, 0,
+			intent, PendingIntent.FLAG_ONE_SHOT));
 		    int id = packet.hashCode();
 		    mService.sendNotification(id, notif);
 		}
@@ -684,23 +761,40 @@
 
 	@Override
 	public void processPacket(Packet packet) {
-	    if (!(packet instanceof Presence))
-		return;
-	    Presence p = (Presence) packet;
-	    if (p.getType() != Presence.Type.subscribe)
-		return;
-	    String from = p.getFrom();
-	    Notification notification = new Notification(android.R.drawable.stat_notify_more, mService.getString(
-		R.string.AcceptContactRequest, from), System.currentTimeMillis());
-	    notification.flags = Notification.FLAG_AUTO_CANCEL;
-	    Intent intent = new Intent(mService, Subscription.class);
-	    intent.setData(Contact.makeXmppUri(from));
-	    notification.setLatestEventInfo(mService, from,
-		mService.getString(R.string.AcceptContactRequestFrom, from),
-		PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT));
-	    int id = p.hashCode();
-	    mService.sendNotification(id, notification);
+	    Log.e(TAG, "Message : " + packet.getClass().toString());
+	    if (packet instanceof Presence) {
+		Presence p = (Presence) packet;
+		if (p.getType() != Presence.Type.subscribe)
+		    return;
+		String from = p.getFrom();
+		Notification notification = new Notification(android.R.drawable.stat_notify_more, mService.getString(
+		    R.string.AcceptContactRequest, from), System.currentTimeMillis());
+		notification.flags = Notification.FLAG_AUTO_CANCEL;
+		Intent intent = new Intent(mService, Subscription.class);
+		intent.setData(Contact.makeXmppUri(from));
+		notification.setLatestEventInfo(mService, from, mService.getString(R.string.AcceptContactRequestFrom,
+		    from), PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT));
+		int id = p.hashCode();
+		mService.sendNotification(id, notification);
+	    } else if (packet instanceof Message) {
+		Message message = (Message) packet;
+		com.beem.project.beem.service.Message msg = new com.beem.project.beem.service.Message(message);
+		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		// note that we don't have to add an id as our table set id as autoincrement
+		ContentValues values = new ContentValues();
+		values.put(Messages.FROM, msg.getFrom());
+		values.put(Messages.MESSAGE_ID, "message id");
+		values.put(Messages.TO, msg.getTo());
+		values.put(Messages.TYPE, msg.getType());
+		values.put(Messages.SUBJECT, "SUBJECT");
+		values.put(Messages.BODY, msg.getBody());
+		values.put(Messages.THREAD, "THREAD");
+		values.put(Messages.EXTRAS, "EXTRAS");
+		values.put(Messages.IS_RECEIVE, true);
+		values.put(Messages.DATE_RECEIVE, dateFormat.format(new Date()));
+		values.put(Messages.DATE_READ, dateFormat.format(msg.getTimestamp()));
+		mService.getContentResolver().insert(Messages.CONTENT_URI, values);
+	    }
 	}
     }
-
 }
--- a/src/com/beem/project/beem/ui/Chat.java	Thu Nov 03 14:45:56 2011 +0100
+++ b/src/com/beem/project/beem/ui/Chat.java	Sun Nov 06 00:15:35 2011 +0100
@@ -43,26 +43,33 @@
  */
 package com.beem.project.beem.ui;
 
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
 import android.app.Activity;
-import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
 import android.content.SharedPreferences;
+import android.database.Cursor;
 import android.graphics.drawable.LayerDrawable;
 import android.net.Uri;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.RawContacts;
 import android.util.Log;
 import android.view.KeyEvent;
+import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.View.OnClickListener;
 import android.view.View.OnKeyListener;
 import android.widget.Button;
 import android.widget.EditText;
+import android.widget.Filterable;
 import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
 import android.widget.TextView;
 
+import com.beem.project.beem.BeemIntent;
 import com.beem.project.beem.R;
 import com.beem.project.beem.providers.Messages;
 import com.beem.project.beem.service.Message;
@@ -75,6 +82,7 @@
 
     private static final String TAG = "Chat";
     private String mjid;
+    private String mAccount;
 
     /**
      * Constructor.
@@ -89,12 +97,20 @@
     @Override
     protected void onCreate(Bundle savedBundle) {
 	super.onCreate(savedBundle);
-	// TODO : get account from jid. if multi account propose select
-	// Intent { act=android.intent.action.SENDTO dat=imto://jabber/jid
-	// cmp=com.beem.project.beem/.ui.Chat }
+
 	Uri contactURI = getIntent().getData();
 	mjid = contactURI.getPathSegments().get(0);
 
+	Cursor cursorAccount = getContentResolver().query(RawContacts.CONTENT_URI,
+	    new String[] { RawContacts._ID, RawContacts.ACCOUNT_NAME }, RawContacts.SOURCE_ID + "=?", new String[] { mjid }, null);
+	Log.e(TAG, "Cursor :" + cursorAccount.toString());
+	if (cursorAccount.getCount() == 1) {
+	    cursorAccount.moveToFirst();
+	    mAccount = cursorAccount.getColumnName(cursorAccount.getColumnIndex(RawContacts.ACCOUNT_NAME));
+	} else if (cursorAccount.getCount() > 1) {
+	    // TODO : get account from jid. if multi account propose select
+	}
+
 	SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
 	boolean isCompact = settings.getBoolean("settings_chat_compact_key", false);
 	// UI
@@ -103,7 +119,7 @@
 	} else {
 	    setContentView(R.layout.chat_compact);
 	}
-	
+
 	Button sendButton = (Button) findViewById(R.id.chat_send_message);
 	sendButton.setOnClickListener(new OnClickListener() {
 	    @Override
@@ -115,7 +131,6 @@
     }
 
     private void setNormalView() {
-	Log.d(TAG, "Jid : " + mjid);
 	setContentView(R.layout.chat);
 	TextView ContactNameTextView = (TextView) findViewById(R.id.chat_contact_name);
 	ContactNameTextView.setText(mjid);
@@ -125,6 +140,18 @@
 	LayerDrawable AvatarStatusDrawable = (LayerDrawable) ContactStatusIcon.getDrawable();
 	AvatarStatusDrawable.setLayerInset(1, 36, 36, 0, 0);
 
+	final Cursor cursorMessage = getContentResolver().query(Messages.CONTENT_URI,
+	    new String[] { Messages._ID, Messages.TO, Messages.FROM, Messages.DATE_READ, Messages.BODY },
+	    Messages.TO + "=? OR " + Messages.FROM + " like '%" + mjid + "%'", new String[] { mjid }, null);
+
+	BeemMessageList mAdapterMessageList = new BeemMessageList(this, R.layout.chat_msg_row, cursorMessage,
+	    new String[] { Messages._ID, Messages.TO, Messages.FROM, Messages.DATE_READ, Messages.BODY }, new int[] {
+		R.id.chatmessagename, R.id.chatmessagedate, R.id.chatmessagetext });
+
+	ListView listView = (ListView) findViewById(R.id.chat_messages);
+	registerForContextMenu(listView);
+	listView.setAdapter(mAdapterMessageList);
+
     }
 
     @Override
@@ -143,28 +170,64 @@
 	return false;
     }
 
-    
     private void sendMessage() {
 	EditText inputField = (EditText) findViewById(R.id.chat_input);
-	    final String inputContent = inputField.getText().toString();
+	final String inputContent = inputField.getText().toString();
+
+	Message message = new Message(mjid, Message.MSG_TYPE_CHAT);
+	message.setBody(inputContent);
+
+	Intent intent = new Intent(BeemIntent.ACTION_SEND_MESSAGE);
+	intent.putExtra(BeemIntent.EXTRA_ACCOUNT, mAccount);
+	intent.putExtra(BeemIntent.EXTRA_MESSAGE, message);
+	startService(intent);
+
+	inputField.setText(null);
+    }
+
+    /**
+     * Adapter message list.
+     */
+    private static class BeemMessageList extends SimpleCursorAdapter implements Filterable {
+
+	private Context mContext;
+	private int mLayout;
+
+	public BeemMessageList(Context context, int layout, Cursor c, String[] from, int[] to) {
+	    super(context, layout, c, from, to);
+	    mContext = context;
+	    mLayout = layout;
+	}
 
-	    Message message = new Message(mjid, Message.MSG_TYPE_CHAT);
-	    message.setBody(inputContent);
-	    
-	    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-	    ContentValues values = new ContentValues();
-	    values.put(Messages.FROM, "me"); //TODO: Get current account name
-	    values.put(Messages.MESSAGE_ID, "message id");
-	    values.put(Messages.TO, mjid);
-	    values.put(Messages.TYPE, message.getType());
-	    values.put(Messages.SUBJECT, "SUBJECT");
-	    values.put(Messages.BODY, message.getBody());
-	    values.put(Messages.THREAD, "THREAD");
-	    values.put(Messages.EXTRAS, "EXTRAS");
-	    values.put(Messages.IS_RECEIVE, true);
-	    values.put(Messages.DATE_RECEIVE, dateFormat.format(new Date()));
-	    values.put(Messages.DATE_READ, dateFormat.format(message.getTimestamp()));
-	    getContentResolver().insert(Messages.CONTENT_URI, values);
-	    inputField.setText(null);
+	@Override
+	public View newView(Context context, Cursor cursor, ViewGroup parent) {
+	    final LayoutInflater inflater = LayoutInflater.from(mContext);
+	    return inflater.inflate(mLayout, parent, false);
+	}
+
+	@Override
+	public void bindView(View view, Context context, Cursor cursor) {
+	    String jid = cursor.getString(cursor.getColumnIndex(Messages.TO));
+	    if (jid.length() == 0)
+		jid = cursor.getString(cursor.getColumnIndex(Messages.FROM));
+	    String date = cursor.getString(cursor.getColumnIndex(Messages.DATE_READ));
+	    String body = cursor.getString(cursor.getColumnIndex(Messages.BODY));
+	    TextView nameText = (TextView) view.findViewById(R.id.chatmessagename);
+	    if (nameText != null) {
+		nameText.setText(jid);
+	    }
+
+	    TextView dateText = (TextView) view.findViewById(R.id.chatmessagedate);
+	    if (dateText != null) {
+		dateText.setText(date);
+	    }
+
+	    TextView bodyText = (TextView) view.findViewById(R.id.chatmessagetext);
+	    if (bodyText != null) {
+		bodyText.setText(body);
+	    }
+
+	}
+
     }
 }
--- a/src/com/beem/project/beem/ui/ContactList.java	Thu Nov 03 14:45:56 2011 +0100
+++ b/src/com/beem/project/beem/ui/ContactList.java	Sun Nov 06 00:15:35 2011 +0100
@@ -523,6 +523,9 @@
 	}
     }
 
+    /**
+     * Class to observe modification in groups.
+     */
     private class BeemGroupObserver extends ContentObserver {
 
 	public BeemGroupObserver(Handler handler) {