Corrections des problèmes de l´activité Chat.
authorJean-Manuel ¨dasilvj¨ Da Silva
Wed, 11 Nov 2009 17:58:26 +0100
changeset 501 d52918cfaba7
parent 500 4da77df8f950
child 502 3091acfe31f4
Corrections des problèmes de l´activité Chat. + A présent, lorsque l´on recoit une notification, on peut se rendre sur l´activité Chat pour voir le nouveau message. + Ajout de l´affichages des derniers messages envoyés entre les contacts. (l´historique courant, pas l´historique après fermeture de BEEM) + Léger nettoyage dans la class BeemChatManager
src/com/beem/project/beem/service/BeemChatManager.java
src/com/beem/project/beem/service/ChatAdapter.java
src/com/beem/project/beem/service/Contact.java
src/com/beem/project/beem/ui/Chat.java
--- a/src/com/beem/project/beem/service/BeemChatManager.java	Wed Nov 11 03:05:34 2009 +0100
+++ b/src/com/beem/project/beem/service/BeemChatManager.java	Wed Nov 11 17:58:26 2009 +0100
@@ -27,217 +27,240 @@
 import com.beem.project.beem.service.aidl.IMessageListener;
 
 /**
- * An adapter for smack's ChatManager. This class provides functionnality to handle chats.
+ * An adapter for smack's ChatManager. This class provides functionnality to
+ * handle chats.
+ * 
  * @author darisk
  */
 public class BeemChatManager extends IChatManager.Stub {
 
-    /**
-     * A listener for all the chat creation event that happens on the connection.
-     * @author darisk
-     */
-    private class ChatListener implements ChatStateListener, ChatManagerListener, MessageListener {
-
 	/**
-	 * Constructor.
-	 */
-	public ChatListener() {
-	}
-
-	/**
-	 * {@inheritDoc}
+	 * A listener for all the chat creation event that happens on the
+	 * connection.
+	 * 
+	 * @author darisk
 	 */
-	@Override
-	public void chatCreated(Chat chat, boolean locally) {
-	    IChat newchat = getChat(chat);
-	    chat.addMessageListener(mChatListener);
-	    final int n = mRemoteChatCreationListeners.beginBroadcast();
+	private class ChatListener implements ChatStateListener, ChatManagerListener, MessageListener {
+
+		/**
+		 * Constructor.
+		 */
+		public ChatListener() {
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public void chatCreated(Chat chat, boolean locally) {
+			IChat newchat = getChat(chat);
+			chat.addMessageListener(mChatListener);
+			final int n = mRemoteChatCreationListeners.beginBroadcast();
+
+			for (int i = 0; i < n; i++) {
+				IChatManagerListener listener = mRemoteChatCreationListeners.getBroadcastItem(i);
+				try {
+					listener.chatCreated(newchat, locally);
+				} 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);
+				}
+			}
+			mRemoteChatCreationListeners.finishBroadcast();
+		}
+		
+		/**
+		 * Create the PendingIntent to launch our activity if the user select this chat notification.
+		 * @param chat
+		 * @return
+		 */
+		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);
+			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);
+		}
 
-	    for (int i = 0; i < n; i++) {
-		IChatManagerListener listener = mRemoteChatCreationListeners.getBroadcastItem(i);
-		try {
-		    listener.chatCreated(newchat, locally);
-		} 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);
+		/**
+		 * Set a notification of a new chat.
+		 * 
+		 * @param chat
+		 *            The chat to access by the notification
+		 */
+		private void notifyNewChat(IChat chat) {
+			try {
+				CharSequence tickerText = chat.getParticipant().getName();
+				Notification notification = new Notification(android.R.drawable.stat_notify_chat, tickerText, System
+						.currentTimeMillis());
+				notification.defaults = Notification.DEFAULT_ALL;
+				notification.flags = Notification.FLAG_AUTO_CANCEL;
+				notification.setLatestEventInfo(mService, tickerText, mService.getString(R.string.BeemChatManagerNewMessage), makeChatIntent(chat));
+				mService.sendNotification(chat.hashCode(), notification);
+			} catch (RemoteException e) {
+				Log.e(TAG, e.getMessage());
+			}
 		}
-	    }
-	    mRemoteChatCreationListeners.finishBroadcast();
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public void processMessage(Chat chat, Message message) {
+			ChatAdapter newchat = getChat(chat);
+			try {
+				if (message.getBody() != null)
+					newchat.addMessage(new com.beem.project.beem.service.Message(message));
+				final int n = mRemoteMessageListeners.beginBroadcast();
+				for (int i = 0; i < n; i++) {
+					IMessageListener listener = mRemoteMessageListeners.getBroadcastItem(i);
+					listener.processMessage(newchat, new com.beem.project.beem.service.Message(message));
+				}
+				mRemoteMessageListeners.finishBroadcast();
+				if (!newchat.isOpen() && message.getBody() != null) {
+					notifyNewChat(newchat);
+				}
+			} catch (RemoteException e) {
+				Log.w(TAG, e.getMessage());
+			}
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		@Override
+		public void stateChanged(Chat chat, ChatState state) {
+			IChat newchat = getChat(chat);
+			try {
+				newchat.setState(state.name());
+			} catch (RemoteException e) {
+				e.printStackTrace();
+			}
+			final int n = mRemoteMessageListeners.beginBroadcast();
+
+			for (int i = 0; i < n; i++) {
+				IMessageListener listener = mRemoteMessageListeners.getBroadcastItem(i);
+				try {
+					listener.stateChanged(newchat);
+				} catch (RemoteException e) {
+					Log.w(TAG, e.getMessage());
+				}
+			}
+			mRemoteMessageListeners.finishBroadcast();
+		}
 	}
 
 	/**
-	 * Set a notification of a new chat in android.
-	 * @param chat The chat to access by the notification
+	 * Tag to use with log methods.
 	 */
-	private void notifyNewChat(IChat chat) {
-	    try {
-		String text = chat.getParticipant().getJID();
-		Notification notif = new Notification(android.R.drawable.stat_notify_chat, text, System
-		    .currentTimeMillis());
-		notif.defaults = Notification.DEFAULT_ALL;
-		notif.flags = Notification.FLAG_AUTO_CANCEL;
-		Intent intent = new Intent(mService, Chat.class);
-		intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
-		intent.setData(chat.getParticipant().toUri());
-		notif.setLatestEventInfo(mService, text, mService.getString(R.string.BeemChatManagerNewMessage),
-		    PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
-		int id = chat.hashCode();
-		mService.sendNotification(id, notif);
-	    } catch (RemoteException e) {
-		Log.e(TAG, "notification error", e);
-	    }
-	}
+	public 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 RemoteCallbackList<IMessageListener> mRemoteMessageListeners = new RemoteCallbackList<IMessageListener>();
+
+	private final BeemService mService;
 
 	/**
-	 * {@inheritDoc}
+	 * Constructor.
+	 * 
+	 * @param chatManager
+	 *            the smack ChatManager to adapt
+	 * @param service
+	 *            the service which runs the chat manager
 	 */
-	@Override
-	public void processMessage(Chat chat, Message message) {
-	    ChatAdapter newchat = getChat(chat);
-	    try {
-		if (message.getBody() != null)
-		    newchat.addMessage(new com.beem.project.beem.service.Message(message));
-		final int n = mRemoteMessageListeners.beginBroadcast();
-		for (int i = 0; i < n; i++) {
-		    IMessageListener listener = mRemoteMessageListeners.getBroadcastItem(i);
-		    listener.processMessage(newchat, new com.beem.project.beem.service.Message(message));
-		}
-		mRemoteMessageListeners.finishBroadcast();
-		if (!newchat.isOpen() && message.getBody() != null) {
-		    notifyNewChat(newchat);
-		}
-	    } catch (RemoteException e) {
-		// The RemoteCallbackList will take care of removing the
-		// dead listeners.
-		Log.w(TAG, "Error while triggering remote connection listeners", e);
-	    }
+	public BeemChatManager(final ChatManager chatManager, final BeemService service) {
+		mService = service;
+		mAdaptee = chatManager;
+		mAdaptee.addChatListener(mChatListener);
 	}
 
 	/**
 	 * {@inheritDoc}
 	 */
 	@Override
-	public void stateChanged(Chat chat, ChatState state) {
-	    IChat newchat = getChat(chat);
-	    try {
-		newchat.setState(state.name());
-	    } catch (RemoteException e) {
-		e.printStackTrace();
-	    }
-	    final int n = mRemoteMessageListeners.beginBroadcast();
+	public void addChatCreationListener(IChatManagerListener listener) throws RemoteException {
+		mRemoteChatCreationListeners.register(listener);
+	}
 
-	    for (int i = 0; i < n; i++) {
-		IMessageListener listener = mRemoteMessageListeners.getBroadcastItem(i);
-		try {
-		    listener.stateChanged(newchat);
-		} catch (RemoteException e) {
-		    Log.w(TAG, "Error while changing chat state", e);
-		}
-	    }
-	    mRemoteMessageListeners.finishBroadcast();
+	/**
+	 * 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
+	 */
+	public IChat createChat(Contact contact, IMessageListener listener) {
+		String jid = contact.getJID();
+		return createChat(jid, listener);
 	}
-    }
 
-    /**
-     * Tag to use with log methods.
-     */
-    public 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 RemoteCallbackList<IMessageListener> mRemoteMessageListeners =
-	new RemoteCallbackList<IMessageListener>();
-
-    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);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void addChatCreationListener(IChatManagerListener listener) throws RemoteException {
-	mRemoteChatCreationListeners.register(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) {
+		mRemoteMessageListeners.register(listener);
+		String key = StringUtils.parseBareAddress(jid);
+		if (mChats.containsKey(key)) {
+			return mChats.get(key);
+		}
+		mAdaptee.createChat(key, mChatListener);
+		return mChats.get(key);
+	}
 
-    /**
-     * 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
-     */
-    public IChat createChat(Contact contact, IMessageListener listener) {
-	String jid = contact.getJID();
-	return createChat(jid, listener);
-    }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void destroyChat(IChat chat) throws RemoteException {
+		Log.d(TAG, "destroyChat - jid = " + chat.getParticipant().getJID());
+		IChat c = mChats.remove(chat.getParticipant().getJID());
+		if (c == null)
+			Log.w(TAG, "destroyChat - chat = null, jid = " + chat.getParticipant().getJID());
+	}
 
-    /**
-     * 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) {
-	mRemoteMessageListeners.register(listener);
-	String key = StringUtils.parseBareAddress(jid);
-	if (mChats.containsKey(key)) {
-	    return mChats.get(key);
+	@Override
+	public void deleteChatNotification(IChat chat) {
+		mService.deleteNotification(chat.hashCode());
 	}
-	// create the chat. the adaptee will be add automatically in the map
-	mAdaptee.createChat(key, mChatListener);
-	return mChats.get(key);
-    }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void destroyChat(IChat chat) throws RemoteException {
-	// TODO gerer les resources egalement
-	Log.d(TAG, "destroy chat jid " + chat.getParticipant().getJID());
-	IChat c = mChats.remove(chat.getParticipant().getJID());
-	if (c == null)
-	    Log.w(TAG, "CA devrait pas 1!!" + chat.getParticipant().getJID());
-    }
-
-    @Override
-    public void deleteChatNotification(IChat chat) {
-	mService.deleteNotification(chat.hashCode());
-    }
+	/**
+	 * 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 = StringUtils.parseBareAddress(chat.getParticipant());
+		if (mChats.containsKey(key)) {
+			return mChats.get(key);
+		}
+		ChatAdapter res = new ChatAdapter(chat);
+		mChats.put(key, res);
+		return res;
+	}
 
-    /**
-     * 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 = StringUtils.parseBareAddress(chat.getParticipant());
-	if (mChats.containsKey(key)) {
-	    return mChats.get(key);
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void removeChatCreationListener(IChatManagerListener listener) throws RemoteException {
+		mRemoteChatCreationListeners.unregister(listener);
 	}
-	ChatAdapter res = new ChatAdapter(chat);
-	mChats.put(key, res);
-	return res;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void removeChatCreationListener(IChatManagerListener listener) throws RemoteException {
-	mRemoteChatCreationListeners.unregister(listener);
-    }
 
 }
--- a/src/com/beem/project/beem/service/ChatAdapter.java	Wed Nov 11 03:05:34 2009 +0100
+++ b/src/com/beem/project/beem/service/ChatAdapter.java	Wed Nov 11 17:58:26 2009 +0100
@@ -13,113 +13,119 @@
 
 /**
  * An adapter for smack's Chat class.
+ * 
  * @author darisk
  */
 public class ChatAdapter extends IChat.Stub {
-    private static final int HISTORY_MAX_SIZE = 50;
+	private static final int HISTORY_MAX_SIZE = 50;
 
-    private final Chat mAdaptee;
-    private final Contact mParticipant;
-    private String mState;
-    private boolean mIsOpen;
-    private final List<Message> mMessages;
+	private final Chat mAdaptee;
+	private final Contact mParticipant;
+	private String mState;
+	private boolean mIsOpen;
+	private final List<Message> mMessages;
 
-    /**
-     * Constructor.
-     * @param chat The chat to adapt
-     */
-    public ChatAdapter(final Chat chat) {
-	mAdaptee = chat;
-	mParticipant = new Contact(chat.getParticipant());
-	mMessages = new LinkedList<Message>();
-    }
+	/**
+	 * Constructor.
+	 * 
+	 * @param chat
+	 *            The chat to adapt
+	 */
+	public ChatAdapter(final Chat chat) {
+		mAdaptee = chat;
+		mParticipant = new Contact(chat.getParticipant());
+		mMessages = new LinkedList<Message>();
+	}
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Contact getParticipant() throws RemoteException {
-	return mParticipant;
-    }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public Contact getParticipant() throws RemoteException {
+		return mParticipant;
+	}
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void sendMessage(com.beem.project.beem.service.Message message) throws RemoteException {
-	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.sendMessage(send);
-	    mMessages.add(message);
-	} catch (XMPPException e) {
-	    // TODO Auto-generated catch block
-	    e.printStackTrace();
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void sendMessage(com.beem.project.beem.service.Message message) throws RemoteException {
+		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.sendMessage(send);
+			mMessages.add(message);
+		} catch (XMPPException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
 	}
-    }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getState() throws RemoteException {
-	return mState;
-    }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String getState() throws RemoteException {
+		return mState;
+	}
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setState(String state) throws RemoteException {
-	mState = state;
-    }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setState(String state) throws RemoteException {
+		mState = state;
+	}
 
-    /**
-     * Get the adaptee for the Chat.
-     * @return The real chat object
-     */
-    public Chat getAdaptee() {
-	return mAdaptee;
-    }
+	/**
+	 * Get the adaptee for the Chat.
+	 * 
+	 * @return The real chat object
+	 */
+	public Chat getAdaptee() {
+		return mAdaptee;
+	}
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void setOpen(boolean isOpen) {
-	this.mIsOpen = isOpen;
-    }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void setOpen(boolean isOpen) {
+		this.mIsOpen = isOpen;
+	}
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isOpen() {
-	return mIsOpen;
-    }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public boolean isOpen() {
+		return mIsOpen;
+	}
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public List<Message> getMessages() throws RemoteException {
-	return Collections.unmodifiableList(mMessages);
-    }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public List<Message> getMessages() throws RemoteException {
+		return Collections.unmodifiableList(mMessages);
+	}
 
-    /**
-     * Add a message in the chat history.
-     * @param msg the message to add
-     */
-    void addMessage(Message msg) {
-	if (mMessages.size() == HISTORY_MAX_SIZE)
-	    mMessages.remove(0);
-	mMessages.add(msg);
-    }
+	/**
+	 * Add a message in the chat history.
+	 * 
+	 * @param msg
+	 *            the message to add
+	 */
+	void addMessage(Message msg) {
+		if (mMessages.size() == HISTORY_MAX_SIZE)
+			mMessages.remove(0);
+		mMessages.add(msg);
+	}
 
 }
--- a/src/com/beem/project/beem/service/Contact.java	Wed Nov 11 03:05:34 2009 +0100
+++ b/src/com/beem/project/beem/service/Contact.java	Wed Nov 11 17:58:26 2009 +0100
@@ -19,339 +19,385 @@
 
 /**
  * This class contains informations on a jabber contact.
+ * 
  * @author darisk
  */
 public class Contact implements Parcelable {
 
-    /**
-     * Parcelable.Creator needs by Android.
-     */
-    public static final Parcelable.Creator<Contact> CREATOR = new Parcelable.Creator<Contact>() {
+	/**
+	 * Parcelable.Creator needs by Android.
+	 */
+	public static final Parcelable.Creator<Contact> CREATOR = new Parcelable.Creator<Contact>() {
+
+		@Override
+		public Contact createFromParcel(Parcel source) {
+			return new Contact(source);
+		}
+
+		@Override
+		public Contact[] newArray(int size) {
+			return new Contact[size];
+		}
+	};
+
+	private int mID;
+	private int mStatus;
+	private String mJID;
+	private String mMsgState;
+	private List<String> mRes;
+	private List<String> mGroups;
+	private String mName;
+
+	/**
+	 * Constructor.
+	 */
+	public Contact() {
+	}
+
+	/**
+	 * Construct a contact from a parcel.
+	 * 
+	 * @param in
+	 *            parcel to use for construction
+	 */
+	private Contact(final Parcel in) {
+		mID = in.readInt();
+		mStatus = in.readInt();
+		mJID = in.readString();
+		mName = in.readString();
+		mMsgState = in.readString();
+		mRes = new ArrayList<String>();
+		mGroups = new ArrayList<String>();
+		in.readStringList(mRes);
+		in.readStringList(mGroups);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void writeToParcel(Parcel dest, int flags) {
+		dest.writeInt(mID);
+		dest.writeInt(mStatus);
+		dest.writeString(mJID);
+		dest.writeString(mName);
+		dest.writeString(mMsgState);
+		dest.writeStringList(getMRes());
+		dest.writeStringList(getGroups());
+	}
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param jid
+	 *            JID of the contact
+	 */
+	public Contact(final String jid) {
+		mJID = StringUtils.parseBareAddress(jid);
+		mName = mJID;
+		mStatus = Status.CONTACT_STATUS_DISCONNECT;
+		mMsgState = null;
+		mRes = new ArrayList<String>();
+		String res = StringUtils.parseResource(jid);
+		if (!"".equals(res))
+			mRes.add(res);
+		mGroups = new ArrayList<String>();
+	}
 
+	/**
+	 * Create a contact from a Uri.
+	 * 
+	 * @param uri
+	 *            an uri for the contact
+	 * @throws IllegalArgumentException
+	 *             if it is not a xmpp uri
+	 */
+	public Contact(final Uri uri) {
+		if (!"xmpp".equals(uri.getScheme()))
+			throw new IllegalArgumentException();
+		String enduri = uri.getEncodedSchemeSpecificPart();
+		mJID = StringUtils.parseBareAddress(enduri);
+		mName = mJID;
+		mStatus = Status.CONTACT_STATUS_DISCONNECT;
+		mMsgState = null;
+		mRes = new ArrayList<String>();
+		mRes.add(StringUtils.parseResource(enduri));
+		mGroups = new ArrayList<String>();
+	}
+
+	/**
+	 * Add a group for the contact.
+	 * 
+	 * @param group
+	 *            the group
+	 */
+	public void addGroup(String group) {
+		if (!mGroups.contains(group))
+			mGroups.add(group);
+	}
+
+	/**
+	 * Remove the contact from a group.
+	 * 
+	 * @param group
+	 *            the group to delete the contact from.
+	 */
+	public void delGroup(String group) {
+		mGroups.remove(group);
+	}
+
+	/**
+	 * Add a resource for this contact.
+	 * 
+	 * @param res
+	 *            the resource to add
+	 */
+	public void addRes(String res) {
+		if (!mRes.contains(res))
+			mRes.add(res);
+	}
+
+	/**
+	 * Delete a resource for this contact.
+	 * 
+	 * @param res
+	 *            the resource de delete
+	 */
+	public void delRes(String res) {
+		mRes.remove(res);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
-	public Contact createFromParcel(Parcel source) {
-	    return new Contact(source);
+	public int describeContents() {
+		// TODO Auto-generated method stub
+		return 0;
+	}
+
+	/**
+	 * Get the groups the contact is in.
+	 * 
+	 * @return the mGroups
+	 */
+	public List<String> getGroups() {
+		return mGroups;
+	}
+
+	/**
+	 * Get the id of the contact on the phone contact list.
+	 * 
+	 * @return the mID
+	 */
+	public int getID() {
+		return mID;
+	}
+
+	/**
+	 * Get the Jabber ID of the contact.
+	 * 
+	 * @return the Jabber ID
+	 */
+	public String getJID() {
+		return mJID;
+	}
+
+	/**
+	 * Get the list of resource for the contact.
+	 * 
+	 * @return the mRes
+	 */
+	public List<String> getMRes() {
+		return mRes;
 	}
 
-	@Override
-	public Contact[] newArray(int size) {
-	    return new Contact[size];
+	/**
+	 * Get the message status of the contact.
+	 * 
+	 * @return the message status of the contact.
+	 */
+	public String getMsgState() {
+		return mMsgState;
 	}
-    };
 
-    private int mID;
-    private int mStatus;
-    private String mJID;
-    private String mMsgState;
-    private List<String> mRes;
-    private List<String> mGroups;
-    private String mName;
-
-    /**
-     * Constructor.
-     */
-    public Contact() {
-    }
+	/**
+	 * Get the name of the contact.
+	 * 
+	 * @return the mName
+	 */
+	public String getName() {
+		return mName;
+	}
 
-    /**
-     * Construct a contact from a parcel.
-     * @param in parcel to use for construction
-     */
-    private Contact(final Parcel in) {
-	mID = in.readInt();
-	mStatus = in.readInt();
-	mJID = in.readString();
-	mName = in.readString();
-	mMsgState = in.readString();
-	mRes = new ArrayList<String>();
-	mGroups = new ArrayList<String>();
-	in.readStringList(mRes);
-	in.readStringList(mGroups);
-    }
-    
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-	dest.writeInt(mID);
-	dest.writeInt(mStatus);
-	dest.writeString(mJID);
-	dest.writeString(mName);
-	dest.writeString(mMsgState);
-	dest.writeStringList(getMRes());
-	dest.writeStringList(getGroups());
-    }
+	/**
+	 * Get the status of the contact.
+	 * 
+	 * @return the mStatus
+	 */
+	public int getStatus() {
+		return mStatus;
+	}
 
-    /**
-     * Constructor.
-     * @param jid JID of the contact
-     */
-    public Contact(final String jid) {
-	mJID = StringUtils.parseBareAddress(jid);
-	mName = mJID;
-	mStatus = Status.CONTACT_STATUS_DISCONNECT;
-	mRes = new ArrayList<String>();
-	String res = StringUtils.parseResource(jid);
-	if (!"".equals(res))
-	    mRes.add(res);
-	mGroups = new ArrayList<String>();
-    }
+	/**
+	 * Set the groups the contact is in.
+	 * 
+	 * @param groups
+	 *            list of groups
+	 */
+	public void setGroups(Collection<RosterGroup> groups) {
+		this.mGroups.clear();
+		for (RosterGroup rosterGroup : groups) {
+			mGroups.add(rosterGroup.getName());
+		}
+	}
 
-    /**
-     * Create a contact from a Uri.
-     * @param uri an uri for the contact
-     * @throws IllegalArgumentException if it is not a xmpp uri
-     */
-    public Contact(final Uri uri) {
-	if (!"xmpp".equals(uri.getScheme()))
-	    throw new IllegalArgumentException();
-	String enduri = uri.getEncodedSchemeSpecificPart();
-	mJID = StringUtils.parseBareAddress(enduri);
-	mName = mJID;
-	mStatus = Status.CONTACT_STATUS_DISCONNECT;
-	mRes = new ArrayList<String>();
-	mRes.add(StringUtils.parseResource(enduri));
-	mGroups = new ArrayList<String>();
-    }
+	/**
+	 * Set the groups the contact is in.
+	 * 
+	 * @param groups
+	 *            the mGroups to set
+	 */
+	public void setGroups(List<String> groups) {
+		this.mGroups = groups;
+	}
 
-    /**
-     * Add a group for the contact.
-     * @param group the group
-     */
-    public void addGroup(String group) {
-	if (!mGroups.contains(group))
-	    mGroups.add(group);
-    }
-
-    /**
-     * Remove the contact from a group.
-     * @param group the group to delete the contact from.
-     */
-    public void delGroup(String group) {
-	mGroups.remove(group);
-    }
-
-    /**
-     * Add a resource for this contact.
-     * @param res the resource to add
-     */
-    public void addRes(String res) {
-	if (!mRes.contains(res))
-	    mRes.add(res);
-    }
+	/**
+	 * set the id of te contact on the phone contact list.
+	 * 
+	 * @param mid
+	 *            the mID to set
+	 */
+	public void setID(int mid) {
+		mID = mid;
+	}
 
-    /**
-     * Delete a resource for this contact.
-     * @param res the resource de delete
-     */
-    public void delRes(String res) {
-	mRes.remove(res);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int describeContents() {
-	// TODO Auto-generated method stub
-	return 0;
-    }
+	/**
+	 * Set the Jabber ID of the contact.
+	 * 
+	 * @param jid
+	 *            the jabber ID to set
+	 */
+	public void setJID(String jid) {
+		mJID = jid;
+	}
 
-    /**
-     * Get the groups the contact is in.
-     * @return the mGroups
-     */
-    public List<String> getGroups() {
-	return mGroups;
-    }
-
-    /**
-     * Get the id of the contact on the phone contact list.
-     * @return the mID
-     */
-    public int getID() {
-	return mID;
-    }
+	/**
+	 * Set a list of resource for the contact.
+	 * 
+	 * @param mRes
+	 *            the mRes to set
+	 */
+	public void setMRes(List<String> mRes) {
+		this.mRes = mRes;
+	}
 
-    /**
-     * Get the Jabber ID of the contact.
-     * @return the Jabber ID
-     */
-    public String getJID() {
-	return mJID;
-    }
-
-    /**
-     * Get the list of resource for the contact.
-     * @return the mRes
-     */
-    public List<String> getMRes() {
-	return mRes;
-    }
+	/**
+	 * Set the message status of the contact.
+	 * 
+	 * @param msgState
+	 *            the message status of the contact to set
+	 */
+	public void setMsgState(String msgState) {
+		mMsgState = msgState;
+	}
 
-    /**
-     * Get the message status of the contact.
-     * @return the message status of the contact.
-     */
-    public String getMsgState() {
-	return mMsgState;
-    }
-
-    /**
-     * Get the name of the contact.
-     * @return the mName
-     */
-    public String getName() {
-	return mName;
-    }
-
-    /**
-     * Get the status of the contact.
-     * @return the mStatus
-     */
-    public int getStatus() {
-	return mStatus;
-    }
-
-    /**
-     * Set the groups the contact is in.
-     * @param groups list of groups
-     */
-    public void setGroups(Collection<RosterGroup> groups) {
-	this.mGroups.clear();
-	for (RosterGroup rosterGroup : groups) {
-	    mGroups.add(rosterGroup.getName());
+	/**
+	 * Set the name of the contact.
+	 * 
+	 * @param name
+	 *            the mName to set
+	 */
+	public void setName(String name) {
+		if (name == null || "".equals(name)) {
+			this.mName = this.mJID;
+			this.mName = StringUtils.parseName(this.mName);
+			if (this.mName == null || "".equals(this.mName))
+				this.mName = this.mJID;
+		} else {
+			this.mName = name;
+		}
 	}
-    }
 
-    /**
-     * Set the groups the contact is in.
-     * @param groups the mGroups to set
-     */
-    public void setGroups(List<String> groups) {
-	this.mGroups = groups;
-    }
-
-    /**
-     * set the id of te contact on the phone contact list.
-     * @param mid the mID to set
-     */
-    public void setID(int mid) {
-	mID = mid;
-    }
+	/**
+	 * Set the status of the contact.
+	 * 
+	 * @param status
+	 *            the mStatus to set
+	 */
+	public void setStatus(int status) {
+		mStatus = status;
+	}
 
-    /**
-     * Set the Jabber ID of the contact.
-     * @param jid the jabber ID to set
-     */
-    public void setJID(String jid) {
-	mJID = jid;
-    }
+	/**
+	 * Set the status of the contact using a presence packet.
+	 * 
+	 * @param presence
+	 *            the presence containing status
+	 */
+	public void setStatus(Presence presence) {
+		mStatus = Status.getStatusFromPresence(presence);
+		mMsgState = presence.getStatus();
+	}
 
-    /**
-     * Set a list of resource for the contact.
-     * @param mRes the mRes to set
-     */
-    public void setMRes(List<String> mRes) {
-	this.mRes = mRes;
-    }
-
-    /**
-     * Set the message status of the contact.
-     * @param msgState the message status of the contact to set
-     */
-    public void setMsgState(String msgState) {
-	mMsgState = msgState;
-    }
+	/**
+	 * Set status for the contact.
+	 * 
+	 * @param presence
+	 *            The presence packet which contains the status
+	 */
+	public void setStatus(PresenceAdapter presence) {
+		mStatus = presence.getStatus();
+		mMsgState = presence.getStatusText();
 
-    /**
-     * Set the name of the contact.
-     * @param name the mName to set
-     */
-    public void setName(String name) {
-	if (name == null || "".equals(name)) {
-	    this.mName = this.mJID;
-	    this.mName = StringUtils.parseName(this.mName);
-	    if (this.mName == null || "".equals(this.mName))
-		this.mName = this.mJID;
-	} else {
-	    this.mName = name;
 	}
-    }
 
-    /**
-     * Set the status of the contact.
-     * @param status the mStatus to set
-     */
-    public void setStatus(int status) {
-	mStatus = status;
-    }
-
-    /**
-     * Set the status of the contact using a presence packet.
-     * @param presence the presence containing status
-     */
-    public void setStatus(Presence presence) {
-	mStatus = Status.getStatusFromPresence(presence);
-	mMsgState = presence.getStatus();
-    }
-
-    /**
-     * Set status for the contact.
-     * @param presence The presence packet which contains the status
-     */
-    public void setStatus(PresenceAdapter presence) {
-	mStatus = presence.getStatus();
-	mMsgState = presence.getStatusText();
-
-    }
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public String toString() {
+		if (mJID != null)
+			return mJID;
+		return super.toString();
+	}
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String toString() {
-	if (mJID != null)
-	    return mJID;
-	return super.toString();
-    }
+	/**
+	 * Get a URI to access the contact.
+	 * 
+	 * @return the URI
+	 */
+	public Uri toUri() {
+		StringBuilder build = new StringBuilder("xmpp:");
+		String name = StringUtils.parseName(mJID);
+		build.append(name);
+		if (!"".equals(name))
+			build.append('@');
+		build.append(StringUtils.parseServer(mJID));
+		Uri u = Uri.parse(build.toString());
+		return u;
+	}
 
-    /**
-     * Get a URI to access the contact.
-     * @return the URI
-     */
-    public Uri toUri() {
-	StringBuilder build = new StringBuilder("xmpp:");
-	String name = StringUtils.parseName(mJID);
-	build.append(name);
-	if (!"".equals(name))
-	    build.append('@');
-	build.append(StringUtils.parseServer(mJID));
-	Uri u = Uri.parse(build.toString());
-	return u;
-    }
-
-    /**
-     * Get a URI to access the specific contact on this resource.
-     * @param resource the resource of the contact
-     * @return the URI
-     */
-    public Uri toUri(String resource) {
-	StringBuilder build = new StringBuilder("xmpp:");
-	String name = StringUtils.parseName(mJID);
-	build.append(name);
-	if (!"".equals(name))
-	    build.append('@');
-	build.append(StringUtils.parseServer(mJID));
-	if (!"".equals(resource)) {
-	    build.append('/');
-	    build.append(resource);
+	/**
+	 * Get a URI to access the specific contact on this resource.
+	 * 
+	 * @param resource
+	 *            the resource of the contact
+	 * @return the URI
+	 */
+	public Uri toUri(String resource) {
+		StringBuilder build = new StringBuilder("xmpp:");
+		String name = StringUtils.parseName(mJID);
+		build.append(name);
+		if (!"".equals(name))
+			build.append('@');
+		build.append(StringUtils.parseServer(mJID));
+		if (!"".equals(resource)) {
+			build.append('/');
+			build.append(resource);
+		}
+		Uri u = Uri.parse(build.toString());
+		return u;
 	}
-	Uri u = Uri.parse(build.toString());
-	return u;
-    }
-
-
 
 }
--- a/src/com/beem/project/beem/ui/Chat.java	Wed Nov 11 03:05:34 2009 +0100
+++ b/src/com/beem/project/beem/ui/Chat.java	Wed Nov 11 17:58:26 2009 +0100
@@ -1,12 +1,10 @@
 package com.beem.project.beem.ui;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.jivesoftware.smack.packet.Presence;
 import org.jivesoftware.smack.util.StringUtils;
 
 import android.app.Activity;
@@ -194,22 +192,14 @@
 		super.onNewIntent(intent);
 
 		Log.v(TAG, "BEGIN onNewIntent.");
-		mContact = new Contact(intent.getData());
-		if (mRoster != null) {
-			try {
-				mContact = mRoster.getContact(mContact.getJID());
-				if (mContact.getMsgState() == null)
-					mContact.setMsgState(mDefaultStatusMessages.get(mContact.getStatus()));
-		
-				updateContactInformations();
-				updateContactStatusIcon();
-			} catch (RemoteException e) {
-				Log.e(TAG, e.getMessage());
-			}
+		try {
+			changeCurrentChat((mContact = new Contact(intent.getData())));
+		} catch (RemoteException e) {
+			Log.e(TAG, e.getMessage());
 		}
 		Log.v(TAG, "END onNewIntent.");
 	}
-	
+
 	/**
 	 * {@inheritDoc}.
 	 */
@@ -218,7 +208,7 @@
 		// TODO
 		super.onSaveInstanceState(savedInstanceState);
 	}
-	
+
 	/**
 	 * {@inheritDoc}.
 	 */
@@ -229,6 +219,73 @@
 	}
 
 	/**
+	 * Change the displayed chat.
+	 * 
+	 * @param contact
+	 * @throws RemoteException
+	 */
+	private void changeCurrentChat(Contact contact) throws RemoteException {
+		Log.v(TAG, "BEGIN changeCurrentChat.");
+		if (mChat != null)
+			mChat.setOpen(false);
+		mChat = mChatManager.createChat(contact, mMessageListener);
+		mChat.setOpen(true);
+
+		mChatManager.deleteChatNotification(mChat);
+
+		mContact = mRoster.getContact(contact.getJID());
+		if (mContact.getMsgState() == null || mContact.getMsgState().equals(""))
+			mContact.setMsgState(mDefaultStatusMessages.get(mContact.getStatus()));
+		updateContactInformations();
+		updateContactStatusIcon();
+		
+		playRegisteredTranscript();
+		Log.v(TAG, "END changeCurrentChat.");
+	}
+	
+	/**
+	 * Get all messages from the current chat and refresh
+	 * the activity with them.
+	 * 
+	 * @throws RemoteException
+	 */
+	private void playRegisteredTranscript() throws RemoteException {
+		String fromBareJid = null;
+		String fromName = null;
+		List<Message> chatMessages = mChat.getMessages();
+		
+		Log.v(TAG, "BEGIN playRegisteredTranscript.");
+		mListMessages.clear();
+		if (chatMessages.size() > 0) {
+			MessageText lastMessage = null;
+			for (Message m : chatMessages) {
+				fromBareJid = StringUtils.parseBareAddress(m.getFrom());
+				fromName = mContact.getName();
+				
+				if (fromBareJid == null) {
+					fromBareJid = getString(R.string.chat_self);
+					fromName = getString(R.string.chat_self);
+				}
+
+				if (lastMessage == null) {
+					lastMessage = new MessageText(fromBareJid, fromName, m.getBody());
+					continue;
+				}
+
+				if (!lastMessage.getBareJid().equals(fromBareJid)) {
+					mListMessages.add(lastMessage);
+					lastMessage = new MessageText(fromBareJid, fromName, m.getBody());
+				}
+				else
+					lastMessage.setMessage(lastMessage.getMessage().concat("\n" + m.getBody()));
+			}
+			mListMessages.add(lastMessage);
+		}
+		mMessagesListAdapter.notifyDataSetChanged();
+		Log.v(TAG, "END playRegisteredTranscript.");
+	}
+
+	/**
 	 * 
 	 * @author Jamu
 	 * 
@@ -248,20 +305,9 @@
 			mBroadcastReceiver.setBinded(true);
 			try {
 				mChatManager = mXmppFacade.getChatManager();
-
 				mRoster = mXmppFacade.getRoster();
 				mRoster.addRosterListener(mBeemRosterListener);
-
-				mChat = mChatManager.createChat((mContact = new Contact(getIntent().getData())), mMessageListener);
-				mChat.setOpen(true);
-				mChatManager.deleteChatNotification(mChat);
-
-				mContact = mRoster.getContact(mContact.getJID());
-				if (mContact.getMsgState() == null)
-					mContact.setMsgState(mDefaultStatusMessages.get(mContact.getStatus()));
-
-				updateContactInformations();
-				updateContactStatusIcon();
+				changeCurrentChat((mContact = new Contact(getIntent().getData())));
 			} catch (RemoteException e) {
 				Log.e(TAG, e.getMessage());
 			}
@@ -654,6 +700,11 @@
 		Log.v(TAG, "END sendMessage.");
 	}
 
+	/**
+	 * Create a map which contains default status messages.
+	 * 
+	 * @return
+	 */
 	private Map<Integer, String> createDefaultStatusMessagesMap() {
 		Map<Integer, String> defaultStatusMessages = new HashMap<Integer, String>();
 		defaultStatusMessages.put(Status.CONTACT_STATUS_AVAILABLE, getString(R.string.contact_status_msg_available));
@@ -663,7 +714,7 @@
 		defaultStatusMessages.put(Status.CONTACT_STATUS_BUSY, getString(R.string.contact_status_msg_dnd));
 		defaultStatusMessages.put(Status.CONTACT_STATUS_DISCONNECT, getString(R.string.contact_status_msg_offline));
 		defaultStatusMessages.put(Status.CONTACT_STATUS_UNAVAILABLE, getString(R.string.contact_status_msg_xa));
-		
+
 		return (defaultStatusMessages);
 	}
 }