# HG changeset patch # User Da Risk # Date 1344569919 -7200 # Node ID 46b16746d8a273700375de3a4436cbe8c0431269 # Parent e818646525da13d91ec8ae202e226178ebbb18f5 Improve notification by using NotificationCompat.Builder diff -r e818646525da -r 46b16746d8a2 src/com/beem/project/beem/BeemService.java --- a/src/com/beem/project/beem/BeemService.java Tue Jul 24 18:30:07 2012 +0200 +++ b/src/com/beem/project/beem/BeemService.java Fri Aug 10 05:38:39 2012 +0200 @@ -223,8 +223,8 @@ if (!"".equals(tmpPort)) mPort = Integer.parseInt(tmpPort); } - if (mSettings.getBoolean(BeemApplication.FULL_JID_LOGIN_KEY, false) || - "gmail.com".equals(mService) || "googlemail.com".equals(mService)) { + if (mSettings.getBoolean(BeemApplication.FULL_JID_LOGIN_KEY, false) + || "gmail.com".equals(mService) || "googlemail.com".equals(mService)) { mLogin = tmpJid; } @@ -291,8 +291,9 @@ notif.ledARGB = 0xff0000ff; // Blue color notif.ledOnMS = 1000; notif.ledOffMS = 1000; - notif.defaults |= Notification.DEFAULT_LIGHTS; - String ringtoneStr = mSettings.getString(BeemApplication.NOTIFICATION_SOUND_KEY, Settings.System.DEFAULT_NOTIFICATION_URI.toString()); + notif.flags |= Notification.FLAG_SHOW_LIGHTS; + String ringtoneStr = mSettings.getString(BeemApplication.NOTIFICATION_SOUND_KEY, + Settings.System.DEFAULT_NOTIFICATION_URI.toString()); notif.sound = Uri.parse(ringtoneStr); mNotificationManager.notify(id, notif); } diff -r e818646525da -r 46b16746d8a2 src/com/beem/project/beem/service/BeemChatManager.java --- a/src/com/beem/project/beem/service/BeemChatManager.java Tue Jul 24 18:30:07 2012 +0200 +++ b/src/com/beem/project/beem/service/BeemChatManager.java Fri Aug 10 05:38:39 2012 +0200 @@ -44,12 +44,37 @@ package com.beem.project.beem.service; import java.io.File; +import java.io.FileNotFoundException; +import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import android.app.PendingIntent; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.os.Environment; +import android.os.RemoteCallbackList; +import android.os.RemoteException; +import android.preference.PreferenceManager; +import android.support.v4.app.NotificationCompat; +import android.util.Log; + +import com.beem.project.beem.BeemApplication; +import com.beem.project.beem.BeemService; +import com.beem.project.beem.R; +import com.beem.project.beem.providers.AvatarProvider; +import com.beem.project.beem.service.aidl.IChat; +import com.beem.project.beem.service.aidl.IChatManager; +import com.beem.project.beem.service.aidl.IChatManagerListener; +import com.beem.project.beem.service.aidl.IMessageListener; +import com.beem.project.beem.service.aidl.IRoster; +import com.beem.project.beem.utils.Status; + import net.java.otr4j.OtrException; import org.jivesoftware.smack.Chat; @@ -60,25 +85,6 @@ import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.util.StringUtils; -import android.app.Notification; -import android.app.PendingIntent; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Environment; -import android.os.RemoteCallbackList; -import android.os.RemoteException; -import android.preference.PreferenceManager; -import android.util.Log; - -import com.beem.project.beem.BeemApplication; -import com.beem.project.beem.BeemService; -import com.beem.project.beem.service.aidl.IChat; -import com.beem.project.beem.service.aidl.IChatManager; -import com.beem.project.beem.service.aidl.IChatManagerListener; -import com.beem.project.beem.service.aidl.IMessageListener; -import com.beem.project.beem.service.aidl.IRoster; -import com.beem.project.beem.utils.Status; - /** * An adapter for smack's ChatManager. This class provides functionnality to handle chats. * @author darisk @@ -92,6 +98,7 @@ private final RemoteCallbackList mRemoteChatCreationListeners = new RemoteCallbackList(); private final BeemService mService; + private final Roster mRoster; private final ChatRosterListener mChatRosterListn = new ChatRosterListener(); /** @@ -103,7 +110,8 @@ public BeemChatManager(final ChatManager chatManager, final BeemService service, final Roster roster) { mService = service; mAdaptee = chatManager; - roster.addRosterListener(mChatRosterListn); + mRoster = roster; + mRoster.addRosterListener(mChatRosterListn); mAdaptee.addChatListener(mChatListener); } @@ -212,11 +220,10 @@ */ public List getOpenedChatList() throws RemoteException { List openedChats = new ArrayList(); - IRoster mRoster = mService.getBind().getRoster(); - + IRoster r = mService.getBind().getRoster(); for (ChatAdapter chat : mChats.values()) { if (chat.getMessages().size() > 0) { - Contact t = mRoster.getContact(chat.getParticipant().getJID()); + Contact t = r.getContact(chat.getParticipant().getJID()); if (t == null) t = new Contact(chat.getParticipant().getJID()); openedChats.add(t); @@ -294,21 +301,48 @@ * @param msgBody the body of the new message */ private void notifyNewChat(IChat chat, String msgBody) { - SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(mService); + NotificationCompat.Builder notif = new NotificationCompat.Builder(mService); try { - CharSequence tickerText = mService.getBind().getRoster().getContact(chat.getParticipant().getJID()) - .getName(); - Notification notification = new Notification(android.R.drawable.stat_notify_chat, tickerText, System - .currentTimeMillis()); - notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS; - notification.setLatestEventInfo(mService, tickerText, msgBody, makeChatIntent(chat)); - mService.sendNotification(chat.getParticipant().getJID().hashCode(), notification); + String contactJid = chat.getParticipant().getJID(); + Contact c = mService.getBind().getRoster().getContact(contactJid); + String contactName = contactJid; + if (c != null) { + contactName = c.getName(); + Bitmap avatar = getAvatar(c); + notif.setLargeIcon(avatar); + } + notif.setTicker(contactName).setContentTitle(contactName); + notif.setContentText(msgBody); + notif.setSmallIcon(R.drawable.beem_status_icon_gray); + notif.setNumber(chat.getUnreadMessageCount()); + notif.setContentIntent(makeChatIntent(chat)); + notif.setAutoCancel(true).setWhen(System.currentTimeMillis()); + mService.sendNotification(chat.getParticipant().getJID().hashCode(), notif.getNotification()); } catch (RemoteException e) { Log.e(TAG, e.getMessage()); } } /** + * Get the avatar of a contact. + * @param c the contact + * @return the avatar of c or null if avatar is not defined + */ + private Bitmap getAvatar(Contact c) { + String id = c.getAvatarId(); + if (id == null) + id = ""; + Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(id).build(); + try { + InputStream in = mService.getContentResolver().openInputStream(uri); + return BitmapFactory.decodeStream(in); + } catch (FileNotFoundException e) { + Log.d(TAG, "Error loading avatar id: " + id, e); + return null; + } + } + + /** * {@inheritDoc} */ @Override diff -r e818646525da -r 46b16746d8a2 src/com/beem/project/beem/service/ChatAdapter.java --- a/src/com/beem/project/beem/service/ChatAdapter.java Tue Jul 24 18:30:07 2012 +0200 +++ b/src/com/beem/project/beem/service/ChatAdapter.java Fri Aug 10 05:38:39 2012 +0200 @@ -50,6 +50,15 @@ import java.util.LinkedList; import java.util.List; +import android.os.Environment; +import android.os.RemoteCallbackList; +import android.os.RemoteException; +import android.util.Log; + +import com.beem.project.beem.otr.BeemOtrManager; +import com.beem.project.beem.service.aidl.IChat; +import com.beem.project.beem.service.aidl.IMessageListener; + import net.java.otr4j.OtrException; import net.java.otr4j.session.SessionID; @@ -59,15 +68,6 @@ import org.jivesoftware.smackx.ChatState; import org.jivesoftware.smackx.ChatStateListener; -import android.os.Environment; -import android.os.RemoteCallbackList; -import android.os.RemoteException; -import android.util.Log; - -import com.beem.project.beem.otr.BeemOtrManager; -import com.beem.project.beem.service.aidl.IChat; -import com.beem.project.beem.service.aidl.IMessageListener; - /** * An adapter for smack's Chat class. * @author darisk @@ -88,6 +88,7 @@ private boolean mIsHistory; private File mHistoryPath; private String mAccountUser; + private int mUnreadMsgCount; /** * Constructor. @@ -204,6 +205,8 @@ @Override public void setOpen(boolean isOpen) { this.mIsOpen = isOpen; + if (isOpen) + mUnreadMsgCount = 0; } /** @@ -230,6 +233,8 @@ if (mMessages.size() == HISTORY_MAX_SIZE) mMessages.remove(0); mMessages.add(msg); + if (!isOpen()) + mUnreadMsgCount++; if (!"".equals(msg.getBody()) && msg.getBody() != null) { logMessage(msg); } @@ -327,7 +332,8 @@ if (mOtrSessionId != null && unencrypted != null && unencrypted.getBody() != null) { try { - String body = BeemOtrManager.getInstance().getOtrManager().transformSending(mOtrSessionId, unencrypted.getBody()); + String body = BeemOtrManager.getInstance().getOtrManager() + .transformSending(mOtrSessionId, unencrypted.getBody()); Message result = new Message(unencrypted.getTo(), unencrypted.getType()); result.setBody(body); return result; @@ -339,67 +345,6 @@ } /** - * Listener. - */ - private class MsgListener implements ChatStateListener { - /** - * Constructor. - */ - public MsgListener() { - } - - @Override - public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) { - Message msg = new Message(message); - Log.d(TAG, "new msg " + msg.getBody()); - String body; - - if (mOtrSessionId != null) { - try { - body = BeemOtrManager.getInstance().getOtrManager() - .transformReceiving(mOtrSessionId, msg.getBody()); - msg.setBody(body); - } catch (OtrException e) { - Log.w(TAG, "Unable to decrypt OTR message", e); - } - } - //TODO add que les message pas de type errors - ChatAdapter.this.addMessage(msg); - final int n = mRemoteListeners.beginBroadcast(); - for (int i = 0; i < n; i++) { - IMessageListener listener = mRemoteListeners.getBroadcastItem(i); - try { - if (listener != null) - listener.processMessage(ChatAdapter.this, msg); - } catch (RemoteException e) { - Log.w(TAG, "Error while diffusing message to listener", e); - } - } - mRemoteListeners.finishBroadcast(); - } - - /** - * {@inheritDoc} - */ - @Override - public void stateChanged(Chat chat, ChatState state) { - mState = state.name(); - final int n = mRemoteListeners.beginBroadcast(); - - for (int i = 0; i < n; i++) { - IMessageListener listener = mRemoteListeners.getBroadcastItem(i); - try { - listener.stateChanged(ChatAdapter.this); - } catch (RemoteException e) { - Log.w(TAG, e.getMessage()); - } - } - mRemoteListeners.finishBroadcast(); - } - - } - - /** * This method is executed when the otr session status change. * @param otrState the new state of otr session. */ @@ -462,6 +407,9 @@ return true; } + /** + * Start listenning to an OTR session. + */ public void listenOtrSession() { if (mOtrSessionId != null) return; @@ -504,4 +452,71 @@ return null; return BeemOtrManager.getInstance().getOtrManager().getSessionStatus(mOtrSessionId).toString(); } + + @Override + public int getUnreadMessageCount() throws RemoteException { + return mUnreadMsgCount; + } + + /** + * Listener. + */ + private class MsgListener implements ChatStateListener { + /** + * Constructor. + */ + public MsgListener() { + } + + @Override + public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) { + Message msg = new Message(message); + Log.d(TAG, "new msg " + msg.getBody()); + String body; + + if (mOtrSessionId != null) { + try { + body = BeemOtrManager.getInstance().getOtrManager() + .transformReceiving(mOtrSessionId, msg.getBody()); + msg.setBody(body); + } catch (OtrException e) { + Log.w(TAG, "Unable to decrypt OTR message", e); + } + } + //TODO add que les message pas de type errors + ChatAdapter.this.addMessage(msg); + final int n = mRemoteListeners.beginBroadcast(); + for (int i = 0; i < n; i++) { + IMessageListener listener = mRemoteListeners.getBroadcastItem(i); + try { + if (listener != null) + listener.processMessage(ChatAdapter.this, msg); + } catch (RemoteException e) { + Log.w(TAG, "Error while diffusing message to listener", e); + } + } + mRemoteListeners.finishBroadcast(); + } + + /** + * {@inheritDoc} + */ + @Override + public void stateChanged(Chat chat, ChatState state) { + mState = state.name(); + final int n = mRemoteListeners.beginBroadcast(); + + for (int i = 0; i < n; i++) { + IMessageListener listener = mRemoteListeners.getBroadcastItem(i); + try { + listener.stateChanged(ChatAdapter.this); + } catch (RemoteException e) { + Log.w(TAG, e.getMessage()); + } + } + mRemoteListeners.finishBroadcast(); + } + + } + } diff -r e818646525da -r 46b16746d8a2 src/com/beem/project/beem/service/XmppConnectionAdapter.java --- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java Tue Jul 24 18:30:07 2012 +0200 +++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java Fri Aug 10 05:38:39 2012 +0200 @@ -53,6 +53,7 @@ import android.content.SharedPreferences; import android.os.RemoteCallbackList; import android.os.RemoteException; +import android.support.v4.app.NotificationCompat; import android.util.Log; import com.beem.project.beem.BeemApplication; @@ -119,7 +120,8 @@ private BeemAvatarManager mAvatarManager; private PepSubManager mPepManager; private SharedPreferences mPref; - private final RemoteCallbackList mRemoteConnListeners = new RemoteCallbackList(); + private final RemoteCallbackList mRemoteConnListeners = + new RemoteCallbackList(); private final SubscribePacketListener mSubscribePacketListener = new SubscribePacketListener(); private final PingListener mPingListener = new PingListener(); @@ -665,25 +667,7 @@ } }; - mAdaptee.addPacketListener(new PacketListener() { - - @Override - public void processPacket(Packet packet) { - String from = packet.getFrom(); - Notification notif = new Notification(android.R.drawable.stat_notify_more, mService.getString( - R.string.AcceptContactRequest, from), System.currentTimeMillis()); - notif.flags = Notification.FLAG_AUTO_CANCEL; - Intent intent = new Intent(mService, Subscription.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).putExtra("from", from); - notif.setLatestEventInfo(mService, from, - mService.getString(R.string.AcceptContactRequestFrom, from), - PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT)); - int id = packet.hashCode(); - mService.sendNotification(id, notif); - Presence p = (Presence) packet; - updateNotification(Status.getStatusFromPresence(p), p.getStatus()); - } - }, filter); + mAdaptee.addPacketListener(mSubscribePacketListener, filter); final int n = mRemoteConnListeners.beginBroadcast(); @@ -716,22 +700,24 @@ @Override public void processPacket(Packet packet) { - if (!(packet instanceof Presence)) - return; - Presence p = (Presence) packet; - if (p.getType() != Presence.Type.subscribe) - return; - String from = p.getFrom(); - Notification notification = new Notification(android.R.drawable.stat_notify_more, mService.getString( - R.string.AcceptContactRequest, from), System.currentTimeMillis()); - notification.flags = Notification.FLAG_AUTO_CANCEL; + String from = packet.getFrom(); + + NotificationCompat.Builder notif = new NotificationCompat.Builder(mService); + String title = mService.getString(R.string.AcceptContactRequest, from); + String text = mService.getString(R.string.AcceptContactRequestFrom, from); + notif.setTicker(title).setContentTitle(title); + notif.setContentText(text); + notif.setSmallIcon(R.drawable.beem_status_icon_gray); + notif.setAutoCancel(true).setWhen(System.currentTimeMillis()); + Intent intent = new Intent(mService, Subscription.class); intent.setData(Contact.makeXmppUri(from)); - notification.setLatestEventInfo(mService, from, - mService.getString(R.string.AcceptContactRequestFrom, from), - PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT)); - int id = p.hashCode(); - mService.sendNotification(id, notification); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + PendingIntent notifIntent = PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT); + notif.setContentIntent(notifIntent); + + int id = packet.hashCode(); + mService.sendNotification(id, notif.getNotification()); } } diff -r e818646525da -r 46b16746d8a2 src/com/beem/project/beem/service/aidl/IChat.aidl --- a/src/com/beem/project/beem/service/aidl/IChat.aidl Tue Jul 24 18:30:07 2012 +0200 +++ b/src/com/beem/project/beem/service/aidl/IChat.aidl Fri Aug 10 05:38:39 2012 +0200 @@ -82,38 +82,40 @@ boolean isOpen(); + int getUnreadMessageCount(); + void setState(in String state); List getMessages(); - + /** * Try to start an OTR session. */ void startOtrSession(); - + /** * Stop the OTR session. */ void endOtrSession(); - + /** * get local OTR key fingerprints. */ String getLocalOtrFingerprint(); - - + + /** * get remote OTR key fingerprints. */ String getRemoteOtrFingerprint(); - + void verifyRemoteFingerprint(in boolean ok); - - + + /** * get current OTR status. */ String getOtrStatus(); - + }