More refactoring to send and receive messages by intent. default tip
authorDa Risk <da_risk@beem-project.com>
Sat, 04 Jun 2011 21:50:56 +0200
changeset 890 82ab018f3a4c
parent 889 fb4d6a08bffa
More refactoring to send and receive messages by intent.
AndroidManifest.xml
src/com/beem/project/beem/BeemIntent.java
src/com/beem/project/beem/BeemService.java
src/com/beem/project/beem/Intent.java
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/LoginAnim.java
src/com/beem/project/beem/utils/BeemBroadcastReceiver.java
--- a/AndroidManifest.xml	Thu Jun 02 01:28:40 2011 +0200
+++ b/AndroidManifest.xml	Sat Jun 04 21:50:56 2011 +0200
@@ -39,6 +39,12 @@
 			android:name="android.intent.action.BOOT_COMPLETED" />
 			</intent-filter> </receiver>
 		-->
+		<receiver android:name=".utils.BeemBroadcastReceiver">
+		    <intent-filter android:priority="-1" >
+			<action android:name="com.beem.project.beem.intent.action.MESSAGE_RECEIVED" />
+		    </intent-filter>
+		</receiver>
+
 		<provider android:name=".providers.AvatarProvider"
 		    android:authorities="com.beem.project.beem.providers.avatarprovider"
 		    android:exported="false" />
@@ -49,7 +55,7 @@
 				<action android:name="com.beem.project.beem.BeemService"></action>
 				<action android:name="com.beem.project.beem.intent.action.CONNECT" />
 				<action android:name="com.beem.project.beem.intent.action.DISCONNECT" />
-				<action android:name="com.beem.project.beem.intent.action.SEND_MSG" />
+				<action android:name="com.beem.project.beem.intent.action.SEND_MESSAGE" />
 			</intent-filter>
 		</service>
 	</application>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/BeemIntent.java	Sat Jun 04 21:50:56 2011 +0200
@@ -0,0 +1,69 @@
+
+/*
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009 by Frederic-Charles Barthelery,
+                          Jean-Manuel Da Silva,
+                          Nikita Kozlov,
+                          Philippe Lago,
+                          Jean Baptiste Vergely,
+                          Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://dev.beem-project.com/
+
+    Epitech, hereby disclaims all copyright interest in the program "Beem"
+    written by Frederic-Charles Barthelery,
+               Jean-Manuel Da Silva,
+               Nikita Kozlov,
+               Philippe Lago,
+               Jean Baptiste Vergely,
+               Vincent Veronis.
+
+    Nicolas Sadirac, November 26, 2009
+    President of Epitech.
+
+    Flavien Astraud, November 26, 2009
+    Head of the EIP Laboratory.
+
+*/
+package com.beem.project.beem;
+
+public class BeemIntent {
+
+    public static final String ACTION_CONNECT = "com.beem.project.beem.intent.action.CONNECT";
+
+    public static final String ACTION_DISCONNECT = "com.beem.project.beem.intent.action.DISCONNECT";
+
+    public static final String ACTION_SEND_MESSAGE = "com.beem.project.beem.intent.action.SEND_MESSAGE";
+
+    /*Broadcast Receiver's action */
+    public static final String ACTION_CONNECTED = "com.beem.project.beem.intent.action.CONNECTED";
+
+    public static final String ACTION_DISCONNECTED = "com.beem.project.beem.intent.action.DISCONNECTED";
+
+    public static final String ACTION_MESSAGE_RECEIVED = "com.beem.project.beem.intent.action.MESSAGE_RECEIVED";
+
+    public static final String EXTRA_ACCOUNT = "com.beem.project.beem.intent.extra.ACCOUNT";
+
+    public static final String EXTRA_JID = "com.beem.project.beem.intent.extra.JID";
+
+    public static final String EXTRA_MESSAGE = "com.beem.project.beem.intent.extra.MESSAGE";
+
+}
+
--- a/src/com/beem/project/beem/BeemService.java	Thu Jun 02 01:28:40 2011 +0200
+++ b/src/com/beem/project/beem/BeemService.java	Sat Jun 04 21:50:56 2011 +0200
@@ -110,7 +110,6 @@
 
     private static final String TAG = "BeemService";
     private static final int DEFAULT_XMPP_PORT = 5222;
-    //private static final String COMMAND_NAMESPACE = "http://jabber.org/protocol/commands";
 
     private static final int MESSAGE_CONNECT = 0x1;
     private static final int MESSAGE_SEND_MSG = 0x2;
@@ -448,9 +447,9 @@
     private void handleIntent(Intent intent) {
 	Message msg = null;
 	String action = intent.getAction();
-	if (com.beem.project.beem.Intent.ACTION_CONNECT.equals(action)) {
+	if (BeemIntent.ACTION_CONNECT.equals(action)) {
 	    msg = mHandler.obtainMessage(MESSAGE_CONNECT, intent.getExtras());
-	} else if (com.beem.project.beem.Intent.ACTION_SEND_MSG.equals(action)) {
+	} else if (BeemIntent.ACTION_SEND_MESSAGE.equals(action)) {
 	    msg = mHandler.obtainMessage(MESSAGE_SEND_MSG, intent.getExtras());
 	} else {
 	    Log.w(TAG, "Unknown intent " + intent);
@@ -529,8 +528,10 @@
 		    handleConnect(b);
 		    break;
 		case MESSAGE_SEND_MSG:
-		    String account = b.getString(com.beem.project.beem.Intent.EXTRA_ACCOUNT);
+		    String account = b.getString(BeemIntent.EXTRA_ACCOUNT);
 		    XmppConnectionAdapter con = mConnections.get(account);
+		    //TODD
+		    con = mConnection;
 		    if (con != null) {
 			con.handleMessage(msg);
 		    }
@@ -542,16 +543,16 @@
     }
 
     private void handleConnect(Bundle b) {
-	Intent res = new Intent(com.beem.project.beem.Intent.ACTION_DISCONNECTED);
+	Intent res = new Intent(BeemIntent.ACTION_DISCONNECTED);
 	String account = null;
 	if (b != null)
-	    account = b.getString(com.beem.project.beem.Intent.EXTRA_ACCOUNT);
+	    account = b.getString(BeemIntent.EXTRA_ACCOUNT);
 	if (account == null) //TODO temporary
 	    account = "dummy";
 	if (account == null) {
 	    //connect all
 	} else {
-	    res.putExtra(com.beem.project.beem.Intent.EXTRA_ACCOUNT, account);
+	    res.putExtra(BeemIntent.EXTRA_ACCOUNT, account);
 	    XmppConnectionAdapter con = mConnections.get(account);
 	    if (con != null && con.isAuthentificated())
 		return;
@@ -570,7 +571,7 @@
 		    if(con.connectSync()){
 			mConnections.put(account, con);
 			mConnection = con;
-			res.setAction(com.beem.project.beem.Intent.ACTION_CONNECTED);
+			res.setAction(BeemIntent.ACTION_CONNECTED);
 			//TODO 
 			mBind = new XmppFacade(con);
 		    } else {
--- a/src/com/beem/project/beem/Intent.java	Thu Jun 02 01:28:40 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-
-/*
-    BEEM is a videoconference application on the Android Platform.
-
-    Copyright (C) 2009 by Frederic-Charles Barthelery,
-                          Jean-Manuel Da Silva,
-                          Nikita Kozlov,
-                          Philippe Lago,
-                          Jean Baptiste Vergely,
-                          Vincent Veronis.
-
-    This file is part of BEEM.
-
-    BEEM is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    BEEM is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
-
-    Please send bug reports with examples or suggestions to
-    contact@beem-project.com or http://dev.beem-project.com/
-
-    Epitech, hereby disclaims all copyright interest in the program "Beem"
-    written by Frederic-Charles Barthelery,
-               Jean-Manuel Da Silva,
-               Nikita Kozlov,
-               Philippe Lago,
-               Jean Baptiste Vergely,
-               Vincent Veronis.
-
-    Nicolas Sadirac, November 26, 2009
-    President of Epitech.
-
-    Flavien Astraud, November 26, 2009
-    Head of the EIP Laboratory.
-
-*/
-package com.beem.project.beem;
-
-public class Intent {
-
-    public static final String ACTION_CONNECT = "com.beem.project.beem.intent.action.CONNECT";
-
-    public static final String ACTION_DISCONNECT = "com.beem.project.beem.intent.action.DISCONNECT";
-
-    public static final String ACTION_SEND_MSG = "com.beem.project.beem.intent.action.SEND_MSG";
-
-    public static final String ACTION_CONNECTED = "com.beem.project.beem.intent.action.CONNECTED";
-
-    public static final String ACTION_DISCONNECTED = "com.beem.project.beem.intent.action.DISCONNECTED";
-
-    public static final String EXTRA_ACCOUNT = "com.beem.project.beem.intent.extra.ACCOUNT";
-
-    public static final String EXTRA_JID = "com.beem.project.beem.intent.extra.JID";
-
-
-}
-
--- a/src/com/beem/project/beem/service/BeemChatManager.java	Thu Jun 02 01:28:40 2011 +0200
+++ b/src/com/beem/project/beem/service/BeemChatManager.java	Sat Jun 04 21:50:56 2011 +0200
@@ -43,7 +43,6 @@
 */
 package com.beem.project.beem.service;
 
-import java.io.File;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -52,37 +51,33 @@
 import org.jivesoftware.smack.Chat;
 import org.jivesoftware.smack.ChatManager;
 import org.jivesoftware.smack.ChatManagerListener;
+import org.jivesoftware.smack.MessageListener;
+import org.jivesoftware.smack.XMPPException;
 
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.os.Environment;
-import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.preference.PreferenceManager;
 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.service.aidl.IChat;
-import com.beem.project.beem.service.aidl.IChatManager;
-import com.beem.project.beem.service.aidl.IChatManagerListener;
-import com.beem.project.beem.service.aidl.IMessageListener;
 import com.beem.project.beem.service.aidl.IRoster;
 
 /**
  * An adapter for smack's ChatManager. This class provides functionnality to handle chats.
  * @author darisk
  */
-public class BeemChatManager extends IChatManager.Stub {
+public class BeemChatManager {
 
     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;
 
     /**
@@ -96,53 +91,31 @@
 	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;
+    public void sendMessage(String to, Message message) {
+	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
+	Chat chat = mAdaptee.createChat(to, mChatListener);
+	try {
+	    chat.sendMessage(send);
+//             mMessages.add(message);
+	} catch (XMPPException e) {
+	    Log.e(TAG, "Error while sending message", e);
 	}
-	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;
+//         String state = Environment.getExternalStorageState();
+//         if (mIsHistory && Environment.MEDIA_MOUNTED.equals(state))
+//             saveHistory(message, mAccountUser);
     }
 
     /**
      * {@inheritDoc}
      */
-    @Override
+//     @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);
@@ -155,7 +128,7 @@
     /**
      * {@inheritDoc}
      */
-    @Override
+//     @Override
     public void deleteChatNotification(IChat chat) {
 	try {
 	    mService.deleteNotification(chat.getParticipant().getJID().hashCode());
@@ -165,38 +138,6 @@
     }
 
     /**
-     * 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.
@@ -217,19 +158,10 @@
     }
 
     /**
-     * {@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 {
+    private class ChatListener implements ChatManagerListener, MessageListener {
 
 	/**
 	 * Constructor.
@@ -242,22 +174,8 @@
 	 */
 	@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);
-	    }
+	    chat.addMessageListener(this);
+	    Log.d(TAG, "Chat " + chat.toString() + " created locally " + locally + " with " + chat.getParticipant());
 	}
 
 	/**
@@ -299,26 +217,15 @@
 	    }
 	}
 
-	/**
-	 * {@inheritDoc}
-	 */
 	@Override
-	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());
-	    }
+	public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) {
+	    Intent intent = new Intent(BeemIntent.ACTION_MESSAGE_RECEIVED);
+	    intent.putExtra(BeemIntent.EXTRA_MESSAGE, new Message(message));
+	    mService.sendOrderedBroadcast(intent, null);
 	}
 
-	@Override
-	public void stateChanged(final IChat chat) {
-	}
+//         @Override
+//         public void stateChanged(final IChat chat) {
+//         }
     }
 }
--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Thu Jun 02 01:28:40 2011 +0200
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Sat Jun 04 21:50:56 2011 +0200
@@ -43,11 +43,8 @@
 */
 package com.beem.project.beem.service;
 
-import org.jivesoftware.smack.Chat;
-import org.jivesoftware.smack.ChatManager;
 import org.jivesoftware.smack.ConnectionConfiguration;
 import org.jivesoftware.smack.ConnectionListener;
-import org.jivesoftware.smack.MessageListener;
 import org.jivesoftware.smack.PacketListener;
 import org.jivesoftware.smack.PrivacyListManager;
 import org.jivesoftware.smack.Roster;
@@ -74,6 +71,7 @@
 import java.util.Iterator;
 import java.util.List;
 
+import com.beem.project.beem.BeemIntent;
 import com.beem.project.beem.BeemService;
 import com.beem.project.beem.R;
 import com.beem.project.beem.BeemApplication;
@@ -107,10 +105,9 @@
     private static final int SMACK_PRIORITY_MAX = 128;
     private static final String TAG = "XMPPConnectionAdapter";
     private final XMPPConnection mAdaptee;
-    private ChatManager mChatManager;
+    private BeemChatManager mChatManager;
     private final String mLogin;
     private final String mPassword;
-    private final OnMessageListener mMsgListener = new OnMessageListener();
     private String mResource;
     private String mErrorMsg;
     private RosterAdapter mRoster;
@@ -250,8 +247,7 @@
 	    mAdaptee.login(mLogin, mPassword, mResource);
 	    mUserInfo = new UserInfo(mAdaptee.getUser());
 
-//             mChatManager = new BeemChatManager(mAdaptee.getChatManager(), mService);
-	    mChatManager = mAdaptee.getChatManager();
+	    mChatManager = new BeemChatManager(mAdaptee.getChatManager(), mService);
 	    //nikita: I commented this line because of the logs provided in http://www.beem-project.com/issues/321
 	    //Also, since the privacylistmanager isn't finished and used, it will be safer to not initialize it
 	    //mPrivacyListManager = new PrivacyListManagerAdapter(PrivacyListManager.getInstanceFor(mAdaptee));
@@ -486,16 +482,13 @@
     }
 
     private void sendMessage(Bundle b) {
-	String jid = b.getString(com.beem.project.beem.Intent.EXTRA_JID);
-	CharSequence msg = b.getCharSequence(Intent.EXTRA_TEXT);
-	if (jid == null || msg == null)
+	String jid = b.getString(BeemIntent.EXTRA_JID);
+	Message msg = b.getParcelable(BeemIntent.EXTRA_MESSAGE);
+	if (jid == null || msg == null) {
+	    Log.w(TAG, "Ignoring message : No recipient jid or message");
 	    return;
-	Chat chat = mChatManager.createChat(jid, mMsgListener);
-	try {
-	    chat.sendMessage(msg.toString());
-	} catch (XMPPException e) {
-	    Log.e(TAG, "Error while sending message", e);
 	}
+	mChatManager.sendMessage(jid, msg);
     }
 
     /**
@@ -785,16 +778,4 @@
 	}
     }
 
-    private class OnMessageListener implements MessageListener {
-	
-	@Override
-	public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) {
-	    // TODO
-//             Intent intent = new Intent(ACTION_MSG_RECEIVED);
-//             intent.putExtra(EXTRA_MSG, message);
-//             Log.d(TAG, "Notify " + intent.toString());
-//             mService.sendOrderedBroadcast(intent, null);
-	}
-    }
-
 }
--- a/src/com/beem/project/beem/ui/Chat.java	Thu Jun 02 01:28:40 2011 +0200
+++ b/src/com/beem/project/beem/ui/Chat.java	Sat Jun 04 21:50:56 2011 +0200
@@ -57,6 +57,8 @@
 
 import android.app.Activity;
 import android.app.Dialog;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -94,6 +96,7 @@
 
 import com.beem.project.beem.R;
 import com.beem.project.beem.BeemApplication;
+import com.beem.project.beem.BeemIntent;
 import com.beem.project.beem.providers.AvatarProvider;
 import com.beem.project.beem.service.Contact;
 import com.beem.project.beem.service.Message;
@@ -102,7 +105,6 @@
 import com.beem.project.beem.service.aidl.IChat;
 import com.beem.project.beem.service.aidl.IChatManager;
 import com.beem.project.beem.service.aidl.IChatManagerListener;
-import com.beem.project.beem.service.aidl.IMessageListener;
 import com.beem.project.beem.service.aidl.IRoster;
 import com.beem.project.beem.service.aidl.IXmppFacade;
 import com.beem.project.beem.ui.dialogs.builders.ChatList;
@@ -139,7 +141,7 @@
 
     private IChat mChat;
     private IChatManager mChatManager;
-    private final IMessageListener mMessageListener = new OnMessageListener();
+    private final MessageReceiver mMessageReceiver = new MessageReceiver();
     private final IChatManagerListener mChatManagerListener = new ChatManagerListener();
     private MessagesListAdapter mMessagesListAdapter = new MessagesListAdapter();
 
@@ -195,13 +197,17 @@
     }
 
     @Override
-    protected void onResume() {
-	super.onResume();
+    protected void onStart() {
+	super.onStart();
 	mContact = new Contact(getIntent().getData());
-	if (!mBinded) {
-	    bindService(SERVICE_INTENT, mConn, BIND_AUTO_CREATE);
-	    mBinded = true;
-	}
+	IntentFilter filter = new IntentFilter(BeemIntent.ACTION_MESSAGE_RECEIVED);
+	registerReceiver(mMessageReceiver, filter);
+    }
+
+    @Override
+    protected void onStop() {
+	super.onStop();
+	unregisterReceiver(mMessageReceiver);
     }
 
     /**
@@ -222,7 +228,6 @@
 	try {
 	    if (mChat != null) {
 		mChat.setOpen(false);
-		mChat.removeMessageListener(mMessageListener);
 	    }
 	    if (mRoster != null)
 		mRoster.removeRosterListener(mBeemRosterListener);
@@ -248,6 +253,7 @@
     protected void onNewIntent(Intent intent) {
 	super.onNewIntent(intent);
 	setIntent(intent);
+	mContact = new Contact(getIntent().getData());
     }
 
     /**
@@ -320,12 +326,10 @@
     private void changeCurrentChat(Contact contact) throws RemoteException {
 	if (mChat != null) {
 	    mChat.setOpen(false);
-	    mChat.removeMessageListener(mMessageListener);
 	}
 	mChat = mChatManager.getChat(contact);
 	if (mChat != null) {
 	    mChat.setOpen(true);
-	    mChat.addMessageListener(mMessageListener);
 	    mChatManager.deleteChatNotification(mChat);
 	}
 	mContact = mRoster.getContact(contact.getJID());
@@ -490,76 +494,78 @@
     /**
      * {@inheritDoc}.
      */
-    private class OnMessageListener extends IMessageListener.Stub {
+    private class MessageReceiver extends BroadcastReceiver {
 
 	/**
 	 * Constructor.
 	 */
-	public OnMessageListener() {
+	public MessageReceiver() {
 	}
 
 	/**
 	 * {@inheritDoc}.
 	 */
 	@Override
-	public void processMessage(IChat chat, final Message msg) throws RemoteException {
+	public void onReceive(final Context context, final Intent intent) {
+	    String intentAction = intent.getAction();
+	    if (!intentAction.equals(BeemIntent.ACTION_MESSAGE_RECEIVED)) {
+		Log.d(TAG, "Bad Intent received : " + intent.toString());
+		return;
+	    }
+	    final Message msg = intent.getParcelableExtra(BeemIntent.EXTRA_MESSAGE);
+
 	    final String fromBareJid = StringUtils.parseBareAddress(msg.getFrom());
 
 	    if (mContact.getJID().equals(fromBareJid)) {
-		mHandler.post(new Runnable() {
-
-		    @Override
-		    public void run() {
-			if (msg.getType() == Message.MSG_TYPE_ERROR) {
-			    mListMessages.add(new MessageText(fromBareJid, mContact.getName(),
+		if (msg.getType() == Message.MSG_TYPE_ERROR) {
+		    mListMessages.add(new MessageText(fromBareJid, mContact.getName(),
 				msg.getBody(), true, msg.getTimestamp()));
-			    mMessagesListAdapter.notifyDataSetChanged();
-			} else if (msg.getBody() != null) {
-			    MessageText lastMessage = null;
-			    if (mListMessages.size() != 0)
-				lastMessage = mListMessages.get(mListMessages.size() - 1);
+		    mMessagesListAdapter.notifyDataSetChanged();
+		} else if (msg.getBody() != null) {
+		    MessageText lastMessage = null;
+		    if (mListMessages.size() != 0)
+			lastMessage = mListMessages.get(mListMessages.size() - 1);
 
-			    if (lastMessage != null && lastMessage.getBareJid().equals(fromBareJid)) {
-				lastMessage.setMessage(lastMessage.getMessage().concat("\n" + msg.getBody()));
-				lastMessage.setTimestamp(msg.getTimestamp());
-				mListMessages.set(mListMessages.size() - 1, lastMessage);
-			    } else if (msg.getBody() != null)
-				mListMessages.add(new MessageText(fromBareJid, mContact.getName(),
+		    if (lastMessage != null && lastMessage.getBareJid().equals(fromBareJid)) {
+			lastMessage.setMessage(lastMessage.getMessage().concat("\n" + msg.getBody()));
+			lastMessage.setTimestamp(msg.getTimestamp());
+			mListMessages.set(mListMessages.size() - 1, lastMessage);
+		    } else if (msg.getBody() != null)
+			mListMessages.add(new MessageText(fromBareJid, mContact.getName(),
 				    msg.getBody(), false, msg.getTimestamp()));
-			    mMessagesListAdapter.notifyDataSetChanged();
-			}
-		    }
-		});
+		    mMessagesListAdapter.notifyDataSetChanged();
+		}
+		abortBroadcast();
 	    }
 	}
 
 	/**
 	 * {@inheritDoc}.
 	 */
-	@Override
-	public void stateChanged(IChat chat) throws RemoteException {
-	    final String state = chat.getState();
-	    mHandler.post(new Runnable() {
-		@Override
-		public void run() {
-		    String text = null;
-		    if ("active".equals(state)) {
-			text = Chat.this.getString(R.string.chat_state_active);
-		    } else if ("composing".equals(state)) {
-			text = Chat.this.getString(R.string.chat_state_composing);
-		    } else if ("gone".equals(state)) {
-			text = Chat.this.getString(R.string.chat_state_gone);
-		    } else if ("inactive".equals(state)) {
-			text = Chat.this.getString(R.string.chat_state_inactive);
-		    } else if ("paused".equals(state)) {
-			text = Chat.this.getString(R.string.chat_state_active);
-		    }
-		    if (!mCompact)
-			mContactChatState.setText(text);
-		}
-	    });
+//         @Override
+//         public void stateChanged(IChat chat) throws RemoteException {
+//             final String state = chat.getState();
+//             mHandler.post(new Runnable() {
+//                 @Override
+//                 public void run() {
+//                     String text = null;
+//                     if ("active".equals(state)) {
+//                         text = Chat.this.getString(R.string.chat_state_active);
+//                     } else if ("composing".equals(state)) {
+//                         text = Chat.this.getString(R.string.chat_state_composing);
+//                     } else if ("gone".equals(state)) {
+//                         text = Chat.this.getString(R.string.chat_state_gone);
+//                     } else if ("inactive".equals(state)) {
+//                         text = Chat.this.getString(R.string.chat_state_inactive);
+//                     } else if ("paused".equals(state)) {
+//                         text = Chat.this.getString(R.string.chat_state_active);
+//                     }
+//                     if (!mCompact)
+//                         mContactChatState.setText(text);
+//                 }
+//             });
 
-	}
+//         }
     }
 
     /**
@@ -883,23 +889,12 @@
 	final String inputContent = mInputField.getText().toString();
 
 	if (!"".equals(inputContent)) {
-//             Message msgToSend = new Message(mContact.getJIDWithRes(), Message.MSG_TYPE_CHAT);
-//             msgToSend.setBody(inputContent);
-
-//             try {
-//                 if (mChat == null) {
-//                     mChat = mChatManager.createChat(mContact, mMessageListener);
-//                     mChat.setOpen(true);
-//                 }
-//                 mChat.sendMessage(msgToSend);
-//             } catch (RemoteException e) {
-//                 Log.e(TAG, e.getMessage());
-//             }
-
-	    Intent i = new Intent(com.beem.project.beem.Intent.ACTION_SEND_MSG);
-	    i.putExtra(com.beem.project.beem.Intent.EXTRA_JID, "");
-	    i.putExtra(com.beem.project.beem.Intent.EXTRA_ACCOUNT, "");
-	    i.putExtra(Intent.EXTRA_TEXT, inputContent);
+	    Intent i = new Intent(BeemIntent.ACTION_SEND_MESSAGE);
+	    i.putExtra(BeemIntent.EXTRA_JID, mContact.getJIDWithRes());
+	    i.putExtra(BeemIntent.EXTRA_ACCOUNT, "");
+	    Message msgToSend = new Message(mContact.getJIDWithRes(), Message.MSG_TYPE_CHAT);
+	    msgToSend.setBody(inputContent);
+	    i.putExtra(BeemIntent.EXTRA_MESSAGE, msgToSend);
 	    startService(i);
 	    final String self = getString(R.string.chat_self);
 	    MessageText lastMessage = null;
@@ -938,11 +933,9 @@
 		    // This should not be happened but to be sure
 		    if (mChat != null) {
 			mChat.setOpen(false);
-			mChat.removeMessageListener(mMessageListener);
 		    }
 		    mChat = chat;
 		    mChat.setOpen(true);
-		    mChat.addMessageListener(mMessageListener);
 		    mChatManager.deleteChatNotification(mChat);
 		}
 	    } catch (RemoteException ex) {
--- a/src/com/beem/project/beem/ui/LoginAnim.java	Thu Jun 02 01:28:40 2011 +0200
+++ b/src/com/beem/project/beem/ui/LoginAnim.java	Sat Jun 04 21:50:56 2011 +0200
@@ -67,6 +67,7 @@
 
 import com.beem.project.beem.R;
 import com.beem.project.beem.BeemApplication;
+import com.beem.project.beem.BeemIntent;
 import com.beem.project.beem.service.LoginAsyncTask;
 import com.beem.project.beem.service.aidl.IXmppFacade;
 
@@ -114,10 +115,10 @@
 	mReceiver = new BroadcastReceiver() {
 	    public void onReceive(Context ctx, Intent intent) {
 		String action = intent.getAction();
-	        if (com.beem.project.beem.Intent.ACTION_CONNECTED.equals(action)) {
+	        if (BeemIntent.ACTION_CONNECTED.equals(action)) {
 		    LoginAnim.this.setResult(Activity.RESULT_OK);
 		    finish();
-		} else if (com.beem.project.beem.Intent.ACTION_DISCONNECTED.equals(action)) {
+		} else if (BeemIntent.ACTION_DISCONNECTED.equals(action)) {
 		    LoginAnim.this.setResult(Activity.RESULT_CANCELED);
 		    finish();
 		}
@@ -134,10 +135,10 @@
 	super.onStart();
 	mLogo.startAnimation(mRotateAnim);
 	String account = mSettings.getString(BeemApplication.ACCOUNT_USERNAME_KEY, "").trim();
-	Intent intent = new Intent(com.beem.project.beem.Intent.ACTION_CONNECT);
-	intent.putExtra(com.beem.project.beem.Intent.EXTRA_ACCOUNT, account);
-	IntentFilter filter = new IntentFilter(com.beem.project.beem.Intent.ACTION_CONNECTED);
-	filter.addAction(com.beem.project.beem.Intent.ACTION_DISCONNECTED);
+	Intent intent = new Intent(BeemIntent.ACTION_CONNECT);
+	intent.putExtra(BeemIntent.EXTRA_ACCOUNT, account);
+	IntentFilter filter = new IntentFilter(BeemIntent.ACTION_CONNECTED);
+	filter.addAction(BeemIntent.ACTION_DISCONNECTED);
 	registerReceiver(mReceiver, filter);
 	startService(intent);
 //         if (mTask == null)
--- a/src/com/beem/project/beem/utils/BeemBroadcastReceiver.java	Thu Jun 02 01:28:40 2011 +0200
+++ b/src/com/beem/project/beem/utils/BeemBroadcastReceiver.java	Sat Jun 04 21:50:56 2011 +0200
@@ -43,15 +43,32 @@
 */
 package com.beem.project.beem.utils;
 
+import org.jivesoftware.smack.util.StringUtils;
+
 import android.app.Activity;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.net.ConnectivityManager;
 import android.widget.Toast;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+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.service.Contact;
+import com.beem.project.beem.service.Message;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.net.Uri;
 
 /**
  * Manage broadcast disconnect intent.
@@ -88,6 +105,49 @@
 		    Toast.LENGTH_SHORT).show();
 		context.stopService(new Intent(context, BeemService.class));
 	    }
+	} else if (intentAction.equals(BeemIntent.ACTION_MESSAGE_RECEIVED)) {
+	    Message msg = intent.getParcelableExtra(BeemIntent.EXTRA_MESSAGE);
+	    onMessageReceived(context, msg);
 	}
     }
+
+    private void onMessageReceived(final Context context, Message msg) {
+	NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+	CharSequence tickerText = msg.getFrom();
+	Notification notification = new Notification(android.R.drawable.stat_notify_chat, tickerText, System
+		.currentTimeMillis());
+	notification.flags = Notification.FLAG_AUTO_CANCEL;
+	notification.setLatestEventInfo(context, tickerText, context
+		.getString(R.string.BeemChatManagerNewMessage), makeChatIntent(context, msg.getFrom()));
+	String bareJid = StringUtils.parseBareAddress(msg.getFrom());
+	sendNotification(context, bareJid.hashCode(), notification);
+	Log.d("BR", "had notification : " + bareJid);
+//         abortBroadcast();
+    }
+
+    /**
+     * 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(final Context context, String jid) {
+	Intent chatIntent = new Intent(context, 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);
+	    chatIntent.setData(new Contact(jid).toUri());
+	PendingIntent contentIntent = PendingIntent.getActivity(context, 0, chatIntent,
+		PendingIntent.FLAG_UPDATE_CURRENT);
+	return contentIntent;
+    }
+
+    public static void sendNotification(Context context, int id, Notification notif) {
+	SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
+	if (settings.getBoolean(BeemApplication.NOTIFICATION_VIBRATE_KEY, true))
+	    notif.defaults |= Notification.DEFAULT_VIBRATE; notif.defaults |= Notification.DEFAULT_LIGHTS;
+	String ringtoneStr = settings.getString(BeemApplication.NOTIFICATION_SOUND_KEY, "");
+	notif.sound = Uri.parse(ringtoneStr);
+	NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+	notificationManager.notify(id, notif);
+    }
+
 }