diff --git a/ring-android/app/src/main/java/cx/ring/model/Conference.java b/ring-android/app/src/main/java/cx/ring/model/Conference.java
index 0a423dcf75ec1f199d79a183f0cd35ead3992f2c..e742bdf6edd109e91b0424eb8b694d37032b15db 100644
--- a/ring-android/app/src/main/java/cx/ring/model/Conference.java
+++ b/ring-android/app/src/main/java/cx/ring/model/Conference.java
@@ -33,11 +33,22 @@ package cx.ring.model;
 
 import java.util.ArrayList;
 
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.support.v4.app.NotificationCompat;
+import android.support.v4.app.NotificationManagerCompat;
+import android.util.Log;
 
 import java.util.Random;
-import java.util.concurrent.ThreadLocalRandom;
+
+import cx.ring.R;
+import cx.ring.client.CallActivity;
+import cx.ring.service.DRingService;
 
 public class Conference implements Parcelable {
 
@@ -46,8 +57,9 @@ public class Conference implements Parcelable {
     private ArrayList<SipCall> participants;
     private boolean recording;
     private ArrayList<TextMessage> messages;
-
     public int notificationId;
+    // true if this conference is currently presented to the user.
+    public boolean mVisible = false;
 
     private final static Random rand = new Random();
 
@@ -170,6 +182,7 @@ public class Conference implements Parcelable {
         id = cID;
         participants = new ArrayList<>();
         recording = false;
+        notificationId = rand.nextInt();
         messages = new ArrayList<>();
     }
 
@@ -178,14 +191,15 @@ public class Conference implements Parcelable {
         mConfState = c.mConfState;
         participants = new ArrayList<>(c.participants);
         recording = c.recording;
+        notificationId = c.notificationId;
         messages = new ArrayList<>();
     }
 
     public String getId() {
-        if(hasMultipleParticipants())
-            return id;
-        else
+        if (participants.size() == 1)
             return participants.get(0).getCallId();
+        else
+            return id;
     }
 
     public String getState() {
@@ -305,4 +319,83 @@ public class Conference implements Parcelable {
         participants.add(part);
     }
 
+
+    public void showCallNotification(Context ctx)
+    {
+        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(ctx);
+        notificationManager.cancel(notificationId);
+
+        if (getParticipants().isEmpty())
+            return;
+        SipCall call = getParticipants().get(0);
+        CallContact contact = call.getContact();
+
+        NotificationCompat.Builder noti = new NotificationCompat.Builder(ctx);
+        if (isOnGoing()) {
+            noti.setContentTitle("Current call with " + contact.getDisplayName())
+                    .setContentText("call")
+                    .setContentIntent(PendingIntent.getActivity(ctx, new Random().nextInt(),
+                            new Intent(ctx, CallActivity.class).putExtra("conference", this), PendingIntent.FLAG_ONE_SHOT))
+                    .addAction(R.drawable.ic_call_end_white_24dp, "Hangup",
+                            PendingIntent.getService(ctx, new Random().nextInt(),
+                                    new Intent(ctx, DRingService.class)
+                                            .setAction(DRingService.ACTION_CALL_END)
+                                            .putExtra("conf", call.getCallId()),
+                                    PendingIntent.FLAG_ONE_SHOT));
+            Log.w("CallNotification ", "Updating " + notificationId + " for " + contact.getDisplayName());
+        } else if (isRinging()) {
+            if (isIncoming()) {
+                PendingIntent goto_intent = PendingIntent.getActivity(ctx, new Random().nextInt(),
+                        new Intent(ctx, CallActivity.class).putExtra("conference", this), PendingIntent.FLAG_ONE_SHOT);
+                noti.setContentTitle("Incoming call from " + contact.getDisplayName())
+                        .setPriority(NotificationCompat.PRIORITY_MAX)
+                        .setContentText("incoming call")
+                        .setContentIntent(goto_intent)
+                        .setFullScreenIntent(goto_intent, true)
+                        .addAction(R.drawable.ic_action_accept, "Accept",
+                                PendingIntent.getService(ctx, new Random().nextInt(),
+                                        new Intent(ctx, DRingService.class)
+                                                .setAction(DRingService.ACTION_CALL_ACCEPT)
+                                                .putExtra("conf", call.getCallId()),
+                                        PendingIntent.FLAG_ONE_SHOT))
+                        .addAction(R.drawable.ic_call_end_white_24dp, "Refuse",
+                                PendingIntent.getService(ctx, new Random().nextInt(),
+                                        new Intent(ctx, DRingService.class)
+                                                .setAction(DRingService.ACTION_CALL_REFUSE)
+                                                .putExtra("conf", call.getCallId()),
+                                        PendingIntent.FLAG_ONE_SHOT));
+                Log.w("CallNotification ", "Updating for incoming " + call.getCallId() + " " + notificationId);
+            } else {
+                noti.setContentTitle("Outgoing call with " + contact.getDisplayName())
+                        .setContentText("Outgoing call")
+                        .setContentIntent(PendingIntent.getActivity(ctx, new Random().nextInt(),
+                                new Intent(ctx, CallActivity.class).putExtra("conference", this), PendingIntent.FLAG_ONE_SHOT))
+                        .addAction(R.drawable.ic_call_end_white_24dp, "Cancel",
+                                PendingIntent.getService(ctx, new Random().nextInt(),
+                                        new Intent(ctx, DRingService.class)
+                                                .setAction(DRingService.ACTION_CALL_END)
+                                                .putExtra("conf", call.getCallId()),
+                                        PendingIntent.FLAG_ONE_SHOT));
+            }
+
+        } else {
+            notificationManager.cancel(notificationId);
+            return;
+        }
+
+        noti.setOngoing(true).setCategory(NotificationCompat.CATEGORY_CALL).setSmallIcon(R.drawable.ic_launcher);
+
+        if (contact.getPhoto() != null) {
+            Resources res = ctx.getResources();
+            int height = (int) res.getDimension(android.R.dimen.notification_large_icon_height);
+            int width = (int) res.getDimension(android.R.dimen.notification_large_icon_width);
+            noti.setLargeIcon(Bitmap.createScaledBitmap(contact.getPhoto(), width, height, false));
+        }
+
+        //mService.startForeground(toAdd.notificationId, noti);
+        notificationManager.notify(notificationId, noti.build());
+    }
+
+
+
 }
diff --git a/ring-android/app/src/main/java/cx/ring/service/LocalService.java b/ring-android/app/src/main/java/cx/ring/service/LocalService.java
index 1c79d80a8f282c092bdb16f4148c8d8af100dd33..7086cc5f2427a7e0b840a77d4fd4f6931532dd23 100644
--- a/ring-android/app/src/main/java/cx/ring/service/LocalService.java
+++ b/ring-android/app/src/main/java/cx/ring/service/LocalService.java
@@ -868,7 +868,12 @@ public class LocalService extends Service
     }
 
     private void updated(Map<String, Conversation> res) {
-        Log.w(TAG, "Conversation list updated");
+        NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
+        for (Conversation conv : conversations.values()) {
+            for (Conference c : conv.current_calls) {
+                notificationManager.cancel(c.notificationId);
+            }
+        }
         conversations = res;
         sendBroadcast(new Intent(ACTION_CONF_UPDATE));
     }
@@ -1013,6 +1018,7 @@ public class LocalService extends Service
                     }
 
                     conv.addConference(toAdd);
+                    toAdd.showCallNotification(LocalService.this);
                     break;
                 }
                 case CallManagerCallBack.CALL_STATE_CHANGED: {
@@ -1048,6 +1054,8 @@ public class LocalService extends Service
                             NotificationManagerCompat notificationManager = NotificationManagerCompat.from(LocalService.this);
                             notificationManager.cancel(found.notificationId);
                             found.removeParticipant(call);
+                        } else {
+                            found.showCallNotification(LocalService.this);
                         }
                         if (new_state == SipCall.State.HUNGUP) {
                             call.setTimestampEnd(System.currentTimeMillis());