Save of the work on activity Chat.
authordasilvj
Fri, 06 Nov 2009 17:51:22 +0100
changeset 493 56af5554a081
parent 490 daccdb7f4237
child 494 dd9ad5fec728
Save of the work on activity Chat.
res/layout/chat.xml
src/com/beem/project/beem/BeemService.java
src/com/beem/project/beem/service/Contact.java
src/com/beem/project/beem/ui/Chat.java
src/com/beem/project/beem/ui/ContactList.java
src/com/beem/project/beem/ui/Login.java
src/com/beem/project/beem/ui/SendIM.java
--- a/res/layout/chat.xml	Fri Nov 06 14:09:30 2009 +0100
+++ b/res/layout/chat.xml	Fri Nov 06 17:51:22 2009 +0100
@@ -1,42 +1,34 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
-  xmlns:android="http://schemas.android.com/apk/res/android"
-  android:layout_width="wrap_content"
-  android:layout_height="wrap_content"
-  android:orientation="vertical">
-  <LinearLayout
-  	android:layout_width="fill_parent"
-  	android:layout_height="wrap_content">
-  	<ImageView android:id="@+id/chat_contact_status_icon"
-		android:adjustViewBounds="true" android:maxWidth="15dip"
-		android:maxHeight="12px" android:layout_width="wrap_content"
-		android:layout_height="wrap_content" android:gravity="center_vertical" />
-	<LinearLayout
-		android:orientation="vertical"
-		android:layout_width="wrap_content"
-		android:layout_height="wrap_content">
-		<TextView android:id="@+id/chat_contact_name"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="wrap_content" android:layout_height="wrap_content"
+	android:orientation="vertical">
+	<LinearLayout android:layout_width="fill_parent"
+		android:layout_height="wrap_content" android:gravity="center_vertical"
+		android:background="#222222" android:padding="4px">
+		<ImageView android:id="@+id/chat_contact_status_icon"
+			android:adjustViewBounds="true" android:layout_width="wrap_content"
+			android:layout_height="wrap_content" android:gravity="center_vertical" />
+		<LinearLayout android:orientation="vertical"
 			android:layout_width="fill_parent" android:layout_height="wrap_content"
-			android:lines="1" android:singleLine="true" android:paddingLeft="15sp"
-			android:textSize="14sp" android:textStyle="bold" android:textColor="#FFFFFF" />
-		<TextView android:id="@+id/chat_contact_status_msg"
-			android:layout_width="fill_parent" android:layout_height="wrap_content"
-			android:lines="1"
-			android:paddingLeft="15sp"
-			android:autoLink="all" android:textSize="12sp" android:textColor="#FFFFFF" />
+			android:paddingLeft="15sp">
+			<TextView android:id="@+id/chat_contact_name"
+				android:layout_width="fill_parent" android:layout_height="wrap_content"
+				android:lines="1" android:singleLine="true" android:textSize="14sp"
+				android:textStyle="bold" android:textColor="#FFFFFF" />
+			<TextView android:id="@+id/chat_contact_status_msg"
+				android:layout_width="fill_parent" android:layout_height="wrap_content"
+				android:autoLink="all" android:textSize="12sp" android:textColor="#FFFFFF" />
+		</LinearLayout>
 	</LinearLayout>
-  </LinearLayout>
-  <LinearLayout
-  	android:layout_width="fill_parent"
-  	android:layout_height="wrap_content">
-  </LinearLayout>
-  <LinearLayout
-  	android:layout_width="fill_parent"
-  	android:layout_height="wrap_content">
-	<EditText android:id="@+id/chat_input"
-		android:layout_width="fill_parent"
-		android:layout_height="wrap_content"
-		android:inputType="textShortMessage|textAutoComplete" android:imeOptions="actionSend"
-		android:cursorVisible="false" android:hint="@string/chat_input_default_value" />
-  </LinearLayout>
+	<View android:layout_width="fill_parent" android:layout_height="2dp"
+		android:fadingEdge="horizontal" android:background="#555555" />
+	<ListView android:id="@+id/chat_messages"
+		android:layout_width="fill_parent" android:layout_height="fill_parent" />
+	<RelativeLayout android:layout_width="fill_parent" android:layout_height="wrap_content">
+		<EditText android:id="@+id/chat_input" android:layout_width="fill_parent"
+			android:layout_height="wrap_content" android:inputType="textShortMessage|textAutoComplete"
+			android:imeOptions="actionSend" android:cursorVisible="false"
+			android:hint="@string/chat_input_default_value"
+			android:layout_alignParentBottom="true" />
+	</RelativeLayout>
 </LinearLayout>
--- a/src/com/beem/project/beem/BeemService.java	Fri Nov 06 14:09:30 2009 +0100
+++ b/src/com/beem/project/beem/BeemService.java	Fri Nov 06 17:51:22 2009 +0100
@@ -95,13 +95,13 @@
      */
     @Override
     public IBinder onBind(Intent intent) {
-	Log.e("BEEMSERVICE", "ONBIND()");
+	Log.d("BEEMSERVICE", "ONBIND()");
 	return mBind;
     }
 
     @Override
     public boolean onUnbind(Intent intent) {
-	Log.e("BEEMSERVICE", "ONUNBIND()");
+	Log.d("BEEMSERVICE", "ONUNBIND()");
 	if (!mConnection.getAdaptee().isConnected()) {
 	    this.stopSelf();
 	}
--- a/src/com/beem/project/beem/service/Contact.java	Fri Nov 06 14:09:30 2009 +0100
+++ b/src/com/beem/project/beem/service/Contact.java	Fri Nov 06 17:51:22 2009 +0100
@@ -6,12 +6,15 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+
 import org.jivesoftware.smack.RosterGroup;
 import org.jivesoftware.smack.packet.Presence;
 import org.jivesoftware.smack.util.StringUtils;
+
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
+
 import com.beem.project.beem.utils.Status;
 
 /**
--- a/src/com/beem/project/beem/ui/Chat.java	Fri Nov 06 14:09:30 2009 +0100
+++ b/src/com/beem/project/beem/ui/Chat.java	Fri Nov 06 17:51:22 2009 +0100
@@ -1,30 +1,50 @@
 package com.beem.project.beem.ui;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+
+import org.jivesoftware.smack.util.StringUtils;
+import org.jivesoftware.smackx.ChatState;
 
 import android.app.Activity;
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.text.util.Linkify;
 import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
 import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ListView;
 import android.widget.TextView;
 
+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 com.beem.project.beem.service.PresenceAdapter;
 import com.beem.project.beem.service.aidl.IBeemRosterListener;
 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.utils.BeemBroadcastReceiver;
+import com.beem.project.beem.utils.Status;
 
 public class Chat extends Activity {
 
@@ -34,17 +54,28 @@
 	SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
     }
     
-    private Handler _handler = new Handler();
+    private Handler mHandler = new Handler();
     
-    private IRoster _roster;
-    private Contact _contact;
+    private IRoster mRoster;
+    private Contact mContact;
 
-    private TextView _contactNameTextView;
-    private TextView _contactStatusMsgTextView;
-    private EditText _input;
+    private TextView mContactNameTextView;
+    private TextView mContactStatusMsgTextView;
+    private ImageView mContactStatusIcon;
+    private ListView mMessagesListView;
+    private EditText mInputField;
+    private Map<Integer, Bitmap> mStatusIconsMap = new HashMap<Integer, Bitmap>();
+    
+    private List<MessageText> mListMessages = new ArrayList<MessageText>();
     
-    private final ServiceConnection _conn = new BeemServiceConnection();
-    private BeemBroadcastReceiver _broadcastReceiver;
+    private IChat mChat;
+    private IChatManager mChatManager;
+    private IChatManagerListener mChatManagerListener;
+    private IMessageListener mMessageListener;
+    private MessagesListAdapter mMessagesListAdapter;
+    
+    private final ServiceConnection mConn = new BeemServiceConnection();
+    private BeemBroadcastReceiver mBroadcastReceiver;
     
     
     /**
@@ -60,13 +91,30 @@
     protected void onCreate(Bundle savedBundle) {
 	super.onCreate(savedBundle);
 	
-	_contactNameTextView = (TextView) findViewById(R.id.chat_contact_name);
-	_contactStatusMsgTextView = (TextView) findViewById(R.id.chat_contact_status_msg);
-	
+	Log.v(TAG, "BEGIN onCreate.");
 	setContentView(R.layout.chat);
+	mMessagesListAdapter = new MessagesListAdapter(this);
 	
-	_broadcastReceiver = new BeemBroadcastReceiver(_conn);
-	this.registerReceiver(_broadcastReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));
+	mHandler = new Handler();
+	
+	// Listeners
+	mMessageListener = new OnMessageListener();
+	mChatManagerListener = new OnChatManagerListener();
+
+	mBroadcastReceiver = new BeemBroadcastReceiver(mConn);
+	this.registerReceiver(mBroadcastReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));
+	
+	// UI
+	mContactNameTextView = (TextView) findViewById(R.id.chat_contact_name);
+	mContactStatusMsgTextView = (TextView) findViewById(R.id.chat_contact_status_msg);
+	mContactStatusIcon = (ImageView) findViewById(R.id.chat_contact_status_icon);
+	mMessagesListView = (ListView) findViewById(R.id.chat_messages);
+	mMessagesListView.setAdapter(mMessagesListAdapter);
+	mInputField = (EditText) findViewById(R.id.chat_input);
+	
+	prepareIconsStatus();
+	
+	Log.v(TAG, "END onCreate.");
     }
     
     /**
@@ -74,7 +122,17 @@
      */
     protected void onDestroy() {
 	super.onDestroy();
-	this.unregisterReceiver(_broadcastReceiver);
+	
+	Log.v(TAG, "BEGIN onDestroy.");
+	this.unregisterReceiver(mBroadcastReceiver);
+	if (mChatManager != null) {
+	    try {
+		mChatManager.removeChatCreationListener(mChatManagerListener);
+	    } catch (RemoteException e) {
+		Log.e(TAG, e.getMessage());
+	    }
+	}
+	Log.v(TAG, "END onDestroy.");
     }
     
     /**
@@ -82,6 +140,10 @@
      */
     protected void onStart() {
 	super.onStart();
+	
+	Log.v(TAG, "BEGIN onStart.");
+	bindService(new Intent(this, BeemService.class), mConn, BIND_AUTO_CREATE);
+	Log.v(TAG, "END onStart.");
     }
     
     /**
@@ -89,12 +151,45 @@
      */
     protected void onStop() {	
 	super.onStop();
+	
+	Log.v(TAG, "BEGIN onStop.");
+	if (mChat != null) {
+	    try {
+		mChat.setOpen(false);
+	    } catch (RemoteException e) {
+		Log.e(TAG, e.getMessage());
+	    }
+	}
+	if (mBroadcastReceiver.isBinded()) {
+	    unbindService(mConn);
+	}
+	Log.v(TAG, "END onStop.");
     }
     
+    /**
+     * {@inheritDoc}.
+     */
+    protected void onResume() {
+	super.onResume();
+    }
+  
+    /**
+     * {@inheritDoc}.
+     */
+    protected void onPause() {
+	super.onPause();
+    }
+    
+    /**
+     * {@inheritDoc}.
+     */
     protected void onNewIntent(Intent intent) {
 	super.onNewIntent(intent);
 	
-	_contact = new Contact(intent.getData());
+	Log.v(TAG, "BEGIN onNewIntent.");
+	mContact = new Contact(intent.getData());
+	updateContactInformations();
+	Log.v(TAG, "END onNewIntent.");
     }
     
     /**
@@ -104,23 +199,43 @@
      */
     private final class BeemServiceConnection implements ServiceConnection {
 	
-	private IXmppFacade _xmppFacade;
+	private IXmppFacade mXmppFacade;
+	private final BeemRosterListener mBeemRosterListener = new BeemRosterListener();
 
 	@Override
 	public void onServiceConnected(ComponentName name, IBinder service) {
-	    _xmppFacade = IXmppFacade.Stub.asInterface(service);
-	    _broadcastReceiver.setBinded(true);
+	    Log.v(TAG, "BEGIN onServiceConnected.");
+	    mXmppFacade = IXmppFacade.Stub.asInterface(service);
+	    mBroadcastReceiver.setBinded(true);
 	    try {
-		_roster = _xmppFacade.getRoster();
+		mChatManager = mXmppFacade.getChatManager();
+		
+		mRoster = mXmppFacade.getRoster();
+		mRoster.addRosterListener(mBeemRosterListener);
+		
+		mChat = mChatManager.createChat((mContact = new Contact(getIntent().getData())), mMessageListener);
+		mChat.setOpen(true);
+		mChatManager.deleteChatNotification(mChat);
+		
+		updateContactInformations();
+		updateContactStatusIcon();
 	    } catch (RemoteException e) {
 		Log.e(TAG, e.getMessage());
 	    }
+	    Log.v(TAG, "END onServiceConnected.");
 	}
 	
 	@Override
 	public void onServiceDisconnected(ComponentName name) {
-	    _xmppFacade = null;
-	    _broadcastReceiver.setBinded(false);
+	    Log.v(TAG, "BEGIN onServiceDisconnected.");
+	    mXmppFacade = null;
+	    mBroadcastReceiver.setBinded(false);
+	    try {
+		mRoster.removeRosterListener(mBeemRosterListener);
+	    } catch (RemoteException e) {
+		Log.e(TAG, e.getMessage());
+	    }
+	    Log.v(TAG, "END onServiceDisconnected.");
 	}
     }
     
@@ -154,8 +269,17 @@
 
 	@Override
 	public void onPresenceChanged(PresenceAdapter presence) throws RemoteException {
-	    // TODO Auto-generated method stub
-	    
+	    Log.v(TAG, "BEGIN onPresenceChanged.");
+	    if (mContact.getJID().equals(StringUtils.parseBareAddress(presence.getFrom()))) {
+		mHandler.post(new Runnable() {
+		    @Override
+		    public void run() {
+			updateContactInformations();
+			updateContactStatusIcon();
+		    }
+		});
+	    }
+	    Log.v(TAG, "END onPresenceChanged.");
 	}
     }
     
@@ -167,14 +291,199 @@
     private class OnMessageListener extends IMessageListener.Stub {
 
 	@Override
-	public void processMessage(IChat chat, Message msg) throws RemoteException {
-	    // TODO Auto-generated method stub
+	public void processMessage(IChat chat, final Message msg) throws RemoteException {
+	    Log.v(TAG, "BEGIN processMessage.");
+	    mHandler.post(new Runnable() {
+
+		@Override
+		public void run() {
+		    if (msg.getBody() != null && msg.getType() != Message.MSG_TYPE_ERROR) {
+			mListMessages.add(new MessageText(msg.getFrom(), msg.getBody()));
+			mMessagesListAdapter.notifyDataSetChanged();
+		    }
+		}
+	    });
+	    Log.v(TAG, "END processMessage.");
 	}
 
 	@Override
 	public void stateChanged(IChat chat) throws RemoteException {
-	    // TODO Auto-generated method stub
-	    
+	    Log.v(TAG, "BEGIN stateChanged.");
+	    mHandler.post(new Runnable() {
+		
+		@Override
+		public void run() {
+		}
+	    });
+	    Log.v(TAG, "END stateChanged.");
+	}
+
+    }
+    
+    /**
+     * 
+     * @author Jamu
+     *
+     */
+    private class OnChatManagerListener extends IChatManagerListener.Stub {
+	/**
+	 * Constructor.
+	 */
+	public OnChatManagerListener() {
+	    Log.v(TAG, "OnChatManagerListener constructor.");
+	}
+	
+	@Override
+	public void chatCreated(IChat chat, boolean locally) throws RemoteException {
+	    Log.i(TAG, "Chat has been created.");
 	}
     }
+    
+    /**
+     * Update the contact informations.
+     *
+     */
+    private void updateContactInformations() {
+	Log.v(TAG, "BEGIN updateContactInformations.");
+	// Check for a contact name update
+	if (!(mContactNameTextView.getText().toString().equals(mContact.getName())))
+	    mContactNameTextView.setText(mContact.getName());
+	
+	// Check for a contact status message update
+	if (!(mContactStatusMsgTextView.getText().toString().equals(mContact.getMsgState()))) {
+	    Log.d(TAG, "Setting status message - " + mContact.getMsgState());
+	    if (mContact.getMsgState() == null)
+		mContactStatusMsgTextView.setText("Message de status de test de la mort tres tres long, voir meme trop long!");
+	    else
+		mContactStatusMsgTextView.setText(mContact.getMsgState());
+	    Linkify.addLinks(mContactStatusMsgTextView, Linkify.WEB_URLS);
+	}
+	Log.v(TAG, "END updateContactInformations.");
+    }
+    
+    /**
+     * Update the contact status icon.
+     */
+    private void updateContactStatusIcon() {
+	Log.v(TAG, "BEGIN updateContactStatusIcon.");
+	mContactStatusIcon.setImageBitmap(mStatusIconsMap.get(mContact.getStatus()));
+	Log.v(TAG, "END updateContactStatusIcon.");
+    }
+    
+    /**
+     * Prepare the status icons map.
+     */
+    private void prepareIconsStatus() {
+	mStatusIconsMap.put(Status.CONTACT_STATUS_AVAILABLE, BitmapFactory.decodeResource(getResources(), R.drawable.status_available));
+	mStatusIconsMap.put(Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT, BitmapFactory.decodeResource(getResources(), R.drawable.status_available));
+	mStatusIconsMap.put(Status.CONTACT_STATUS_AWAY, BitmapFactory.decodeResource(getResources(), R.drawable.status_away));
+	mStatusIconsMap.put(Status.CONTACT_STATUS_BUSY, BitmapFactory.decodeResource(getResources(), R.drawable.status_dnd));
+	mStatusIconsMap.put(Status.CONTACT_STATUS_DISCONNECT, BitmapFactory.decodeResource(getResources(), R.drawable.status_offline));
+	mStatusIconsMap.put(Status.CONTACT_STATUS_UNAVAILABLE, BitmapFactory.decodeResource(getResources(), R.drawable.status_requested));
+    }
+    
+    private class MessagesListAdapter extends BaseAdapter {
+
+        private Context mContext;
+	
+        public MessagesListAdapter(Context context) {
+            mContext = context;
+        }
+
+        public int getCount() {
+            return mListMessages.size();
+        }
+
+        public Object getItem(int position) {
+            return position;
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            MessageView sv;
+            if (convertView == null) {
+                sv = new MessageView(mContext, mListMessages.get(position).getName(),
+                    	mListMessages.get(position).getMessage());
+            } else {
+                sv = (MessageView) convertView;
+                sv.setName(mListMessages.get(position).getName());
+                sv.setMessage(mListMessages.get(position).getMessage());
+            }
+
+            return sv;
+        }
+    }
+    
+    private class MessageText {
+	private String mName;
+	private String mMessage;
+	
+	public MessageText(String name, String message) {
+	    mName = name;
+	    mMessage = message;
+	}
+	
+	public String getName() {
+	    return mName;
+	}
+	
+	public String getMessage() {
+	    return mMessage;
+	}
+	
+	public void setName(String name) {
+	    mName = name;
+	}
+	
+	public void setMessage(String message) {
+	    mMessage = message;
+	}
+    }
+    
+    /**
+     * We will use a MessageView to display each message.
+     */
+    private class MessageView extends LinearLayout {
+        private TextView mName;
+        private TextView mMessage;
+	
+        /**
+         * Constructor.
+         * @param context
+         * @param name
+         * @param message
+         */
+        public MessageView(Context context, String name, String message) {
+            super(context);
+
+            this.setOrientation(VERTICAL);
+
+            mName = new TextView(context);
+            mName.setText(name);
+            addView(mName, new LinearLayout.LayoutParams(
+                    LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
+
+            mMessage = new TextView(context);
+            mMessage.setText(message);
+            addView(mMessage, new LinearLayout.LayoutParams(
+                    LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
+        }
+
+        /**
+         * Convenience method to set the title of a MessageView
+         */
+        public void setName(String name) {
+            mName.setText(name);
+        }
+
+        /**
+         * Convenience method to set the dialogue of a MessageView
+         */
+        public void setMessage(String message) {
+            mMessage.setText(message);
+        }
+    }
 }
--- a/src/com/beem/project/beem/ui/ContactList.java	Fri Nov 06 14:09:30 2009 +0100
+++ b/src/com/beem/project/beem/ui/ContactList.java	Fri Nov 06 17:51:22 2009 +0100
@@ -29,8 +29,6 @@
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.animation.Animation;
-import android.view.animation.TranslateAnimation;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.Gallery;
--- a/src/com/beem/project/beem/ui/Login.java	Fri Nov 06 14:09:30 2009 +0100
+++ b/src/com/beem/project/beem/ui/Login.java	Fri Nov 06 17:51:22 2009 +0100
@@ -3,7 +3,6 @@
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.ProgressDialog;
-import android.app.ActivityManager.RunningAppProcessInfo;
 import android.content.ComponentName;
 import android.content.DialogInterface;
 import android.content.Intent;
--- a/src/com/beem/project/beem/ui/SendIM.java	Fri Nov 06 14:09:30 2009 +0100
+++ b/src/com/beem/project/beem/ui/SendIM.java	Fri Nov 06 17:51:22 2009 +0100
@@ -476,7 +476,6 @@
 		Linkify.addLinks(mStatusText, Linkify.WEB_URLS);
 	    }
 	}
-
     }
 
     /**