Intégration de l´activité Chat à la place de l´activité SendIM
Amélioration de l´activité Chat:
- Skin
- Meilleure gestion des URL et des messages de status
Modifications très légères de skin sur les activités ContactList
et ChangeStatus.
package com.beem.project.beem.service;
import java.util.HashMap;
import java.util.Map;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ChatManagerListener;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.ChatState;
import org.jivesoftware.smackx.ChatStateListener;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
import com.beem.project.beem.BeemService;
import com.beem.project.beem.R;
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;
/**
* 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}
*/
@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();
}
/**
* Set a notification of a new chat in android.
* @param chat The chat to access by the notification
*/
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);
}
}
/**
* {@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) {
// The RemoteCallbackList will take care of removing the
// dead listeners.
Log.w(TAG, "Error while triggering remote connection listeners", e);
}
}
/**
* {@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, "Error while changing chat state", e);
}
}
mRemoteMessageListeners.finishBroadcast();
}
}
/**
* 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 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);
}
/**
* 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);
}
// 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;
}
/**
* {@inheritDoc}
*/
@Override
public void removeChatCreationListener(IChatManagerListener listener) throws RemoteException {
mRemoteChatCreationListeners.unregister(listener);
}
}