diff --git a/gen/de/gultsch/chat/R.java b/gen/de/gultsch/chat/R.java
index b7dde8f47..45083c731 100644
--- a/gen/de/gultsch/chat/R.java
+++ b/gen/de/gultsch/chat/R.java
@@ -34,8 +34,7 @@ public final class R {
public static final int ic_launcher=0x7f020006;
public static final int ic_profile=0x7f020007;
public static final int message_border=0x7f020008;
- public static final int profilemock=0x7f020009;
- public static final int section_header=0x7f02000a;
+ public static final int section_header=0x7f020009;
}
public static final class id {
public static final int account_confirm_password_desc=0x7f0a0011;
diff --git a/ic_launcher-web.png b/ic_launcher-web.png
deleted file mode 100644
index 8e26a9310..000000000
Binary files a/ic_launcher-web.png and /dev/null differ
diff --git a/ic_profile-web.png b/ic_profile-web.png
deleted file mode 100644
index c0c6ca8f6..000000000
Binary files a/ic_profile-web.png and /dev/null differ
diff --git a/res/drawable-hdpi/es_slidingpane_shadow.xml b/res/drawable-hdpi/es_slidingpane_shadow.xml
deleted file mode 100644
index eaca7894e..000000000
--- a/res/drawable-hdpi/es_slidingpane_shadow.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/res/drawable-mdpi/es_slidingpane_shadow.xml b/res/drawable-mdpi/es_slidingpane_shadow.xml
deleted file mode 100644
index eaca7894e..000000000
--- a/res/drawable-mdpi/es_slidingpane_shadow.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/res/drawable-xxhdpi/es_slidingpane_shadow.xml b/res/drawable-xxhdpi/es_slidingpane_shadow.xml
deleted file mode 100644
index eaca7894e..000000000
--- a/res/drawable-xxhdpi/es_slidingpane_shadow.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/res/drawable-xhdpi/es_slidingpane_shadow.xml b/res/drawable/es_slidingpane_shadow.xml
similarity index 82%
rename from res/drawable-xhdpi/es_slidingpane_shadow.xml
rename to res/drawable/es_slidingpane_shadow.xml
index cc711819e..34cc44bf4 100644
--- a/res/drawable-xhdpi/es_slidingpane_shadow.xml
+++ b/res/drawable/es_slidingpane_shadow.xml
@@ -2,6 +2,6 @@
+ android:startColor="#eeeeee" />
\ No newline at end of file
diff --git a/res/drawable-xhdpi/section_header.xml b/res/drawable/section_header.xml
similarity index 100%
rename from res/drawable-xhdpi/section_header.xml
rename to res/drawable/section_header.xml
diff --git a/res/layout/fragment_conversations_overview.xml b/res/layout/fragment_conversations_overview.xml
index ae60de40a..5548cce62 100644
--- a/res/layout/fragment_conversations_overview.xml
+++ b/res/layout/fragment_conversations_overview.xml
@@ -6,7 +6,9 @@
+ android:orientation="vertical"
+ android:background="#eeeeee"
+ >
diff --git a/src/de/gultsch/chat/entities/Contact.java b/src/de/gultsch/chat/entities/Contact.java
index 30dfc05bc..66221f8a3 100644
--- a/src/de/gultsch/chat/entities/Contact.java
+++ b/src/de/gultsch/chat/entities/Contact.java
@@ -20,9 +20,8 @@ public class Contact implements Serializable {
return this.display_name;
}
- public Uri getProfilePhoto() {
- if (photo == null) return null;
- return Uri.parse(photo);
+ public String getProfilePhoto() {
+ return photo;
}
public String getJid() {
diff --git a/src/de/gultsch/chat/entities/Conversation.java b/src/de/gultsch/chat/entities/Conversation.java
index a00dd476a..10eb70797 100644
--- a/src/de/gultsch/chat/entities/Conversation.java
+++ b/src/de/gultsch/chat/entities/Conversation.java
@@ -33,10 +33,9 @@ public class Conversation extends AbstractEntity {
private transient List messages = null;
- public Conversation(String name, Uri profilePhoto, Account account,
+ public Conversation(String name, String profilePhoto, Account account,
String contactJid) {
- this(java.util.UUID.randomUUID().toString(), name, profilePhoto
- .toString(), account.getUuid(), contactJid, System
+ this(java.util.UUID.randomUUID().toString(), name, profilePhoto, account.getUuid(), contactJid, System
.currentTimeMillis(), STATUS_AVAILABLE);
}
diff --git a/src/de/gultsch/chat/ui/ConversationActivity.java b/src/de/gultsch/chat/ui/ConversationActivity.java
index d831f9b8b..79d1e218f 100644
--- a/src/de/gultsch/chat/ui/ConversationActivity.java
+++ b/src/de/gultsch/chat/ui/ConversationActivity.java
@@ -9,6 +9,7 @@ import de.gultsch.chat.R;
import de.gultsch.chat.R.id;
import de.gultsch.chat.entities.Conversation;
import de.gultsch.chat.utils.Beautifier;
+import android.net.Uri;
import android.os.Bundle;
import android.app.FragmentTransaction;
import android.content.Context;
@@ -106,6 +107,16 @@ public class ConversationActivity extends XmppActivity {
((TextView) view.findViewById(R.id.conversation_lastmsg)).setText(getItem(position).getLatestMessage());
((TextView) view.findViewById(R.id.conversation_lastupdate))
.setText(Beautifier.readableTimeDifference(getItem(position).getLatestMessageDate()));
+
+ Uri profilePhoto = getItem(position).getProfilePhotoUri();
+ ImageView imageView = (ImageView) view.findViewById(R.id.conversation_image);
+ if (profilePhoto!=null) {
+ imageView.setImageURI(profilePhoto);
+ } else {
+ imageView.setImageBitmap(Beautifier.getUnknownContactPicture(getItem(position).getName(),200));
+ }
+
+
((ImageView) view.findViewById(R.id.conversation_image))
.setImageURI(getItem(position).getProfilePhotoUri());
return view;
diff --git a/src/de/gultsch/chat/ui/NewConversationActivity.java b/src/de/gultsch/chat/ui/NewConversationActivity.java
index 9df5d5eb8..b8061b23e 100644
--- a/src/de/gultsch/chat/ui/NewConversationActivity.java
+++ b/src/de/gultsch/chat/ui/NewConversationActivity.java
@@ -9,7 +9,9 @@ import de.gultsch.chat.R;
import de.gultsch.chat.entities.Account;
import de.gultsch.chat.entities.Contact;
import de.gultsch.chat.entities.Conversation;
+import de.gultsch.chat.utils.Beautifier;
import de.gultsch.chat.utils.Validator;
+import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.text.Editable;
@@ -74,8 +76,7 @@ public class NewConversationActivity extends XmppActivity {
if (Validator.isValidJid(searchString)) {
String name = searchString.split("@")[0];
- Contact newContact = new Contact(name, searchString,
- DEFAULT_PROFILE_PHOTO);
+ Contact newContact = new Contact(name, searchString,null);
aggregatedContacts.add(newContact);
contactsHeader.setText("Create new contact");
} else {
@@ -100,8 +101,6 @@ public class NewConversationActivity extends XmppActivity {
+ "\") AND (" + ContactsContract.CommonDataKinds.Im.PROTOCOL
+ "=\"" + ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER
+ "\")";
- protected static final String DEFAULT_PROFILE_PHOTO = "android.resource://de.gultsch.chat/"
- + R.drawable.ic_profile;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -150,8 +149,13 @@ public class NewConversationActivity extends XmppActivity {
.setText(getItem(position).getDisplayName());
((TextView) view.findViewById(R.id.contact_jid))
.setText(getItem(position).getJid());
- ((ImageView) view.findViewById(R.id.contact_photo))
- .setImageURI(getItem(position).getProfilePhoto());
+ String profilePhoto = getItem(position).getProfilePhoto();
+ ImageView imageView = (ImageView) view.findViewById(R.id.contact_photo);
+ if (profilePhoto!=null) {
+ imageView.setImageURI(Uri.parse(profilePhoto));
+ } else {
+ imageView.setImageBitmap(Beautifier.getUnknownContactPicture(getItem(position).getDisplayName(),90));
+ }
return view;
}
};
@@ -222,9 +226,9 @@ public class NewConversationActivity extends XmppActivity {
while (cursor.moveToNext()) {
String profilePhoto = cursor.getString(cursor
.getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI));
- if (profilePhoto == null) {
+ /*if (profilePhoto == null) {
profilePhoto = DEFAULT_PROFILE_PHOTO;
- }
+ }*/
Contact contact = new Contact(
cursor.getString(cursor
.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)),
diff --git a/src/de/gultsch/chat/utils/Beautifier.java b/src/de/gultsch/chat/utils/Beautifier.java
index 43b7acc2c..5184c0c79 100644
--- a/src/de/gultsch/chat/utils/Beautifier.java
+++ b/src/de/gultsch/chat/utils/Beautifier.java
@@ -3,18 +3,24 @@ package de.gultsch.chat.utils;
import java.text.SimpleDateFormat;
import java.util.Date;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.util.DisplayMetrics;
+
public class Beautifier {
public static String readableTimeDifference(long time) {
- if (time==0) {
+ if (time == 0) {
return "just now";
}
Date date = new Date(time);
long difference = (System.currentTimeMillis() - time) / 1000;
- if (difference<60) {
+ if (difference < 60) {
return "just now";
- } else if (difference<60*10) {
+ } else if (difference < 60 * 10) {
return difference / 60 + " min ago";
- } else if (difference<60*60*24) {
+ } else if (difference < 60 * 60 * 24) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
return sdf.format(date);
} else {
@@ -22,4 +28,33 @@ public class Beautifier {
return sdf.format(date);
}
}
+
+ 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];
+
+ Bitmap bitmap = Bitmap
+ .createBitmap(size, size, Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(bitmap);
+
+ bitmap.eraseColor(color);
+
+ Paint paint = new Paint();
+ paint.setColor(0xffe5e5e5);
+ paint.setTextSize((float) (size * 0.9));
+ paint.setAntiAlias(true);
+ Rect rect = new Rect();
+ paint.getTextBounds(firstLetter, 0, 1, rect);
+ float width = paint.measureText(firstLetter);
+ canvas.drawText(firstLetter, (size / 2) - (width / 2), (size / 2)
+ + (rect.height() / 2), paint);
+
+ return bitmap;
+ }
}
diff --git a/src/de/gultsch/chat/xml/Element.java b/src/de/gultsch/chat/xml/Element.java
index d6d1b23d7..af3d8f1ff 100644
--- a/src/de/gultsch/chat/xml/Element.java
+++ b/src/de/gultsch/chat/xml/Element.java
@@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
+import android.util.Log;
+
public class Element {
protected String name;
protected Hashtable attributes = new Hashtable();
@@ -26,6 +28,15 @@ public class Element {
return this;
}
+ public boolean hasChild(String name) {
+ for(Element child : this.children) {
+ if (child.getName().equals(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public Element setAttribute(String name, String value) {
this.attributes.put(name, value);
return this;
@@ -36,6 +47,14 @@ public class Element {
return this;
}
+ public String getAttribute(String name) {
+ if (this.attributes.containsKey(name)) {
+ return this.attributes.get(name);
+ } else {
+ return null;
+ }
+ }
+
public String toString() {
StringBuilder elementOutput = new StringBuilder();
if ((content==null)&&(children.size() == 0)) {
diff --git a/src/de/gultsch/chat/xmpp/IqPacket.java b/src/de/gultsch/chat/xmpp/IqPacket.java
index eec66a64f..d7672540d 100644
--- a/src/de/gultsch/chat/xmpp/IqPacket.java
+++ b/src/de/gultsch/chat/xmpp/IqPacket.java
@@ -12,9 +12,8 @@ public class IqPacket extends Element {
super(name);
}
- public IqPacket(String id, int type) {
+ public IqPacket(int type) {
super("iq");
- this.setAttribute("id",id);
switch (type) {
case TYPE_SET:
this.setAttribute("type", "set");
@@ -34,4 +33,8 @@ public class IqPacket extends Element {
super("iq");
}
+ public String getId() {
+ return this.getAttribute("id");
+ }
+
}
diff --git a/src/de/gultsch/chat/xmpp/OnIqPacketReceived.java b/src/de/gultsch/chat/xmpp/OnIqPacketReceived.java
new file mode 100644
index 000000000..5e69b0cea
--- /dev/null
+++ b/src/de/gultsch/chat/xmpp/OnIqPacketReceived.java
@@ -0,0 +1,5 @@
+package de.gultsch.chat.xmpp;
+
+public interface OnIqPacketReceived {
+ public void onIqPacketReceived(IqPacket packet);
+}
diff --git a/src/de/gultsch/chat/xmpp/OnMessagePacketReceived.java b/src/de/gultsch/chat/xmpp/OnMessagePacketReceived.java
new file mode 100644
index 000000000..9f4e6317b
--- /dev/null
+++ b/src/de/gultsch/chat/xmpp/OnMessagePacketReceived.java
@@ -0,0 +1,5 @@
+package de.gultsch.chat.xmpp;
+
+public interface OnMessagePacketReceived {
+ public void onMessagePacketReceived(MessagePacket packet);
+}
diff --git a/src/de/gultsch/chat/xmpp/OnPresencePacketReceived.java b/src/de/gultsch/chat/xmpp/OnPresencePacketReceived.java
new file mode 100644
index 000000000..d48c430da
--- /dev/null
+++ b/src/de/gultsch/chat/xmpp/OnPresencePacketReceived.java
@@ -0,0 +1,5 @@
+package de.gultsch.chat.xmpp;
+
+public interface OnPresencePacketReceived {
+ public void onPresencePacketReceived(PresencePacket packet);
+}
diff --git a/src/de/gultsch/chat/xmpp/XmppConnection.java b/src/de/gultsch/chat/xmpp/XmppConnection.java
index de35a0ea0..a167bd87f 100644
--- a/src/de/gultsch/chat/xmpp/XmppConnection.java
+++ b/src/de/gultsch/chat/xmpp/XmppConnection.java
@@ -7,6 +7,7 @@ import java.math.BigInteger;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.SecureRandom;
+import java.util.Hashtable;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
@@ -35,12 +36,19 @@ public class XmppConnection implements Runnable {
private XmlReader tagReader;
private TagWriter tagWriter;
- private boolean isTlsEncrypted = true;
+ private boolean isTlsEncrypted = false;
private boolean isAuthenticated = false;
+ private boolean shouldUseTLS = false;
+ private boolean shouldReConnect = true;
+ private boolean shouldBind = true;
+ private boolean shouldAuthenticate = true;
+ private Element streamFeatures;
private static final int PACKET_IQ = 0;
private static final int PACKET_MESSAGE = 1;
private static final int PACKET_PRESENCE = 2;
+
+ private Hashtable iqPacketCallbacks = new Hashtable();
public XmppConnection(Account account, PowerManager pm) {
this.account = account;
@@ -58,17 +66,6 @@ public class XmppConnection implements Runnable {
tagWriter.setOutputStream(out);
InputStream in = socket.getInputStream();
tagReader.setInputStream(in);
- } catch (UnknownHostException e) {
- Log.d(LOGTAG, "error during connect. unknown host");
- } catch (IOException e) {
- Log.d(LOGTAG, "error during connect. io exception. falscher port?");
- }
- }
-
- @Override
- public void run() {
- connect();
- try {
tagWriter.beginDocument();
sendStartStream();
Tag nextTag;
@@ -77,14 +74,25 @@ public class XmppConnection implements Runnable {
processStream(nextTag);
} else {
Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName());
+ return;
}
}
- } catch (XmlPullParserException e) {
- Log.d(LOGTAG,
- "xml error during normal read. maybe missformed xml? "
- + e.getMessage());
+ } catch (UnknownHostException e) {
+ Log.d(LOGTAG, "error during connect. unknown host");
+ return;
} catch (IOException e) {
- Log.d(LOGTAG, "io exception during read. connection lost?");
+ Log.d(LOGTAG, "error during connect. io exception. falscher port?");
+ return;
+ } catch (XmlPullParserException e) {
+ Log.d(LOGTAG,"xml exception "+e.getMessage());
+ return;
+ }
+ }
+
+ @Override
+ public void run() {
+ while(shouldReConnect) {
+ connect();
}
}
@@ -92,20 +100,11 @@ public class XmppConnection implements Runnable {
IOException {
Log.d(LOGTAG, "process Stream");
Tag nextTag;
- while ((nextTag = tagReader.readTag()) != null) {
+ while (!(nextTag = tagReader.readTag()).isEnd("stream")) {
if (nextTag.isStart("error")) {
processStreamError(nextTag);
} else if (nextTag.isStart("features")) {
processStreamFeatures(nextTag);
- if (!isTlsEncrypted) {
- sendStartTLS();
- }
- if ((!isAuthenticated) && (isTlsEncrypted)) {
- sendSaslAuth();
- }
- if ((isAuthenticated)&&(isTlsEncrypted)) {
- sendBindRequest();
- }
} else if (nextTag.isStart("proceed")) {
switchOverToTls(nextTag);
} else if (nextTag.isStart("success")) {
@@ -121,8 +120,6 @@ public class XmppConnection implements Runnable {
Log.d(LOGTAG,processMessage(nextTag).toString());
} else if (nextTag.isStart("presence")) {
Log.d(LOGTAG,processPresence(nextTag).toString());
- } else if (nextTag.isEnd("stream")) {
- break;
} else {
Log.d(LOGTAG, "found unexpected tag: " + nextTag.getName()
+ " as child of " + currentTag.getName());
@@ -159,7 +156,12 @@ public class XmppConnection implements Runnable {
private IqPacket processIq(Tag currentTag) throws XmlPullParserException, IOException {
- return (IqPacket) processPacket(currentTag,PACKET_IQ);
+ IqPacket packet = (IqPacket) processPacket(currentTag,PACKET_IQ);
+ if (iqPacketCallbacks.containsKey(packet.getId())) {
+ iqPacketCallbacks.get(packet.getId()).onIqPacketReceived(packet);
+ iqPacketCallbacks.remove(packet.getId());
+ }
+ return packet;
}
private MessagePacket processMessage(Tag currentTag) throws XmlPullParserException, IOException {
@@ -212,47 +214,44 @@ public class XmppConnection implements Runnable {
private void processStreamFeatures(Tag currentTag)
throws XmlPullParserException, IOException {
- Log.d(LOGTAG, "processStreamFeatures");
-
- Element streamFeatures = new Element("features");
-
- Tag nextTag = tagReader.readTag();
- while(!nextTag.isEnd("features")) {
- Element element = tagReader.readElement(nextTag);
- streamFeatures.addChild(element);
- nextTag = tagReader.readTag();
+ this.streamFeatures = tagReader.readElement(currentTag);
+ Log.d(LOGTAG,"process stream features "+streamFeatures);
+ if (this.streamFeatures.hasChild("starttls")&&shouldUseTLS) {
+ sendStartTLS();
+ }
+ if (this.streamFeatures.hasChild("mechanisms")&&shouldAuthenticate) {
+ sendSaslAuth();
+ }
+ if (this.streamFeatures.hasChild("bind")&&shouldBind) {
+ sendBindRequest();
+ if (this.streamFeatures.hasChild("session")) {
+ IqPacket startSession = new IqPacket(IqPacket.TYPE_SET);
+ Element session = new Element("session");
+ session.setAttribute("xmlns","urn:ietf:params:xml:ns:xmpp-session");
+ session.setContent("");
+ startSession.addChild(session);
+ sendIqPacket(startSession, null);
+ tagWriter.writeElement(startSession);
+ tagWriter.flush();
+ }
+ Element presence = new Element("presence");
+
+ tagWriter.writeElement(presence);
+ tagWriter.flush();
}
- Log.d(LOGTAG,streamFeatures.toString());
}
private void sendBindRequest() throws IOException {
- IqPacket iq = new IqPacket(nextRandomId(),IqPacket.TYPE_SET);
+ IqPacket iq = new IqPacket(IqPacket.TYPE_SET);
Element bind = new Element("bind");
bind.setAttribute("xmlns","urn:ietf:params:xml:ns:xmpp-bind");
iq.addChild(bind);
- //Element resource = new Element("resource");
- //resource.setContent("mobile");
- //bind.addChild(resource);
- Log.d(LOGTAG,"sending bind request: "+iq.toString());
- tagWriter.writeElement(iq);
- tagWriter.flush();
-
-
- //technically not bind stuff
- IqPacket startSession = new IqPacket(this.nextRandomId(), IqPacket.TYPE_SET);
- Element session = new Element("session");
- session.setAttribute("xmlns","urn:ietf:params:xml:ns:xmpp-session");
- session.setContent("");
- startSession.addChild(session);
-
- tagWriter.writeElement(startSession);
- tagWriter.flush();
-
- Element presence = new Element("presence");
-
- tagWriter.writeElement(presence);
- tagWriter.flush();
-
+ this.sendIqPacket(iq, new OnIqPacketReceived() {
+ @Override
+ public void onIqPacketReceived(IqPacket packet) {
+ Log.d(LOGTAG,"answer for our bind was: "+packet.toString());
+ }
+ });
}
private void processStreamError(Tag currentTag) {
@@ -273,4 +272,15 @@ public class XmppConnection implements Runnable {
private String nextRandomId() {
return new BigInteger(50, random).toString(32);
}
+
+ public void sendIqPacket(IqPacket packet, OnIqPacketReceived callback) throws IOException {
+ String id = nextRandomId();
+ packet.setAttribute("id",id);
+ tagWriter.writeElement(packet);
+ tagWriter.flush();
+ if (callback != null) {
+ iqPacketCallbacks.put(id, callback);
+ }
+ Log.d(LOGTAG,"sending: "+packet.toString());
+ }
}