Better notifications for JB + improved shadowed avatar
This commit is contained in:
parent
427ed76520
commit
2d2e14647f
4 changed files with 161 additions and 43 deletions
|
@ -17,8 +17,8 @@
|
||||||
android:layout_height="100dp"
|
android:layout_height="100dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:contentDescription="@string/content_description_contact_picture"
|
android:contentDescription="@string/content_description_contact_picture"
|
||||||
android:src="@drawable/unknown_small"
|
android:scaleType="fitEnd"
|
||||||
android:scaleType="fitCenter" />
|
android:src="@drawable/unknown_small" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="25dp"
|
android:layout_width="25dp"
|
||||||
|
|
|
@ -22,15 +22,19 @@ import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.linphone.LinphoneManager.NewOutgoingCallUiListener;
|
import org.linphone.LinphoneManager.NewOutgoingCallUiListener;
|
||||||
import org.linphone.LinphoneSimpleListener.LinphoneServiceListener;
|
import org.linphone.LinphoneSimpleListener.LinphoneServiceListener;
|
||||||
|
import org.linphone.compatibility.Compatibility;
|
||||||
|
import org.linphone.core.LinphoneAddress;
|
||||||
import org.linphone.core.LinphoneCall;
|
import org.linphone.core.LinphoneCall;
|
||||||
import org.linphone.core.LinphoneCall.State;
|
import org.linphone.core.LinphoneCall.State;
|
||||||
import org.linphone.core.LinphoneCore;
|
import org.linphone.core.LinphoneCore;
|
||||||
import org.linphone.core.LinphoneCore.GlobalState;
|
import org.linphone.core.LinphoneCore.GlobalState;
|
||||||
import org.linphone.core.LinphoneCore.RegistrationState;
|
import org.linphone.core.LinphoneCore.RegistrationState;
|
||||||
import org.linphone.core.LinphoneCoreException;
|
import org.linphone.core.LinphoneCoreException;
|
||||||
|
import org.linphone.core.LinphoneCoreFactoryImpl;
|
||||||
import org.linphone.core.LinphoneProxyConfig;
|
import org.linphone.core.LinphoneProxyConfig;
|
||||||
import org.linphone.core.Log;
|
import org.linphone.core.Log;
|
||||||
import org.linphone.core.OnlineStatus;
|
import org.linphone.core.OnlineStatus;
|
||||||
|
@ -46,6 +50,8 @@ import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.media.MediaPlayer;
|
import android.media.MediaPlayer;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
|
@ -54,6 +60,7 @@ import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
import android.provider.MediaStore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -81,6 +88,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
||||||
private boolean mTestDelayElapsed = true; // no timer
|
private boolean mTestDelayElapsed = true; // no timer
|
||||||
private WifiManager mWifiManager ;
|
private WifiManager mWifiManager ;
|
||||||
private WifiLock mWifiLock ;
|
private WifiLock mWifiLock ;
|
||||||
|
private List<Notification> messagesNotifications;
|
||||||
public static boolean isReady() {
|
public static boolean isReady() {
|
||||||
return instance!=null && instance.mTestDelayElapsed;
|
return instance!=null && instance.mTestDelayElapsed;
|
||||||
}
|
}
|
||||||
|
@ -103,6 +111,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
||||||
private Notification mNotif;
|
private Notification mNotif;
|
||||||
private Notification mIncallNotif;
|
private Notification mIncallNotif;
|
||||||
private Notification mMsgNotif;
|
private Notification mMsgNotif;
|
||||||
|
private Notification mCustomNotif;
|
||||||
private int mMsgNotifCount;
|
private int mMsgNotifCount;
|
||||||
private PendingIntent mNotifContentIntent;
|
private PendingIntent mNotifContentIntent;
|
||||||
private String mNotificationTitle;
|
private String mNotificationTitle;
|
||||||
|
@ -192,33 +201,45 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
||||||
private synchronized void setIncallIcon(IncallIconState state) {
|
private synchronized void setIncallIcon(IncallIconState state) {
|
||||||
if (state == mCurrentIncallIconState) return;
|
if (state == mCurrentIncallIconState) return;
|
||||||
mCurrentIncallIconState = state;
|
mCurrentIncallIconState = state;
|
||||||
if (mIncallNotif == null) mIncallNotif = new Notification();
|
|
||||||
|
|
||||||
int notificationTextId = 0;
|
int notificationTextId = 0;
|
||||||
|
int inconId = 0;
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case IDLE:
|
case IDLE:
|
||||||
mNM.cancel(INCALL_NOTIF_ID);
|
mNM.cancel(INCALL_NOTIF_ID);
|
||||||
return;
|
return;
|
||||||
case INCALL:
|
case INCALL:
|
||||||
mIncallNotif.icon = R.drawable.conf_unhook;
|
inconId = R.drawable.conf_unhook;
|
||||||
notificationTextId = R.string.incall_notif_active;
|
notificationTextId = R.string.incall_notif_active;
|
||||||
break;
|
break;
|
||||||
case PAUSE:
|
case PAUSE:
|
||||||
mIncallNotif.icon = R.drawable.conf_status_paused;
|
inconId = R.drawable.conf_status_paused;
|
||||||
notificationTextId = R.string.incall_notif_paused;
|
notificationTextId = R.string.incall_notif_paused;
|
||||||
break;
|
break;
|
||||||
case VIDEO:
|
case VIDEO:
|
||||||
mIncallNotif.icon = R.drawable.conf_video;
|
inconId = R.drawable.conf_video;
|
||||||
notificationTextId = R.string.incall_notif_video;
|
notificationTextId = R.string.incall_notif_video;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown state " + state);
|
throw new IllegalArgumentException("Unknown state " + state);
|
||||||
}
|
}
|
||||||
|
|
||||||
mIncallNotif.iconLevel = 0;
|
String userName = LinphoneManager.getLc().getCurrentCall().getRemoteAddress().getUserName();
|
||||||
mIncallNotif.when=System.currentTimeMillis();
|
String domain = LinphoneManager.getLc().getCurrentCall().getRemoteAddress().getDomain();
|
||||||
mIncallNotif.flags &= Notification.FLAG_ONGOING_EVENT;
|
String displayName = LinphoneManager.getLc().getCurrentCall().getRemoteAddress().getDisplayName();
|
||||||
mIncallNotif.setLatestEventInfo(this, mNotificationTitle, getString(notificationTextId), mNotifContentIntent);
|
LinphoneAddress address = LinphoneCoreFactoryImpl.instance().createLinphoneAddress("sip:" + userName + "@" + domain);
|
||||||
|
address.setDisplayName(displayName);
|
||||||
|
|
||||||
|
Uri pictureUri = LinphoneUtils.findUriPictureOfContactAndSetDisplayName(address, getContentResolver());
|
||||||
|
Bitmap bm = null;
|
||||||
|
try {
|
||||||
|
bm = MediaStore.Images.Media.getBitmap(getContentResolver(), pictureUri);
|
||||||
|
} catch (Exception e) {
|
||||||
|
bm = BitmapFactory.decodeResource(getResources(), R.drawable.unknown_small);
|
||||||
|
}
|
||||||
|
mIncallNotif = Compatibility.createInCallNotification(getApplicationContext(), mNotificationTitle, getString(notificationTextId), inconId, bm, mNotifContentIntent);
|
||||||
|
|
||||||
notifyWrapper(INCALL_NOTIF_ID, mIncallNotif);
|
notifyWrapper(INCALL_NOTIF_ID, mIncallNotif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,22 +264,22 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
||||||
public void addNotification(Intent onClickIntent, int iconResourceID, String title, String message) {
|
public void addNotification(Intent onClickIntent, int iconResourceID, String title, String message) {
|
||||||
PendingIntent notifContentIntent = PendingIntent.getActivity(this, 0, onClickIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
PendingIntent notifContentIntent = PendingIntent.getActivity(this, 0, onClickIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||||
|
|
||||||
if (mMsgNotif == null) {
|
if (mCustomNotif == null) {
|
||||||
mMsgNotif = new Notification();
|
mCustomNotif = new Notification();
|
||||||
}
|
}
|
||||||
|
|
||||||
mMsgNotif.icon = iconResourceID;
|
mCustomNotif.icon = iconResourceID;
|
||||||
mMsgNotif.iconLevel = 0;
|
mCustomNotif.iconLevel = 0;
|
||||||
mMsgNotif.when = System.currentTimeMillis();
|
mCustomNotif.when = System.currentTimeMillis();
|
||||||
mMsgNotif.flags &= Notification.FLAG_ONGOING_EVENT;
|
mCustomNotif.flags &= Notification.FLAG_ONGOING_EVENT;
|
||||||
|
|
||||||
mMsgNotif.defaults |= Notification.DEFAULT_VIBRATE;
|
mCustomNotif.defaults |= Notification.DEFAULT_VIBRATE;
|
||||||
mMsgNotif.defaults |= Notification.DEFAULT_SOUND;
|
mCustomNotif.defaults |= Notification.DEFAULT_SOUND;
|
||||||
mMsgNotif.defaults |= Notification.DEFAULT_LIGHTS;
|
mCustomNotif.defaults |= Notification.DEFAULT_LIGHTS;
|
||||||
|
|
||||||
mMsgNotif.setLatestEventInfo(this, title, message, notifContentIntent);
|
mCustomNotif.setLatestEventInfo(this, title, message, notifContentIntent);
|
||||||
|
|
||||||
notifyWrapper(CUSTOM_NOTIF_ID, mMsgNotif);
|
notifyWrapper(CUSTOM_NOTIF_ID, mCustomNotif);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayMessageNotification(String fromSipUri, String fromName, String message) {
|
public void displayMessageNotification(String fromSipUri, String fromName, String message) {
|
||||||
|
@ -274,27 +295,19 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
|
||||||
|
|
||||||
if (mMsgNotif == null) {
|
if (mMsgNotif == null) {
|
||||||
mMsgNotifCount = 1;
|
mMsgNotifCount = 1;
|
||||||
mMsgNotif = new Notification();
|
|
||||||
|
|
||||||
mMsgNotif.icon = R.drawable.chat_icon_over;
|
|
||||||
mMsgNotif.iconLevel = 0;
|
|
||||||
mMsgNotif.when = System.currentTimeMillis();
|
|
||||||
mMsgNotif.flags &= Notification.FLAG_ONGOING_EVENT;
|
|
||||||
|
|
||||||
mMsgNotif.defaults |= Notification.DEFAULT_VIBRATE;
|
|
||||||
mMsgNotif.defaults |= Notification.DEFAULT_SOUND;
|
|
||||||
mMsgNotif.defaults |= Notification.DEFAULT_LIGHTS;
|
|
||||||
|
|
||||||
String title = "New message from %s :".replace("%s", fromName);
|
|
||||||
mMsgNotif.setLatestEventInfo(this, title, message, notifContentIntent);
|
|
||||||
} else {
|
} else {
|
||||||
mMsgNotifCount++;
|
mMsgNotifCount++;
|
||||||
mMsgNotif.when = System.currentTimeMillis();
|
|
||||||
|
|
||||||
String title = mMsgNotifCount + " new messages from %s".replace("%s", fromName);
|
|
||||||
mMsgNotif.setLatestEventInfo(this, title, "", notifContentIntent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Uri pictureUri = LinphoneUtils.findUriPictureOfContactAndSetDisplayName(LinphoneCoreFactoryImpl.instance().createLinphoneAddress(fromSipUri), getContentResolver());
|
||||||
|
Bitmap bm = null;
|
||||||
|
try {
|
||||||
|
bm = MediaStore.Images.Media.getBitmap(getContentResolver(), pictureUri);
|
||||||
|
} catch (Exception e) {
|
||||||
|
bm = BitmapFactory.decodeResource(getResources(), R.drawable.unknown_small);
|
||||||
|
}
|
||||||
|
mMsgNotif = Compatibility.createMessageNotification(getApplicationContext(), mMsgNotifCount, fromName, message, bm, notifContentIntent);
|
||||||
|
|
||||||
notifyWrapper(MESSAGE_NOTIF_ID, mMsgNotif);
|
notifyWrapper(MESSAGE_NOTIF_ID, mMsgNotif);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
57
src/org/linphone/compatibility/ApiSixteenPlus.java
Normal file
57
src/org/linphone/compatibility/ApiSixteenPlus.java
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
package org.linphone.compatibility;
|
||||||
|
|
||||||
|
import org.linphone.R;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
@TargetApi(16)
|
||||||
|
public class ApiSixteenPlus {
|
||||||
|
|
||||||
|
public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
||||||
|
String title, summary;
|
||||||
|
if (msgCount == 1) {
|
||||||
|
title = "Unread message from %s".replace("%s", msgSender);
|
||||||
|
summary = "";
|
||||||
|
} else {
|
||||||
|
title = "%i unread messages".replace("%i", String.valueOf(msgCount));
|
||||||
|
summary = "+" + (msgCount - 1) + " more";
|
||||||
|
}
|
||||||
|
|
||||||
|
Notification notif = new Notification.BigPictureStyle(
|
||||||
|
new Notification.Builder(context)
|
||||||
|
.setContentTitle(title)
|
||||||
|
.setContentText(msg)
|
||||||
|
.setSmallIcon(R.drawable.chat_icon_default)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
|
||||||
|
.setWhen(System.currentTimeMillis())
|
||||||
|
.setLargeIcon(contactIcon))
|
||||||
|
.setSummaryText(summary)
|
||||||
|
.build();
|
||||||
|
notif.contentIntent = intent;
|
||||||
|
|
||||||
|
return notif;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Notification createInCallNotification(Context context,
|
||||||
|
String title, String msg, int iconID, Bitmap contactIcon,
|
||||||
|
PendingIntent intent) {
|
||||||
|
|
||||||
|
Notification notif = new Notification.BigPictureStyle(
|
||||||
|
new Notification.Builder(context)
|
||||||
|
.setContentTitle(title)
|
||||||
|
.setContentText(msg)
|
||||||
|
.setSmallIcon(iconID)
|
||||||
|
.setAutoCancel(false)
|
||||||
|
.setWhen(System.currentTimeMillis())
|
||||||
|
.setLargeIcon(contactIcon))
|
||||||
|
.build();
|
||||||
|
notif.contentIntent = intent;
|
||||||
|
|
||||||
|
return notif;
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,13 +21,18 @@ import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.linphone.Contact;
|
import org.linphone.Contact;
|
||||||
|
import org.linphone.R;
|
||||||
import org.linphone.core.LinphoneAddress;
|
import org.linphone.core.LinphoneAddress;
|
||||||
import org.linphone.mediastream.Version;
|
import org.linphone.mediastream.Version;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
/**
|
/**
|
||||||
* @author Sylvain Berfini
|
* @author Sylvain Berfini
|
||||||
|
@ -119,4 +124,47 @@ public class Compatibility {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
||||||
|
Notification notif = null;
|
||||||
|
String title;
|
||||||
|
if (msgCount == 1) {
|
||||||
|
title = "Unread message from %s".replace("%s", msgSender);
|
||||||
|
} else {
|
||||||
|
title = "%i unread messages".replace("%i", String.valueOf(msgCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Version.sdkAboveOrEqual(16)) {
|
||||||
|
notif = ApiSixteenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent);
|
||||||
|
} else {
|
||||||
|
notif = new Notification();
|
||||||
|
notif.icon = R.drawable.chat_icon_over;
|
||||||
|
notif.iconLevel = 0;
|
||||||
|
notif.when = System.currentTimeMillis();
|
||||||
|
notif.flags &= Notification.FLAG_ONGOING_EVENT;
|
||||||
|
|
||||||
|
notif.defaults |= Notification.DEFAULT_VIBRATE;
|
||||||
|
notif.defaults |= Notification.DEFAULT_SOUND;
|
||||||
|
notif.defaults |= Notification.DEFAULT_LIGHTS;
|
||||||
|
|
||||||
|
notif.setLatestEventInfo(context, title, msg, intent);
|
||||||
|
}
|
||||||
|
return notif;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Notification createInCallNotification(Context context, String title, String msg, int iconID, Bitmap contactIcon, PendingIntent intent) {
|
||||||
|
Notification notif = null;
|
||||||
|
|
||||||
|
if (Version.sdkAboveOrEqual(16)) {
|
||||||
|
notif = ApiSixteenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, intent);
|
||||||
|
} else {
|
||||||
|
notif = new Notification();
|
||||||
|
notif.iconLevel = 0;
|
||||||
|
notif.when=System.currentTimeMillis();
|
||||||
|
notif.flags &= Notification.FLAG_ONGOING_EVENT;
|
||||||
|
|
||||||
|
notif.setLatestEventInfo(context, title, msg, intent);
|
||||||
|
}
|
||||||
|
return notif;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue