diff --git a/gen/de/gultsch/chat/R.java b/gen/de/gultsch/chat/R.java index ebe4e3b3f..d316fb902 100644 --- a/gen/de/gultsch/chat/R.java +++ b/gen/de/gultsch/chat/R.java @@ -69,7 +69,7 @@ public final class R { public static final int conversation_lastupdate=0x7f0a000d; public static final int conversation_name=0x7f0a000b; public static final int details_account=0x7f0a0012; - public static final int details_contact_picture=0x7f0a000e; + public static final int details_contact_badge=0x7f0a000e; public static final int details_contactjid=0x7f0a0010; public static final int details_contactstatus=0x7f0a0011; public static final int details_jidbox=0x7f0a000f; diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 696978deb..390dc3a95 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -36,6 +36,10 @@ - + diff --git a/src/de/gultsch/chat/entities/Account.java b/src/de/gultsch/chat/entities/Account.java index f94f7b486..bd2e14c6d 100644 --- a/src/de/gultsch/chat/entities/Account.java +++ b/src/de/gultsch/chat/entities/Account.java @@ -30,7 +30,7 @@ public class Account extends AbstractEntity{ protected String username; protected String server; protected String password; - protected int options; + protected int options = 0; protected String rosterVersion; protected String resource; protected int status = 0; @@ -60,8 +60,10 @@ public class Account extends AbstractEntity{ public void setOption(int option, boolean value) { if (value) { this.options = (this.options | 1 << option); + Log.d("xmppService","enabling option "+this.options); } else { - this.options = (this.options ^ 1 << option); + this.options = (this.options & 0 << option); + Log.d("xmppService","disabeling option "+this.options); } } diff --git a/src/de/gultsch/chat/entities/Conversation.java b/src/de/gultsch/chat/entities/Conversation.java index 329f2bea5..8be35aa4f 100644 --- a/src/de/gultsch/chat/entities/Conversation.java +++ b/src/de/gultsch/chat/entities/Conversation.java @@ -21,15 +21,15 @@ public class Conversation extends AbstractEntity { public static final int MODE_SINGLE = 0; public static final String NAME = "name"; - public static final String PHOTO_URI = "profilePhotoUri"; public static final String ACCOUNT = "accountUuid"; - public static final String CONTACT = "contactJid"; + public static final String CONTACT = "contactUuid"; + public static final String CONTACTJID = "contactJid"; public static final String STATUS = "status"; public static final String CREATED = "created"; public static final String MODE = "mode"; private String name; - private String profilePhotoUri; + private String contactUuid; private String accountUuid; private String contactJid; private int status; @@ -38,19 +38,20 @@ public class Conversation extends AbstractEntity { private transient List messages = null; private transient Account account = null; + private transient Contact contact; - public Conversation(String name, String profilePhoto, Account account, + public Conversation(String name, Account account, String contactJid, int mode) { - this(java.util.UUID.randomUUID().toString(), name, profilePhoto, account.getUuid(), contactJid, System + this(java.util.UUID.randomUUID().toString(), name, null, account.getUuid(), contactJid, System .currentTimeMillis(), STATUS_AVAILABLE,mode); this.account = account; } - public Conversation(String uuid, String name, String profilePhoto, + public Conversation(String uuid, String name, String contactUuid, String accountUuid, String contactJid, long created, int status, int mode) { this.uuid = uuid; this.name = name; - this.profilePhotoUri = profilePhoto; + this.contactUuid = contactUuid; this.accountUuid = accountUuid; this.contactJid = contactJid; this.created = created; @@ -91,11 +92,19 @@ public class Conversation extends AbstractEntity { } public String getName() { - return this.name; + if (this.contact!=null) { + return this.contact.getDisplayName(); + } else { + return this.name; + } } public String getProfilePhotoString() { - return this.profilePhotoUri; + if (this.contact==null) { + return null; + } else { + return this.contact.getProfilePhoto(); + } } public String getAccountUuid() { @@ -105,6 +114,15 @@ public class Conversation extends AbstractEntity { public Account getAccount() { return this.account; } + + public Contact getContact() { + return this.contact; + } + + public void setContact(Contact contact) { + this.contact = contact; + this.contactUuid = contact.getUuid(); + } public void setAccount(Account account) { this.account = account; @@ -115,8 +133,8 @@ public class Conversation extends AbstractEntity { } public Uri getProfilePhotoUri() { - if (this.profilePhotoUri != null) { - return Uri.parse(profilePhotoUri); + if (this.getProfilePhotoString() != null) { + return Uri.parse(this.getProfilePhotoString()); } return null; } @@ -133,9 +151,9 @@ public class Conversation extends AbstractEntity { ContentValues values = new ContentValues(); values.put(UUID, uuid); values.put(NAME, name); - values.put(PHOTO_URI, profilePhotoUri); + values.put(CONTACT, contact.getUuid()); values.put(ACCOUNT, accountUuid); - values.put(CONTACT, contactJid); + values.put(CONTACTJID, contactJid); values.put(CREATED, created); values.put(STATUS, status); values.put(MODE,mode); @@ -145,9 +163,9 @@ public class Conversation extends AbstractEntity { public static Conversation fromCursor(Cursor cursor) { return new Conversation(cursor.getString(cursor.getColumnIndex(UUID)), cursor.getString(cursor.getColumnIndex(NAME)), - cursor.getString(cursor.getColumnIndex(PHOTO_URI)), - cursor.getString(cursor.getColumnIndex(ACCOUNT)), cursor.getString(cursor.getColumnIndex(CONTACT)), + cursor.getString(cursor.getColumnIndex(ACCOUNT)), + cursor.getString(cursor.getColumnIndex(CONTACTJID)), cursor.getLong(cursor.getColumnIndex(CREATED)), cursor.getInt(cursor.getColumnIndex(STATUS)), cursor.getInt(cursor.getColumnIndex(MODE))); diff --git a/src/de/gultsch/chat/persistance/DatabaseBackend.java b/src/de/gultsch/chat/persistance/DatabaseBackend.java index 58f052ecc..b3290ee0d 100644 --- a/src/de/gultsch/chat/persistance/DatabaseBackend.java +++ b/src/de/gultsch/chat/persistance/DatabaseBackend.java @@ -38,8 +38,8 @@ public class DatabaseBackend extends SQLiteOpenHelper { + " NUMBER)"); db.execSQL("create table " + Conversation.TABLENAME + " (" + Conversation.UUID + " TEXT PRIMARY KEY, " + Conversation.NAME - + " TEXT, " + Conversation.PHOTO_URI + " TEXT, " - + Conversation.ACCOUNT + " TEXT, " + Conversation.CONTACT + + " TEXT, " + Conversation.CONTACT + " TEXT, " + + Conversation.ACCOUNT + " TEXT, " + Conversation.CONTACTJID + " TEXT, " + Conversation.CREATED + " NUMBER, " + Conversation.STATUS + " NUMBER," + Conversation.MODE + " NUMBER," + "FOREIGN KEY(" + Conversation.ACCOUNT @@ -139,7 +139,7 @@ public class DatabaseBackend extends SQLiteOpenHelper { SQLiteDatabase db = this.getReadableDatabase(); String[] selectionArgs = { account.getUuid(), contactJid }; Cursor cursor = db.query(Conversation.TABLENAME, null, - Conversation.ACCOUNT + "=? AND " + Conversation.CONTACT + "=?", + Conversation.ACCOUNT + "=? AND " + Conversation.CONTACTJID + "=?", selectionArgs, null, null, null); if (cursor.getCount() == 0) return null; diff --git a/src/de/gultsch/chat/services/XmppConnectionService.java b/src/de/gultsch/chat/services/XmppConnectionService.java index 55380c12c..1160754e7 100644 --- a/src/de/gultsch/chat/services/XmppConnectionService.java +++ b/src/de/gultsch/chat/services/XmppConnectionService.java @@ -32,6 +32,7 @@ import android.content.CursorLoader; import android.content.Intent; import android.content.Loader; import android.content.Loader.OnLoadCompleteListener; +import android.database.ContentObserver; import android.database.Cursor; import android.os.Binder; import android.os.Bundle; @@ -54,6 +55,15 @@ public class XmppConnectionService extends Service { private OnConversationListChangedListener convChangedListener = null; private OnAccountListChangedListener accountChangedListener = null; + + private ContentObserver contactObserver = new ContentObserver(null) { + @Override + public void onChange(boolean selfChange) { + super.onChange(selfChange); + Log.d(LOGTAG,"contact list has changed"); + mergePhoneContactsWithRoster(); + } + }; private final IBinder mBinder = new XmppConnectionBinder(); private OnMessagePacketReceived messageListener = new OnMessagePacketReceived() { @@ -100,10 +110,9 @@ public class XmppConnectionService extends Service { Conversation conversation = null; String[] fromParts = fullJid.split("/"); String jid = fromParts[0]; - Contact contact = findOrCreateContact(account, jid); boolean muc = (packet.getType() == MessagePacket.TYPE_GROUPCHAT); String counterPart = null; - conversation = findOrCreateConversation(account, contact, muc); + conversation = findOrCreateConversation(account, jid, muc); if (muc) { if ((fromParts.length == 1) || (packet.hasChild("subject")) || (packet.hasChild("delay"))) { @@ -154,10 +163,11 @@ public class XmppConnectionService extends Service { public void onPresencePacketReceived(Account account, PresencePacket packet) { String[] fromParts = packet.getAttribute("from").split("/"); - Contact contact = findOrCreateContact(account, fromParts[0]); - if (contact.getUuid() == null) { + Contact contact = findContact(account, fromParts[0]); + if (contact == null) { // most likely muc, self or roster not synced // Log.d(LOGTAG,"got presence for non contact "+packet.toString()); + return; } String type = packet.getAttribute("type"); if (type == null) { @@ -211,6 +221,10 @@ public class XmppConnectionService extends Service { public void onCreate() { databaseBackend = DatabaseBackend.getInstance(getApplicationContext()); this.accounts = databaseBackend.getAccounts(); + + getContentResolver() + .registerContentObserver( + ContactsContract.Contacts.CONTENT_URI, true,contactObserver); } public XmppConnection createConnection(Account account) { @@ -381,7 +395,9 @@ public class XmppConnectionService extends Service { this.conversations = databaseBackend .getConversations(Conversation.STATUS_AVAILABLE); for (Conversation conv : this.conversations) { - conv.setAccount(accountLookupTable.get(conv.getAccountUuid())); + Account account = accountLookupTable.get(conv.getAccountUuid()); + conv.setAccount(account); + conv.setContact(findContact(account, conv.getContactJid())); } } return this.conversations; @@ -395,26 +411,19 @@ public class XmppConnectionService extends Service { return databaseBackend.getMessages(conversation, 100); } - public Contact findOrCreateContact(Account account, String jid) { - Contact contact = databaseBackend.findContact(account, jid); - if (contact != null) { - contact.setAccount(account); - return contact; - } else { - return new Contact(account, jid.split("@")[0], jid, null); - } + public Contact findContact(Account account, String jid) { + return databaseBackend.findContact(account, jid); } public Conversation findOrCreateConversation(Account account, - Contact contact, boolean muc) { + String jid, boolean muc) { for (Conversation conv : this.getConversations()) { if ((conv.getAccount().equals(account)) - && (conv.getContactJid().equals(contact.getJid()))) { + && (conv.getContactJid().equals(jid))) { return conv; } } - Conversation conversation = databaseBackend.findConversation(account, - contact.getJid()); + Conversation conversation = databaseBackend.findConversation(account,jid); if (conversation != null) { conversation.setStatus(Conversation.STATUS_AVAILABLE); conversation.setAccount(account); @@ -428,18 +437,24 @@ public class XmppConnectionService extends Service { } this.databaseBackend.updateConversation(conversation); } else { + String conversationName; + Contact contact = findContact(account, jid); + if (contact!=null) { + conversationName = contact.getDisplayName(); + } else { + conversationName = jid.split("@")[0]; + } if (muc) { - conversation = new Conversation(contact.getDisplayName(), - contact.getProfilePhoto(), account, contact.getJid(), + conversation = new Conversation(conversationName,account, jid, Conversation.MODE_MULTI); if (account.getStatus() == Account.STATUS_ONLINE) { joinMuc(account, conversation); } } else { - conversation = new Conversation(contact.getDisplayName(), - contact.getProfilePhoto(), account, contact.getJid(), + conversation = new Conversation(conversationName, account, jid, Conversation.MODE_SINGLE); } + conversation.setContact(contact); this.databaseBackend.createConversation(conversation); } this.conversations.add(conversation); diff --git a/src/de/gultsch/chat/ui/ConversationActivity.java b/src/de/gultsch/chat/ui/ConversationActivity.java index c5c03b12c..ed328c461 100644 --- a/src/de/gultsch/chat/ui/ConversationActivity.java +++ b/src/de/gultsch/chat/ui/ConversationActivity.java @@ -265,9 +265,14 @@ public class ConversationActivity extends XmppActivity { break; case R.id.action_details: DialogContactDetails details = new DialogContactDetails(); - Contact contact = xmppConnectionService.findOrCreateContact(this.getSelectedConversation().getAccount(),this.getSelectedConversation().getContactJid()); - details.setContact(contact); - details.show(getFragmentManager(), "details"); + Contact contact = this.getSelectedConversation().getContact(); + if (contact != null) { + contact.setAccount(this.selectedConversation.getAccount()); + details.setContact(contact); + details.show(getFragmentManager(), "details"); + } else { + Log.d("xmppService","contact was null - means not in roster"); + } break; default: break; diff --git a/src/de/gultsch/chat/ui/ConversationFragment.java b/src/de/gultsch/chat/ui/ConversationFragment.java index 204518696..e6cb9196a 100644 --- a/src/de/gultsch/chat/ui/ConversationFragment.java +++ b/src/de/gultsch/chat/ui/ConversationFragment.java @@ -7,12 +7,16 @@ import de.gultsch.chat.R; import de.gultsch.chat.entities.Contact; import de.gultsch.chat.entities.Conversation; import de.gultsch.chat.entities.Message; +import de.gultsch.chat.utils.PhoneHelper; import de.gultsch.chat.utils.UIHelper; import android.app.Fragment; +import android.content.SharedPreferences; import android.database.Cursor; +import android.graphics.Bitmap; import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; +import android.preference.PreferenceManager; import android.provider.ContactsContract.Profile; import android.util.Log; import android.view.LayoutInflater; @@ -72,13 +76,16 @@ public class ConversationFragment extends Fragment { messagesView = (ListView) view.findViewById(R.id.messages_view); - String[] mProjection = new String[] { Profile._ID, - Profile.PHOTO_THUMBNAIL_URI }; - Cursor mProfileCursor = getActivity().getContentResolver().query( - Profile.CONTENT_URI, mProjection, null, null, null); - - mProfileCursor.moveToFirst(); - final Uri profilePicture = Uri.parse(mProfileCursor.getString(1)); + SharedPreferences sharedPref = PreferenceManager + .getDefaultSharedPreferences(getActivity().getApplicationContext()); + boolean showPhoneSelfContactPicture = sharedPref.getBoolean("show_phone_selfcontact_picture",true); + + final Uri selfiUri; + if (showPhoneSelfContactPicture) { + selfiUri = PhoneHelper.getSefliUri(getActivity()); + } else { + selfiUri = null; + } messageListAdapter = new ArrayAdapter(this.getActivity() .getApplicationContext(), R.layout.message_sent, this.messageList) { @@ -133,7 +140,11 @@ public class ConversationFragment extends Fragment { } } } else { - imageView.setImageURI(profilePicture); + if (selfiUri!=null) { + imageView.setImageURI(selfiUri); + } else { + imageView.setImageBitmap(UIHelper.getUnknownContactPicture(conversation.getAccount().getJid(),200)); + } } TextView messageBody = (TextView) view.findViewById(R.id.message_body); String body = item.getBody(); diff --git a/src/de/gultsch/chat/ui/NewConversationActivity.java b/src/de/gultsch/chat/ui/NewConversationActivity.java index 2fb14008c..d86808417 100644 --- a/src/de/gultsch/chat/ui/NewConversationActivity.java +++ b/src/de/gultsch/chat/ui/NewConversationActivity.java @@ -230,7 +230,7 @@ public class NewConversationActivity extends XmppActivity { public void startConversation(Contact contact, Account account, boolean muc) { Log.d("xmppService","starting conversation for account:"+account.getJid()+" and contact:"+contact.getJid()); Conversation conversation = xmppConnectionService - .findOrCreateConversation(account, contact, muc); + .findOrCreateConversation(account, contact.getJid(), muc); Intent viewConversationIntent = new Intent(this, ConversationActivity.class); diff --git a/src/de/gultsch/chat/utils/PhoneHelper.java b/src/de/gultsch/chat/utils/PhoneHelper.java index f1d491d6f..3a53c08f3 100644 --- a/src/de/gultsch/chat/utils/PhoneHelper.java +++ b/src/de/gultsch/chat/utils/PhoneHelper.java @@ -3,13 +3,16 @@ package de.gultsch.chat.utils; import java.util.ArrayList; import java.util.Hashtable; +import android.app.Activity; import android.content.Context; import android.content.CursorLoader; import android.content.Loader; import android.content.Loader.OnLoadCompleteListener; import android.database.Cursor; +import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; +import android.provider.ContactsContract.Profile; public class PhoneHelper { @@ -62,4 +65,18 @@ public class PhoneHelper { }); mCursorLoader.startLoading(); } + + public static Uri getSefliUri(Activity activity) { + String[] mProjection = new String[] { Profile._ID, + Profile.PHOTO_THUMBNAIL_URI }; + Cursor mProfileCursor = activity.getContentResolver().query( + Profile.CONTENT_URI, mProjection, null, null, null); + + if (mProfileCursor.getCount()==0) { + return null; + } else { + mProfileCursor.moveToFirst(); + return Uri.parse(mProfileCursor.getString(1)); + } + } }