Gestion des contacts sans groupe.
package com.beem.project.beem.ui;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jivesoftware.smack.util.StringUtils;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
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.PresenceAdapter;
import com.beem.project.beem.service.XmppConnectionAdapter;
import com.beem.project.beem.service.aidl.IBeemRosterListener;
import com.beem.project.beem.service.aidl.IRoster;
import com.beem.project.beem.service.aidl.IXmppFacade;
import com.beem.project.beem.utils.Status;
/**
* The contact list activity displays the roster of the user.
*/
public class ContactList extends Activity {
private static final String TAG = "CONTACTLIST_ACT";
private static final int REQUEST_CODE = 1;
private BeemContactList mAdapter;
private IRoster mRoster;
private List<Contact> mListContact = new ArrayList<Contact>();
private List<String> mListGroup;
private Map<String, List<Contact>> mContactOnGroup = new HashMap<String, List<Contact>>();
private String mCurGroup;
private Handler mHandler;
private IXmppFacade mXmppFacade;
private final ServiceConnection mServConn = new BeemServiceConnection();
private BroadcastReceiver mReceiver;
/**
* Constructor.
*/
public ContactList() {
}
@Override
protected void onCreate(Bundle saveBundle) {
super.onCreate(saveBundle);
setContentView(R.layout.contactlist);
mAdapter = new BeemContactList(this);
mHandler = new Handler();
mReceiver = new BeemBroadcastReceiver();
}
@Override
protected void onResume() {
super.onResume();
this.registerReceiver(mReceiver, new IntentFilter(XmppConnectionAdapter.BEEM_CONNECTION_CLOSED));
}
@Override
protected void onPause() {
super.onPause();
this.unregisterReceiver(mReceiver);
}
/**
* Callback for menu creation.
* @param menu the menu created
* @return true on success, false otherwise
*/
@Override
public final boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.contact_list, menu);
return true;
}
/**
* Callback for menu item selected.
* @param item the item selected
* @return true on success, false otherwise
*/
@Override
public final boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.contact_list_menu_settings:
startActivityForResult(new Intent(this, EditSettings.class), REQUEST_CODE);
return true;
case R.id.contact_list_menu_add_contact:
startActivity(new Intent(ContactList.this, AddContact.class));
return true;
default:
return false;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE) {
if (resultCode == 69) {
finish();
stopService(new Intent(this, BeemService.class));
startActivity(new Intent(this, Login.class));
}
}
}
/**
* {@inheritDoc}
*/
@Override
protected void onStart() {
super.onStart();
bindService(new Intent(this, BeemService.class), mServConn, BIND_AUTO_CREATE);
}
/**
* {@inheritDoc}
*/
@Override
protected void onStop() {
Log.e(TAG, "UNBINSERVICE");
super.onStop();
unbindService(mServConn);
}
/**
* Comparator Contact by Name.
*/
class ComparatorContactListByName<T> implements Comparator<T> {
/**
* Constructor.
*/
public ComparatorContactListByName() {
}
/**
* {@inheritDoc}
*/
@Override
public int compare(T c1, T c2) {
return ((Contact) c1).getName().compareToIgnoreCase(((Contact) c2).getName());
}
}
/**
* Comparator Contact by status and name.
*/
class ComparatorContactListByStatusAndName<T> implements Comparator<T> {
/**
* Constructor.
*/
public ComparatorContactListByStatusAndName() {
}
/**
* {@inheritDoc}
*/
@Override
public int compare(T c1, T c2) {
if (((Contact) c1).getStatus() < ((Contact) c2).getStatus()) {
return 1;
} else if (((Contact) c1).getStatus() > ((Contact) c2).getStatus()) {
return -1;
} else
return ((Contact) c1).getName().compareToIgnoreCase(((Contact) c2).getName());
}
}
/**
* Contact List construction.
* @param listContact Contact list.
* @param listGroup Group list.
*/
private void buildContactList() {
if (mCurGroup != null) {
mListContact = mContactOnGroup.get(mCurGroup);
}
sortBeemContactList();
ListView listView = (ListView) findViewById(R.id.contactlist);
listView.setOnItemClickListener(new BeemContactListOnClick());
listView.setOnItemLongClickListener(new BeemContactListOnLongClick());
listView.setAdapter(mAdapter);
}
private void buildBanner() {
Gallery g = (Gallery) findViewById(R.id.gallery);
g.setOnItemClickListener(new OnItemClickGroupName());
g.setAdapter(new BeemBanner(this));
}
/**
* Event simple click on item of the contact list.
*/
public class BeemContactListOnClick implements OnItemClickListener {
/**
* Constructor.
*/
public BeemContactListOnClick() {
}
/**
* {@inheritDoc}
*/
@Override
public void onItemClick(AdapterView<?> arg0, View v, int pos, long lpos) {
Contact c = mListContact.get(pos);
Intent i = new Intent(ContactList.this, SendIM.class);
i.setData(c.toUri());
startActivity(i);
}
}
/**
* Event long click on item of the contact list.
*/
public class BeemContactListOnLongClick implements OnItemLongClickListener {
/**
* Constructor.
*/
public BeemContactListOnLongClick() {
}
/**
* {@inheritDoc}
*/
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View v, int pos, long lpos) {
Contact c = mListContact.get(pos);
ContactDialog dialogContact = new ContactDialog(ContactList.this, c, "MYSTATICGROUP");
dialogContact.setOwnerActivity(ContactList.this);
dialogContact.show();
return true;
}
}
/**
* Event on middle groupe name.
*/
private class OnItemClickGroupName implements OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> arg0, View v, int i, long l) {
mCurGroup = mListGroup.get(i);
buildContactList();
}
}
/**
* Sort the contact list.
*/
private void sortBeemContactList() {
Collections.sort(mListContact, new ComparatorContactListByStatusAndName<Contact>());
}
/**
* Listener on service event.
*/
private class BeemRosterListener extends IBeemRosterListener.Stub {
/**
* Constructor.
*/
public BeemRosterListener() {
}
/**
* Refresh the contact list.
*/
private class RunnableChange implements Runnable {
/**
* Constructor.
*/
public RunnableChange() {
}
/**
* {@inheritDoc}
*/
@Override
public void run() {
sortBeemContactList();
mAdapter.notifyDataSetChanged();
}
}
/**
* {@inheritDoc}
*/
@Override
public void onEntriesAdded(List<String> addresses) throws RemoteException {
for (String newName : addresses) {
Contact c = new Contact(newName);
mListContact.add(c);
}
mHandler.post(new RunnableChange());
}
/**
* {@inheritDoc}
*/
@Override
public void onEntriesDeleted(List<String> addresses) throws RemoteException {
for (String cToDelete : addresses) {
for (Contact c : mListContact) {
if (c.getJID().equals(cToDelete)) {
mListContact.remove(c);
break;
}
}
}
mHandler.post(new RunnableChange());
}
/**
* {@inheritDoc}
*/
@Override
public void onEntriesUpdated(List<String> addresses) throws RemoteException {
mHandler.post(new RunnableChange());
}
@Override
public void onEntryDeleteFromGroup(String group, String jid) throws RemoteException {
// TODO Auto-generated method stub
}
/**
* {@inheritDoc}
*/
@Override
public void onPresenceChanged(PresenceAdapter presence) throws RemoteException {
// TODO gerer la presence au niveau de chaque ressources ?
String from = presence.getFrom();
boolean resfound = false;
for (Contact curContact : mListContact) {
if (curContact.getJID().equals(StringUtils.parseBareAddress(from))) {
String pres = StringUtils.parseResource(from);
for (String res : curContact.getMRes()) {
if (res.equals(pres)) {
resfound = true;
break;
}
}
curContact.setStatus(mRoster.getPresence(StringUtils.parseBareAddress(presence.getFrom())));
int status = presence.getStatus();
if (!resfound
&& (status != Status.CONTACT_STATUS_DISCONNECT && status != Status.CONTACT_STATUS_UNAVAILABLE))
curContact.addRes(pres);
else if (resfound
&& (status == Status.CONTACT_STATUS_DISCONNECT && status == Status.CONTACT_STATUS_UNAVAILABLE))
curContact.delRes(pres);
mHandler.post(new RunnableChange());
return;
}
}
}
}
/**
* Adapter contact list.
*/
private class BeemContactList extends BaseAdapter {
private LayoutInflater mInflater;
/**
* Constructor.
* @param context context activity.
*/
public BeemContactList(final Context context) {
mInflater = LayoutInflater.from(context);
}
/**
* {@inheritDoc}
*/
@Override
public int getCount() {
return mListContact.size();
}
/**
* {@inheritDoc}
*/
@Override
public Object getItem(int position) {
return position;
}
/**
* {@inheritDoc}
*/
@Override
public long getItemId(int position) {
return position;
}
/**
* {@inheritDoc}
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (convertView == null) {
v = mInflater.inflate(R.layout.contactlistcontact, null);
}
Contact c = mListContact.get(position);
bindView(v, c);
return v;
}
/**
* Adapte curContact to the view.
* @param view the row view.
* @param curContact the current contact.
*/
private void bindView(View view, Contact curContact) {
if (curContact != null) {
ImageView imgV = (ImageView) view.findViewById(R.id.contactliststatus);
TextView v = (TextView) view.findViewById(R.id.contactlistpseudo);
Drawable imageDrawable = null;
switch (curContact.getStatus()) {
case Status.CONTACT_STATUS_AVAILABLE:
imageDrawable = getResources().getDrawable(R.drawable.online);
v.setTextColor(getResources().getColor(R.color.white));
break;
case Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT:
imageDrawable = getResources().getDrawable(R.drawable.chat);
break;
case Status.CONTACT_STATUS_AWAY:
imageDrawable = getResources().getDrawable(R.drawable.away);
break;
case Status.CONTACT_STATUS_BUSY:
imageDrawable = getResources().getDrawable(R.drawable.dnd);
break;
case Status.CONTACT_STATUS_DISCONNECT:
imageDrawable = getResources().getDrawable(R.drawable.offline);
break;
case Status.CONTACT_STATUS_UNAVAILABLE:
imageDrawable = getResources().getDrawable(R.drawable.requested);
break;
default:
imageDrawable = getResources().getDrawable(R.drawable.error);
break;
}
imgV.setImageDrawable(imageDrawable);
String mContactName = curContact.getName();
if ("".equals(mContactName)) {
mContactName = curContact.getJID();
mContactName = StringUtils.parseName(mContactName);
if ("".equals(mContactName))
mContactName = curContact.getJID();
}
v.setText(mContactName);
v = (TextView) view.findViewById(R.id.contactlistmsgperso);
if (v != null) {
v.setText(curContact.getMsgState());
}
/*
* Rajouter l'avatar du contact getAvatar() dans la classe imgV = (ImageView)
* view.findViewById(R.id.contactlistavatar); if (imgV != null) { imageDrawable =
* getResources().getDrawable(R.drawable.avatar); imgV.setImageDrawable(imageDrawable); }
*/
}
}
}
/**
* Adapter banner list.
*/
public class BeemBanner extends BaseAdapter {
private Context mContext;
/**
* Constructor.
* @param c context activity.
*/
public BeemBanner(final Context c) {
mContext = c;
}
/**
* {@inheritDoc}
*/
@Override
public int getCount() {
return mListGroup.size();
}
/**
* {@inheritDoc}
*/
@Override
public Object getItem(int position) {
return position;
}
/**
* {@inheritDoc}
*/
@Override
public long getItemId(int position) {
return position;
}
/**
* {@inheritDoc}
*/
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView i = new TextView(mContext);
i.setText(mListGroup.get(position));
return i;
}
}
/**
* The service connection used to connect to the Beem service.
*/
private class BeemServiceConnection implements ServiceConnection {
private BeemRosterListener mBeemRosterListener = new BeemRosterListener();
/**
* Constructor.
*/
public BeemServiceConnection() {
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mXmppFacade = IXmppFacade.Stub.asInterface(service);
try {
mRoster = mXmppFacade.getRoster();
if (mRoster != null) {
mRoster.addRosterListener(mBeemRosterListener);
List<Contact> tmpContactList = mRoster.getContactList();
List<String> tmpGroupList = mRoster.getGroupsNames();
Collections.sort(tmpGroupList);
mListGroup = tmpGroupList;
mListGroup.add(getString(R.string.contact_list_no_group));
if (tmpGroupList.size() > 0) {
List<Contact> tmpNoGroup = new ArrayList<Contact>();
for (String s : tmpGroupList) {
List<Contact> tmpList = new ArrayList<Contact>();
for (Contact c : tmpContactList) {
if (c.getGroups().size() == 0 && !tmpNoGroup.contains(c))
tmpNoGroup.add(c);
else if (c.getGroups().contains(s))
tmpList.add(c);
}
mContactOnGroup.put(s, tmpList);
}
mContactOnGroup.put(getString(R.string.contact_list_no_group), tmpNoGroup);
mCurGroup = tmpGroupList.get(0);
} else {
mCurGroup = null;
mListContact = tmpContactList;
}
buildBanner();
buildContactList();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
try {
mRoster.removeRosterListener(mBeemRosterListener);
} catch (RemoteException e) {
e.printStackTrace();
}
mXmppFacade = null;
mRoster = null;
}
}
private class BeemBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "broadcast received");
}
}
}