diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/de/gultsch/chat/entities/Contact.java | 5 | ||||
-rw-r--r-- | src/de/gultsch/chat/entities/Conversation.java | 5 | ||||
-rw-r--r-- | src/de/gultsch/chat/ui/ConversationActivity.java | 11 | ||||
-rw-r--r-- | src/de/gultsch/chat/ui/NewConversationActivity.java | 20 | ||||
-rw-r--r-- | src/de/gultsch/chat/utils/Beautifier.java | 43 | ||||
-rw-r--r-- | src/de/gultsch/chat/xml/Element.java | 19 | ||||
-rw-r--r-- | src/de/gultsch/chat/xmpp/IqPacket.java | 7 | ||||
-rw-r--r-- | src/de/gultsch/chat/xmpp/OnIqPacketReceived.java | 5 | ||||
-rw-r--r-- | src/de/gultsch/chat/xmpp/OnMessagePacketReceived.java | 5 | ||||
-rw-r--r-- | src/de/gultsch/chat/xmpp/OnPresencePacketReceived.java | 5 | ||||
-rw-r--r-- | src/de/gultsch/chat/xmpp/XmppConnection.java | 138 |
11 files changed, 179 insertions, 84 deletions
diff --git a/src/de/gultsch/chat/entities/Contact.java b/src/de/gultsch/chat/entities/Contact.java index 30dfc05b..66221f8a 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 a00dd476..10eb7079 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<Message> 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 d831f9b8..79d1e218 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 9df5d5eb..b8061b23 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 43b7acc2..5184c0c7 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 d6d1b23d..af3d8f1f 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<String, String> attributes = new Hashtable<String, String>(); @@ -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 eec66a64..d7672540 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 00000000..5e69b0ce --- /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 00000000..9f4e6317 --- /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 00000000..d48c430d --- /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 de35a0ea..a167bd87 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<String, OnIqPacketReceived> iqPacketCallbacks = new Hashtable<String, OnIqPacketReceived>(); 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()); + } } |