From aa42eb544a1ebf99dc52d71c917b899d1fce628d Mon Sep 17 00:00:00 2001 From: Daniel Gultsch Date: Wed, 5 Feb 2014 22:33:39 +0100 Subject: basic muc support. reworked contact list stuff --- AndroidManifest.xml | 7 +- src/de/gultsch/chat/entities/Contact.java | 24 ++ src/de/gultsch/chat/entities/Conversation.java | 20 +- .../gultsch/chat/persistance/DatabaseBackend.java | 61 ++++- .../chat/services/XmppConnectionService.java | 264 ++++++++++++++++----- src/de/gultsch/chat/ui/ConversationActivity.java | 16 +- src/de/gultsch/chat/ui/ConversationFragment.java | 34 +-- src/de/gultsch/chat/ui/ManageAccountActivity.java | 4 +- .../gultsch/chat/ui/NewConversationActivity.java | 130 ++++------ src/de/gultsch/chat/utils/UIHelper.java | 4 +- src/de/gultsch/chat/xmpp/MessagePacket.java | 7 +- src/de/gultsch/chat/xmpp/XmppConnection.java | 1 + 12 files changed, 396 insertions(+), 176 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 2b65b3a7e..f60af6324 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -25,9 +25,14 @@ android:windowSoftInputMode="stateHidden"> - + + + + + + messages = null; private transient Account account = null; public Conversation(String name, String profilePhoto, Account account, - String contactJid) { + String contactJid, int mode) { this(java.util.UUID.randomUUID().toString(), name, profilePhoto, account.getUuid(), contactJid, System - .currentTimeMillis(), STATUS_AVAILABLE); + .currentTimeMillis(), STATUS_AVAILABLE,mode); this.account = account; } public Conversation(String uuid, String name, String profilePhoto, - String accountUuid, String contactJid, long created, int status) { + String accountUuid, String contactJid, long created, int status, int mode) { this.uuid = uuid; this.name = name; this.profilePhotoUri = profilePhoto; @@ -50,6 +55,7 @@ public class Conversation extends AbstractEntity { this.contactJid = contactJid; this.created = created; this.status = status; + this.mode = mode; } public List getMessages() { @@ -132,6 +138,7 @@ public class Conversation extends AbstractEntity { values.put(CONTACT, contactJid); values.put(CREATED, created); values.put(STATUS, status); + values.put(MODE,mode); return values; } @@ -142,10 +149,15 @@ public class Conversation extends AbstractEntity { cursor.getString(cursor.getColumnIndex(ACCOUNT)), cursor.getString(cursor.getColumnIndex(CONTACT)), cursor.getLong(cursor.getColumnIndex(CREATED)), - cursor.getInt(cursor.getColumnIndex(STATUS))); + cursor.getInt(cursor.getColumnIndex(STATUS)), + cursor.getInt(cursor.getColumnIndex(MODE))); } public void setStatus(int status) { this.status = status; } + + public int getMode() { + return this.mode; + } } diff --git a/src/de/gultsch/chat/persistance/DatabaseBackend.java b/src/de/gultsch/chat/persistance/DatabaseBackend.java index bb2091123..f28ad7606 100644 --- a/src/de/gultsch/chat/persistance/DatabaseBackend.java +++ b/src/de/gultsch/chat/persistance/DatabaseBackend.java @@ -2,6 +2,7 @@ package de.gultsch.chat.persistance; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import de.gultsch.chat.entities.Account; import de.gultsch.chat.entities.Contact; @@ -37,9 +38,10 @@ public class DatabaseBackend extends SQLiteOpenHelper { + " TEXT, " + Conversation.PHOTO_URI + " TEXT, " + Conversation.ACCOUNT + " TEXT, " + Conversation.CONTACT + " TEXT, " + Conversation.CREATED + " NUMBER, " - + Conversation.STATUS + " NUMBER," + "FOREIGN KEY(" - + Conversation.ACCOUNT + ") REFERENCES " + Account.TABLENAME - + "(" + Account.UUID + ") ON DELETE CASCADE);"); + + Conversation.STATUS + " NUMBER," + Conversation.MODE + + " NUMBER," + "FOREIGN KEY(" + Conversation.ACCOUNT + + ") REFERENCES " + Account.TABLENAME + "(" + Account.UUID + + ") ON DELETE CASCADE);"); db.execSQL("create table " + Message.TABLENAME + "( " + Message.UUID + " TEXT PRIMARY KEY, " + Message.CONVERSATION + " TEXT, " + Message.TIME_SENT + " NUMBER, " + Message.COUNTERPART @@ -86,6 +88,11 @@ public class DatabaseBackend extends SQLiteOpenHelper { SQLiteDatabase db = this.getWritableDatabase(); db.insert(Account.TABLENAME, null, account.getContentValues()); } + + public void createContact(Contact contact) { + SQLiteDatabase db = this.getWritableDatabase(); + db.insert(Contact.TABLENAME, null, contact.getContentValues()); + } public int getConversationCount() { SQLiteDatabase db = this.getReadableDatabase(); @@ -184,4 +191,52 @@ public class DatabaseBackend extends SQLiteOpenHelper { db.update(Message.TABLENAME, message.getContentValues(), Message.UUID + "=?", args); } + + public void updateContact(Contact contact) { + SQLiteDatabase db = this.getWritableDatabase(); + String[] args = { contact.getUuid() }; + db.update(Contact.TABLENAME, contact.getContentValues(), Contact.UUID + + "=?", args); + } + + public void mergeContacts(List contacts) { + SQLiteDatabase db = this.getWritableDatabase(); + for (int i = 0; i < contacts.size(); i++) { + Contact contact = contacts.get(i); + String[] columns = {Contact.UUID}; + String[] args = {contact.getAccount().getUuid(), contact.getJid()}; + Cursor cursor = db.query(Contact.TABLENAME, columns,Contact.ACCOUNT+"=? AND "+Contact.JID+"=?", args, null, null, null); + if (cursor.getCount()>=1) { + cursor.moveToFirst(); + contact.setUuid(cursor.getString(0)); + updateContact(contact); + } else { + contact.setUuid(UUID.randomUUID().toString()); + createContact(contact); + } + } + } + + public List getContacts() { + List list = new ArrayList(); + SQLiteDatabase db = this.getReadableDatabase(); + Cursor cursor = db.query(Contact.TABLENAME, null, null, null, null, + null, null); + while (cursor.moveToNext()) { + list.add(Contact.fromCursor(cursor)); + } + return list; + } + + public Contact findContact(Account account, String jid) { + SQLiteDatabase db = this.getReadableDatabase(); + String[] selectionArgs = { account.getUuid(), jid }; + Cursor cursor = db.query(Contact.TABLENAME, null, + Contact.ACCOUNT + "=? AND " + Contact.JID + "=?", + selectionArgs, null, null, null); + if (cursor.getCount() == 0) + return null; + cursor.moveToFirst(); + return Contact.fromCursor(cursor); + } } diff --git a/src/de/gultsch/chat/services/XmppConnectionService.java b/src/de/gultsch/chat/services/XmppConnectionService.java index ae1140eef..c5477ae08 100644 --- a/src/de/gultsch/chat/services/XmppConnectionService.java +++ b/src/de/gultsch/chat/services/XmppConnectionService.java @@ -19,14 +19,21 @@ import de.gultsch.chat.xmpp.MessagePacket; import de.gultsch.chat.xmpp.OnIqPacketReceived; import de.gultsch.chat.xmpp.OnMessagePacketReceived; import de.gultsch.chat.xmpp.OnStatusChanged; +import de.gultsch.chat.xmpp.PresencePacket; import de.gultsch.chat.xmpp.XmppConnection; import android.app.NotificationManager; import android.app.Service; import android.content.Context; +import android.content.CursorLoader; import android.content.Intent; +import android.content.Loader; +import android.content.Loader.OnLoadCompleteListener; +import android.database.Cursor; import android.os.Binder; +import android.os.Bundle; import android.os.IBinder; import android.os.PowerManager; +import android.provider.ContactsContract; import android.util.Log; public class XmppConnectionService extends Service { @@ -50,15 +57,45 @@ public class XmppConnectionService extends Service { @Override public void onMessagePacketReceived(Account account, MessagePacket packet) { + Conversation conversation = null; + String fullJid = packet.getFrom(); + String counterPart = null; if (packet.getType() == MessagePacket.TYPE_CHAT) { - String fullJid = packet.getFrom(); String jid = fullJid.split("/")[0]; - String name = jid.split("@")[0]; - Contact contact = new Contact(account, name, jid, null); // dummy - // contact - Conversation conversation = findOrCreateConversation(account, - contact); - Message message = new Message(conversation, fullJid, + counterPart = fullJid; + Contact contact = findOrCreateContact(account,jid); + conversation = findOrCreateConversation(account, contact); + } else if (packet.getType() == MessagePacket.TYPE_GROUPCHAT) { + String[] fromParts = fullJid.split("/"); + if (fromParts.length != 2) { + return; + } + if (packet.hasChild("subject")) { + return; + } + if (packet.hasChild("delay")) { + return; + } + + String muc = fromParts[0]; + counterPart = fromParts[1]; + if (counterPart.equals(account.getUsername())) { + return; + } + for (int i = 0; i < conversations.size(); ++i) { + if (conversations.get(i).getContactJid().equals(muc)) { + conversation = conversations.get(i); + break; + } + } + if (conversation == null) { + Log.d(LOGTAG, "couldnt find muc"); + } + + } + if (conversation != null) { + Log.d(LOGTAG, packet.toString()); + Message message = new Message(conversation, counterPart, packet.getBody(), Message.ENCRYPTION_NONE, Message.STATUS_RECIEVED); conversation.getMessages().add(message); @@ -75,13 +112,15 @@ public class XmppConnectionService extends Service { } }; private OnStatusChanged statusListener = new OnStatusChanged() { - + @Override public void onStatusChanged(Account account) { - Log.d(LOGTAG,account.getJid()+" changed status to "+account.getStatus()); if (accountChangedListener != null) { accountChangedListener.onAccountListChangedListener(); } + if (account.getStatus() == Account.STATUS_ONLINE) { + connectMultiModeConversations(account); + } } }; @@ -96,9 +135,11 @@ public class XmppConnectionService extends Service { for (Account account : accounts) { if (!connections.containsKey(account)) { if (!account.isOptionSet(Account.OPTION_DISABLED)) { - this.connections.put(account, this.createConnection(account)); + this.connections.put(account, + this.createConnection(account)); } else { - Log.d(LOGTAG,account.getJid()+": not starting because it's disabled"); + Log.d(LOGTAG, account.getJid() + + ": not starting because it's disabled"); } } } @@ -110,13 +151,12 @@ public class XmppConnectionService extends Service { databaseBackend = DatabaseBackend.getInstance(getApplicationContext()); this.accounts = databaseBackend.getAccounts(); } - + public XmppConnection createConnection(Account account) { PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); XmppConnection connection = new XmppConnection(account, pm); - connection - .setOnMessagePacketReceivedListener(this.messageListener); - connection.setOnStatusChangedListener(this.statusListener ); + connection.setOnMessagePacketReceivedListener(this.messageListener); + connection.setOnStatusChangedListener(this.statusListener); Thread thread = new Thread(connection); thread.start(); return connection; @@ -132,7 +172,11 @@ public class XmppConnectionService extends Service { + message.getCounterpart()); databaseBackend.createMessage(message); MessagePacket packet = new MessagePacket(); - packet.setType(MessagePacket.TYPE_CHAT); + if (message.getConversation().getMode() == Conversation.MODE_SINGLE) { + packet.setType(MessagePacket.TYPE_CHAT); + } else if (message.getConversation().getMode() == Conversation.MODE_MULTI) { + packet.setType(MessagePacket.TYPE_GROUPCHAT); + } packet.setTo(message.getCounterpart()); packet.setFrom(account.getJid()); packet.setBody(message.getBody()); @@ -140,37 +184,109 @@ public class XmppConnectionService extends Service { message.setStatus(Message.STATUS_SEND); databaseBackend.updateMessage(message); } + + public void getRoster(final OnRosterFetchedListener listener) { + List contacts = databaseBackend.getContacts(); + if (listener != null) { + listener.onRosterFetched(contacts); + } + } - public void getRoster(final Account account, + public void updateRoster(final Account account, final OnRosterFetchedListener listener) { - IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); - Element query = new Element("query"); - query.setAttribute("xmlns", "jabber:iq:roster"); - query.setAttribute("ver", ""); - iqPacket.addChild(query); - connections.get(account).sendIqPacket(iqPacket, - new OnIqPacketReceived() { - - @Override - public void onIqPacketReceived(Account account, - IqPacket packet) { - Element roster = packet.findChild("query"); - List contacts = new ArrayList(); - for (Element item : roster.getChildren()) { - String name = item.getAttribute("name"); - String jid = item.getAttribute("jid"); - if (name == null) { - name = jid.split("@")[0]; + + final Hashtable phoneContacts = new Hashtable(); + final List contacts = new ArrayList(); + + final String[] PROJECTION = new String[] { + ContactsContract.Data.CONTACT_ID, + ContactsContract.Data.DISPLAY_NAME, + ContactsContract.Data.PHOTO_THUMBNAIL_URI, + ContactsContract.CommonDataKinds.Im.DATA }; + + final String SELECTION = "(" + ContactsContract.Data.MIMETYPE + "=\"" + + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE + + "\") AND (" + ContactsContract.CommonDataKinds.Im.PROTOCOL + + "=\"" + ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER + + "\")"; + + CursorLoader mCursorLoader = new CursorLoader(this, + ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, null, + null); + mCursorLoader.registerListener(0, new OnLoadCompleteListener() { + + @Override + public void onLoadComplete(Loader arg0, Cursor cursor) { + while (cursor.moveToNext()) { + Bundle contact = new Bundle(); + contact.putInt("phoneid", cursor.getInt(cursor + .getColumnIndex(ContactsContract.Data.CONTACT_ID))); + contact.putString( + "displayname", + cursor.getString(cursor + .getColumnIndex(ContactsContract.Data.DISPLAY_NAME))); + contact.putString( + "photouri", + cursor.getString(cursor + .getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI))); + phoneContacts.put( + cursor.getString(cursor + .getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA)), + contact); + } + IqPacket iqPacket = new IqPacket(IqPacket.TYPE_GET); + Element query = new Element("query"); + query.setAttribute("xmlns", "jabber:iq:roster"); + query.setAttribute("ver", ""); + iqPacket.addChild(query); + connections.get(account).sendIqPacket(iqPacket, + new OnIqPacketReceived() { + + @Override + public void onIqPacketReceived(Account account, + IqPacket packet) { + Element roster = packet.findChild("query"); + if (roster != null) { + for (Element item : roster.getChildren()) { + Contact contact; + Log.d(LOGTAG, item.toString()); + String name = item.getAttribute("name"); + String jid = item.getAttribute("jid"); + if (phoneContacts.containsKey(jid)) { + Bundle phoneContact = phoneContacts + .get(jid); + contact = new Contact( + account, + phoneContact + .getString("displayname"), + jid, + phoneContact + .getString("photouri")); + contact.setSystemAccount(phoneContact.getInt("phoneid")); + } else { + if (name == null) { + name = jid.split("@")[0]; + } + contact = new Contact(account, + name, jid, null); + + } + contact.setAccount(account); + contact.setSubscription(item + .getAttribute("subscription")); + contacts.add(contact); + } + databaseBackend.mergeContacts(contacts); + if (listener != null) { + listener.onRosterFetched(contacts); + } + } } - Contact contact = new Contact(account, name, jid, - null); - contacts.add(contact); - } - if (listener != null) { - listener.onRosterFetched(contacts); - } - } - }); + }); + + } + }); + mCursorLoader.startLoading(); } public void addConversation(Conversation conversation) { @@ -199,6 +315,15 @@ public class XmppConnectionService extends Service { public List getMessages(Conversation conversation) { return databaseBackend.getMessages(conversation, 100); } + + public Contact findOrCreateContact(Account account, String jid) { + Contact contact = databaseBackend.findContact(account,jid); + if (contact!=null) { + return contact; + } else { + return new Contact(account,jid.split("@")[0], jid, null); + } + } public Conversation findOrCreateConversation(Account account, Contact contact) { @@ -220,7 +345,8 @@ public class XmppConnectionService extends Service { } else { Log.d(LOGTAG, "didnt find one in archive. create new one"); conversation = new Conversation(contact.getDisplayName(), - contact.getProfilePhoto(), account, contact.getJid()); + contact.getProfilePhoto(), account, contact.getJid(), + Conversation.MODE_SINGLE); this.databaseBackend.createConversation(conversation); } this.conversations.add(conversation); @@ -246,7 +372,8 @@ public class XmppConnectionService extends Service { databaseBackend.createAccount(account); this.accounts.add(account); this.connections.put(account, this.createConnection(account)); - if (accountChangedListener!=null) accountChangedListener.onAccountListChangedListener(); + if (accountChangedListener != null) + accountChangedListener.onAccountListChangedListener(); } public void updateAccount(Account account) { @@ -259,21 +386,24 @@ public class XmppConnectionService extends Service { if (!account.isOptionSet(Account.OPTION_DISABLED)) { this.connections.put(account, this.createConnection(account)); } else { - Log.d(LOGTAG,account.getJid()+": not starting because it's disabled"); + Log.d(LOGTAG, account.getJid() + + ": not starting because it's disabled"); } - if (accountChangedListener!=null) accountChangedListener.onAccountListChangedListener(); + if (accountChangedListener != null) + accountChangedListener.onAccountListChangedListener(); } public void deleteAccount(Account account) { - Log.d(LOGTAG,"called delete account"); + Log.d(LOGTAG, "called delete account"); if (this.connections.containsKey(account)) { - Log.d(LOGTAG,"found connection. disconnecting"); + Log.d(LOGTAG, "found connection. disconnecting"); this.connections.get(account).disconnect(); this.connections.remove(account); this.accounts.remove(account); } databaseBackend.deleteAccount(account); - if (accountChangedListener!=null) accountChangedListener.onAccountListChangedListener(); + if (accountChangedListener != null) + accountChangedListener.onAccountListChangedListener(); } public void setOnConversationListChangedListener( @@ -284,12 +414,38 @@ public class XmppConnectionService extends Service { public void removeOnConversationListChangedListener() { this.convChangedListener = null; } - - public void setOnAccountListChangedListener(OnAccountListChangedListener listener) { + + public void setOnAccountListChangedListener( + OnAccountListChangedListener listener) { this.accountChangedListener = listener; } - + public void removeOnAccountListChangedListener() { this.accountChangedListener = null; } + + public void connectMultiModeConversations(Account account) { + List conversations = getConversations(); + for (int i = 0; i < conversations.size(); i++) { + Conversation conversation = conversations.get(i); + if ((conversation.getMode() == Conversation.MODE_MULTI) + && (conversation.getAccount() == account)) { + String muc = conversation.getContactJid(); + Log.d(LOGTAG, + "join muc " + muc + " with account " + account.getJid()); + PresencePacket packet = new PresencePacket(); + packet.setAttribute("to", muc + "/" + account.getUsername()); + Element x = new Element("x"); + x.setAttribute("xmlns", "http://jabber.org/protocol/muc"); + packet.addChild(x); + connections.get(conversation.getAccount()).sendPresencePacket( + packet); + + } + } + } + + public void disconnectMultiModeConversations() { + + } } diff --git a/src/de/gultsch/chat/ui/ConversationActivity.java b/src/de/gultsch/chat/ui/ConversationActivity.java index ca9bedf72..d9c497f8e 100644 --- a/src/de/gultsch/chat/ui/ConversationActivity.java +++ b/src/de/gultsch/chat/ui/ConversationActivity.java @@ -283,17 +283,28 @@ public class ConversationActivity extends XmppActivity { super.onStart(); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); nm.cancelAll(); + if (conversationList.size()>=1) { + onConvChanged.onConversationListChanged(); + } } - @Override + /*@Override protected void onPause() { super.onPause(); if (xmppConnectionServiceBound) { - Log.d("xmppService","called on stop. remove listener"); xmppConnectionService.removeOnConversationListChangedListener(); unbindService(mConnection); xmppConnectionServiceBound = false; } + }*/ + + @Override + protected void onStop() { + Log.d("gultsch","called on stop in conversation activity"); + if (xmppConnectionServiceBound) { + xmppConnectionService.removeOnConversationListChangedListener(); + } + super.onStop(); } @Override @@ -302,7 +313,6 @@ public class ConversationActivity extends XmppActivity { xmppConnectionService.setOnConversationListChangedListener(this.onConvChanged); if (conversationList.size()==0) { - Log.d("gultsch","conversation list is empty fetch new"); conversationList.clear(); conversationList.addAll(xmppConnectionService .getConversations()); diff --git a/src/de/gultsch/chat/ui/ConversationFragment.java b/src/de/gultsch/chat/ui/ConversationFragment.java index 1b8edbb5e..f2726945a 100644 --- a/src/de/gultsch/chat/ui/ConversationFragment.java +++ b/src/de/gultsch/chat/ui/ConversationFragment.java @@ -115,11 +115,19 @@ public class ConversationFragment extends Fragment { } ImageView imageView = (ImageView) view.findViewById(R.id.message_photo); if (type == RECIEVED) { - Uri uri = item.getConversation().getProfilePhotoUri(); - if (uri!=null) { - imageView.setImageURI(uri); - } else { - imageView.setImageBitmap(UIHelper.getUnknownContactPicture(item.getConversation().getName(), 200)); + if(item.getConversation().getMode()==Conversation.MODE_SINGLE) { + Uri uri = item.getConversation().getProfilePhotoUri(); + if (uri!=null) { + imageView.setImageURI(uri); + } else { + imageView.setImageBitmap(UIHelper.getUnknownContactPicture(item.getConversation().getName(), 200)); + } + } else if (item.getConversation().getMode()==Conversation.MODE_MULTI) { + if (item.getCounterpart()!=null) { + imageView.setImageBitmap(UIHelper.getUnknownContactPicture(item.getCounterpart(), 200)); + } else { + imageView.setImageBitmap(UIHelper.getUnknownContactPicture(item.getConversation().getName(), 200)); + } } } else { imageView.setImageURI(profilePicture); @@ -152,12 +160,9 @@ public class ConversationFragment extends Fragment { final ConversationActivity activity = (ConversationActivity) getActivity(); - // TODO check if bond and get data back - if (activity.xmppConnectionServiceBound) { this.conversation = activity.getConversationList().get(activity.getSelectedConversation()); - this.messageList.clear(); - this.messageList.addAll(this.conversation.getMessages()); + updateMessages(); // rendering complete. now go tell activity to close pane if (!activity.shouldPaneBeOpen()) { activity.getSlidingPaneLayout().closePane(); @@ -165,18 +170,14 @@ public class ConversationFragment extends Fragment { activity.getActionBar().setTitle(conversation.getName()); activity.invalidateOptionsMenu(); } - - int size = this.messageList.size(); - if (size >= 1) - messagesView.setSelection(size - 1); } } public void onBackendConnected() { + Log.d("gultsch","calling on backend connected in conversation fragment"); final ConversationActivity activity = (ConversationActivity) getActivity(); this.conversation = activity.getConversationList().get(activity.getSelectedConversation()); - this.messageList.clear(); - this.messageList.addAll(this.conversation.getMessages()); + updateMessages(); // rendering complete. now go tell activity to close pane if (!activity.shouldPaneBeOpen()) { activity.getSlidingPaneLayout().closePane(); @@ -190,5 +191,8 @@ public class ConversationFragment extends Fragment { this.messageList.clear(); this.messageList.addAll(this.conversation.getMessages()); this.messageListAdapter.notifyDataSetChanged(); + int size = this.messageList.size(); + if (size >= 1) + messagesView.setSelection(size - 1); } } diff --git a/src/de/gultsch/chat/ui/ManageAccountActivity.java b/src/de/gultsch/chat/ui/ManageAccountActivity.java index 2f0bb1a01..66a407820 100644 --- a/src/de/gultsch/chat/ui/ManageAccountActivity.java +++ b/src/de/gultsch/chat/ui/ManageAccountActivity.java @@ -152,12 +152,10 @@ public class ManageAccountActivity extends XmppActivity implements ActionMode.Ca @Override protected void onStop() { - super.onStop(); if (xmppConnectionServiceBound) { xmppConnectionService.removeOnAccountListChangedListener(); - unbindService(mConnection); - xmppConnectionServiceBound = false; } + super.onStop(); } @Override diff --git a/src/de/gultsch/chat/ui/NewConversationActivity.java b/src/de/gultsch/chat/ui/NewConversationActivity.java index 3bfb4e2a5..cbd68def8 100644 --- a/src/de/gultsch/chat/ui/NewConversationActivity.java +++ b/src/de/gultsch/chat/ui/NewConversationActivity.java @@ -57,10 +57,6 @@ public class NewConversationActivity extends XmppActivity { protected void updateAggregatedContacts() { aggregatedContacts.clear(); - for (Contact contact : phoneContacts) { - if (contact.match(searchString)) - aggregatedContacts.add(contact); - } for (Contact contact : rosterContacts) { if (contact.match(searchString)) aggregatedContacts.add(contact); @@ -71,7 +67,8 @@ public class NewConversationActivity extends XmppActivity { @SuppressLint("DefaultLocale") @Override public int compare(Contact lhs, Contact rhs) { - return lhs.getDisplayName().toLowerCase().compareTo(rhs.getDisplayName().toLowerCase()); + return lhs.getDisplayName().toLowerCase() + .compareTo(rhs.getDisplayName().toLowerCase()); } }); @@ -79,7 +76,7 @@ public class NewConversationActivity extends XmppActivity { if (Validator.isValidJid(searchString)) { String name = searchString.split("@")[0]; - Contact newContact = new Contact(null,name, searchString,null); + Contact newContact = new Contact(null, name, searchString, null); aggregatedContacts.add(newContact); contactsHeader.setText("Create new contact"); } else { @@ -93,19 +90,6 @@ public class NewConversationActivity extends XmppActivity { contactsView.setScrollX(0); } - static final String[] PROJECTION = new String[] { - ContactsContract.Data.CONTACT_ID, - ContactsContract.Data.DISPLAY_NAME, - ContactsContract.Data.PHOTO_THUMBNAIL_URI, - ContactsContract.CommonDataKinds.Im.DATA }; - - // This is the select criteria - static final String SELECTION = "(" + ContactsContract.Data.MIMETYPE - + "=\"" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE - + "\") AND (" + ContactsContract.CommonDataKinds.Im.PROTOCOL - + "=\"" + ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER - + "\")"; - @Override protected void onCreate(Bundle savedInstanceState) { @@ -154,11 +138,13 @@ public class NewConversationActivity extends XmppActivity { ((TextView) view.findViewById(R.id.contact_jid)) .setText(getItem(position).getJid()); String profilePhoto = getItem(position).getProfilePhoto(); - ImageView imageView = (ImageView) view.findViewById(R.id.contact_photo); - if (profilePhoto!=null) { + ImageView imageView = (ImageView) view + .findViewById(R.id.contact_photo); + if (profilePhoto != null) { imageView.setImageURI(Uri.parse(profilePhoto)); } else { - imageView.setImageBitmap(UIHelper.getUnknownContactPicture(getItem(position).getDisplayName(),90)); + imageView.setImageBitmap(UIHelper.getUnknownContactPicture( + getItem(position).getDisplayName(), 90)); } return view; } @@ -168,25 +154,27 @@ public class NewConversationActivity extends XmppActivity { contactsView.setOnItemClickListener(new OnItemClickListener() { @Override - public void onItemClick(AdapterView arg0, final View view, int pos, - long arg3) { + public void onItemClick(AdapterView arg0, final View view, + int pos, long arg3) { final Contact clickedContact = aggregatedContacts.get(pos); Log.d("gultsch", "clicked on " + clickedContact.getDisplayName()); - - final List accounts = xmppConnectionService.getAccounts(); + + final List accounts = xmppConnectionService + .getAccounts(); if (accounts.size() == 1) { startConversation(clickedContact, accounts.get(0)); } else { String[] accountList = new String[accounts.size()]; - for(int i = 0; i < accounts.size(); ++i) { + for (int i = 0; i < accounts.size(); ++i) { accountList[i] = accounts.get(i).getJid(); } - - AlertDialog.Builder builder = new AlertDialog.Builder(activity); + + AlertDialog.Builder builder = new AlertDialog.Builder( + activity); builder.setTitle("Choose account"); - builder.setItems(accountList,new OnClickListener() { - + builder.setItems(accountList, new OnClickListener() { + @Override public void onClick(DialogInterface dialog, int which) { Account account = accounts.get(which); @@ -198,56 +186,22 @@ public class NewConversationActivity extends XmppActivity { } }); } - + public void startConversation(Contact contact, Account account) { Conversation conversation = xmppConnectionService .findOrCreateConversation(account, contact); - Intent viewConversationIntent = new Intent(this,ConversationActivity.class); + Intent viewConversationIntent = new Intent(this, + ConversationActivity.class); viewConversationIntent.setAction(Intent.ACTION_VIEW); - viewConversationIntent.putExtra( - ConversationActivity.CONVERSATION, + viewConversationIntent.putExtra(ConversationActivity.CONVERSATION, conversation.getUuid()); - viewConversationIntent - .setType(ConversationActivity.VIEW_CONVERSATION); - viewConversationIntent.setFlags(viewConversationIntent - .getFlags() | Intent.FLAG_ACTIVITY_CLEAR_TOP); + viewConversationIntent.setType(ConversationActivity.VIEW_CONVERSATION); + viewConversationIntent.setFlags(viewConversationIntent.getFlags() + | Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(viewConversationIntent); } - @Override - public void onStart() { - super.onStart(); - - CursorLoader mCursorLoader = new CursorLoader(this, - ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, null, - null); - mCursorLoader.registerListener(0, new OnLoadCompleteListener() { - - @Override - public void onLoadComplete(Loader arg0, Cursor cursor) { - phoneContacts.clear(); - while (cursor.moveToNext()) { - String profilePhoto = cursor.getString(cursor - .getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI)); - /*if (profilePhoto == null) { - profilePhoto = DEFAULT_PROFILE_PHOTO; - }*/ - Contact contact = new Contact(null, - cursor.getString(cursor - .getColumnIndex(ContactsContract.Data.DISPLAY_NAME)), - cursor.getString(cursor - .getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA)), - profilePhoto); - phoneContacts.add(contact); - } - updateAggregatedContacts(); - } - }); - mCursorLoader.startLoading(); - - } - @Override void onBackendConnected() { if (xmppConnectionService.getConversationCount() == 0) { @@ -256,23 +210,21 @@ public class NewConversationActivity extends XmppActivity { } this.accounts = xmppConnectionService.getAccounts(); this.rosterContacts.clear(); - for(Account account : this.accounts) { - xmppConnectionService.getRoster(account, new OnRosterFetchedListener() { - - @Override - public void onRosterFetched(List roster) { - rosterContacts.addAll(roster); - runOnUiThread(new Runnable() { - - @Override - public void run() { - updateAggregatedContacts(); - } - }); - - } - }); - } + xmppConnectionService.getRoster(new OnRosterFetchedListener() { + + @Override + public void onRosterFetched(List roster) { + rosterContacts.addAll(roster); + runOnUiThread(new Runnable() { + + @Override + public void run() { + updateAggregatedContacts(); + } + }); + + } + }); } @Override diff --git a/src/de/gultsch/chat/utils/UIHelper.java b/src/de/gultsch/chat/utils/UIHelper.java index 1c7a568ea..b7ea5289e 100644 --- a/src/de/gultsch/chat/utils/UIHelper.java +++ b/src/de/gultsch/chat/utils/UIHelper.java @@ -46,13 +46,11 @@ public class UIHelper { public static Bitmap getUnknownContactPicture(String name, int size) { String firstLetter = name.substring(0, 1).toUpperCase(); - String centerLetter = name.substring(name.length() / 2, - (name.length() / 2) + 1); int holoColors[] = { 0xFF1da9da, 0xFFb368d9, 0xFF83b600, 0xFFffa713, 0xFFe92727 }; - int color = holoColors[centerLetter.charAt(0) % holoColors.length]; + int color = holoColors[Math.abs(name.hashCode()) % holoColors.length]; Bitmap bitmap = Bitmap .createBitmap(size, size, Bitmap.Config.ARGB_8888); diff --git a/src/de/gultsch/chat/xmpp/MessagePacket.java b/src/de/gultsch/chat/xmpp/MessagePacket.java index ab0c05c3d..5da76152f 100644 --- a/src/de/gultsch/chat/xmpp/MessagePacket.java +++ b/src/de/gultsch/chat/xmpp/MessagePacket.java @@ -6,6 +6,7 @@ public class MessagePacket extends Element { public static final int TYPE_CHAT = 0; public static final int TYPE_UNKNOWN = 1; public static final int TYPE_NO = 2; + public static final int TYPE_GROUPCHAT = 3; private MessagePacket(String name) { super(name); @@ -51,7 +52,9 @@ public class MessagePacket extends Element { case TYPE_CHAT: this.setAttribute("type","chat"); break; - + case TYPE_GROUPCHAT: + this.setAttribute("type", "groupchat"); + break; default: this.setAttribute("type","chat"); break; @@ -65,6 +68,8 @@ public class MessagePacket extends Element { } if (type.equals("chat")) { return TYPE_CHAT; + } else if (type.equals("groupchat")) { + return TYPE_GROUPCHAT; } else { return TYPE_UNKNOWN; } diff --git a/src/de/gultsch/chat/xmpp/XmppConnection.java b/src/de/gultsch/chat/xmpp/XmppConnection.java index 56a0acb0b..c105bbb4b 100644 --- a/src/de/gultsch/chat/xmpp/XmppConnection.java +++ b/src/de/gultsch/chat/xmpp/XmppConnection.java @@ -340,6 +340,7 @@ public class XmppConnection implements Runnable { public void sendPresencePacket(PresencePacket packet) { tagWriter.writeElement(packet); + Log.d(LOGTAG,account.getJid()+": sending: "+packet.toString()); } public void setOnMessagePacketReceivedListener(OnMessagePacketReceived listener) { -- cgit v1.2.3