fixed a bug where account options where toggled instead of set off. fixed null pointer for missing selfi. made sefli optional

Daniel Gultsch created

Change summary

gen/de/gultsch/chat/R.java                              |  2 
res/xml/preferences.xml                                 |  6 
src/de/gultsch/chat/entities/Account.java               |  6 
src/de/gultsch/chat/entities/Conversation.java          | 48 ++++++--
src/de/gultsch/chat/persistance/DatabaseBackend.java    |  6 
src/de/gultsch/chat/services/XmppConnectionService.java | 57 ++++++----
src/de/gultsch/chat/ui/ConversationActivity.java        | 11 +
src/de/gultsch/chat/ui/ConversationFragment.java        | 27 +++-
src/de/gultsch/chat/ui/NewConversationActivity.java     |  2 
src/de/gultsch/chat/utils/PhoneHelper.java              | 17 +++
10 files changed, 127 insertions(+), 55 deletions(-)

Detailed changes

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;

res/xml/preferences.xml 🔗

@@ -36,6 +36,10 @@
     </PreferenceCategory>
     <PreferenceCategory 
         android:title="Advanced settings">
-        
+        <CheckBoxPreference 
+            android:key="show_phone_selfcontact_picture"
+            android:title="Use Phones self contact picture"
+            android:summary="You may no longer be able to distinguish which account you are using in a conversation"
+            android:defaultValue="true"/>
     </PreferenceCategory>
 </PreferenceScreen>

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);
 		}
 	}
 	

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<Message> 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)));

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;

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);

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;

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<Message>(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();

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);

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));
+		}
+	}
 }