Cleaned LinphoneService a bit, moved all notifications related code to another class
This commit is contained in:
parent
886b5a36c0
commit
1e6fb279c0
22 changed files with 595 additions and 525 deletions
|
@ -294,7 +294,7 @@
|
||||||
<activity android:name=".activities.LinphoneGenericActivity"/>
|
<activity android:name=".activities.LinphoneGenericActivity"/>
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".receivers.NotificationBroadcastReceiver"
|
android:name=".notifications.NotificationBroadcastReceiver"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
|
|
|
@ -504,7 +504,7 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou
|
||||||
if (call != null) {
|
if (call != null) {
|
||||||
call.enableCamera(enable);
|
call.enableCamera(enable);
|
||||||
if (mServiceContext.getResources().getBoolean(R.bool.enable_call_notification))
|
if (mServiceContext.getResources().getBoolean(R.bool.enable_call_notification))
|
||||||
LinphoneService.instance().displayCallNotification(mLc.getCurrentCall());
|
LinphoneService.instance().getNotificationManager().displayCallNotification(mLc.getCurrentCall());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1075,16 +1075,16 @@ public class LinphoneManager implements CoreListener, SensorEventListener, Accou
|
||||||
if (!mServiceContext.getResources().getBoolean(R.bool.disable_chat_message_notification) && !message.isOutgoing()) {
|
if (!mServiceContext.getResources().getBoolean(R.bool.disable_chat_message_notification) && !message.isOutgoing()) {
|
||||||
if (cr.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
if (cr.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
||||||
if (contact != null) {
|
if (contact != null) {
|
||||||
LinphoneService.instance().displayMessageNotification(cr.getPeerAddress().asStringUriOnly(), contact.getFullName(), contact.getThumbnailUri(), textMessage, cr.getLocalAddress().asString());
|
LinphoneService.instance().getNotificationManager().displayMessageNotification(cr.getPeerAddress().asStringUriOnly(), contact.getFullName(), contact.getThumbnailUri(), textMessage, cr.getLocalAddress());
|
||||||
} else {
|
} else {
|
||||||
LinphoneService.instance().displayMessageNotification(cr.getPeerAddress().asStringUriOnly(), from.getUsername(), null, textMessage, cr.getLocalAddress().asString());
|
LinphoneService.instance().getNotificationManager().displayMessageNotification(cr.getPeerAddress().asStringUriOnly(), from.getUsername(), null, textMessage, cr.getLocalAddress());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String subject = cr.getSubject();
|
String subject = cr.getSubject();
|
||||||
if (contact != null) {
|
if (contact != null) {
|
||||||
LinphoneService.instance().displayGroupChatMessageNotification(subject, cr.getPeerAddress().asStringUriOnly(), contact.getFullName(), contact.getThumbnailUri(), textMessage, cr.getLocalAddress().asString());
|
LinphoneService.instance().getNotificationManager().displayGroupChatMessageNotification(subject, cr.getPeerAddress().asStringUriOnly(), contact.getFullName(), contact.getThumbnailUri(), textMessage, cr.getLocalAddress());
|
||||||
} else {
|
} else {
|
||||||
LinphoneService.instance().displayGroupChatMessageNotification(subject, cr.getPeerAddress().asStringUriOnly(), from.getUsername(), null, textMessage, cr.getLocalAddress().asString());
|
LinphoneService.instance().getNotificationManager().displayGroupChatMessageNotification(subject, cr.getPeerAddress().asStringUriOnly(), from.getUsername(), null, textMessage, cr.getLocalAddress());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,31 +23,22 @@ import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlarmManager;
|
import android.app.AlarmManager;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.app.Notification;
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
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.net.Uri;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.provider.ContactsContract;
|
import android.provider.ContactsContract;
|
||||||
import android.provider.MediaStore;
|
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import org.linphone.activities.LinphoneActivity;
|
import org.linphone.activities.LinphoneActivity;
|
||||||
import org.linphone.compatibility.Compatibility;
|
|
||||||
import org.linphone.contacts.ContactsManager;
|
import org.linphone.contacts.ContactsManager;
|
||||||
import org.linphone.contacts.LinphoneContact;
|
|
||||||
import org.linphone.core.Address;
|
|
||||||
import org.linphone.core.Call;
|
import org.linphone.core.Call;
|
||||||
import org.linphone.core.Call.State;
|
import org.linphone.core.Call.State;
|
||||||
import org.linphone.core.Core;
|
import org.linphone.core.Core;
|
||||||
|
@ -58,14 +49,12 @@ import org.linphone.core.ProxyConfig;
|
||||||
import org.linphone.core.RegistrationState;
|
import org.linphone.core.RegistrationState;
|
||||||
import org.linphone.mediastream.Log;
|
import org.linphone.mediastream.Log;
|
||||||
import org.linphone.mediastream.Version;
|
import org.linphone.mediastream.Version;
|
||||||
|
import org.linphone.notifications.NotificationsManager;
|
||||||
import org.linphone.receivers.BluetoothManager;
|
import org.linphone.receivers.BluetoothManager;
|
||||||
import org.linphone.receivers.KeepAliveReceiver;
|
import org.linphone.receivers.KeepAliveReceiver;
|
||||||
import org.linphone.ui.LinphoneOverlay;
|
import org.linphone.ui.LinphoneOverlay;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Linphone service, reacting to Incoming calls, ...<br />
|
* Linphone service, reacting to Incoming calls, ...<br />
|
||||||
|
@ -81,14 +70,9 @@ public final class LinphoneService extends Service {
|
||||||
* setLatestEventInfo and startActivity() which needs a context.
|
* setLatestEventInfo and startActivity() which needs a context.
|
||||||
*/
|
*/
|
||||||
public static final String START_LINPHONE_LOGS = " ==== Phone information dump ====";
|
public static final String START_LINPHONE_LOGS = " ==== Phone information dump ====";
|
||||||
public static final int IC_LEVEL_ORANGE = 0;
|
|
||||||
|
|
||||||
private static LinphoneService instance;
|
private static LinphoneService instance;
|
||||||
|
|
||||||
private final static int NOTIF_ID = 1;
|
|
||||||
private final static int CUSTOM_NOTIF_ID = 4;
|
|
||||||
private final static int MISSED_NOTIF_ID = 5;
|
|
||||||
|
|
||||||
public static boolean isReady() {
|
public static boolean isReady() {
|
||||||
return instance != null && instance.mTestDelayElapsed;
|
return instance != null && instance.mTestDelayElapsed;
|
||||||
}
|
}
|
||||||
|
@ -106,38 +90,28 @@ public final class LinphoneService extends Service {
|
||||||
|
|
||||||
// private boolean mTestDelayElapsed; // add a timer for testing
|
// private boolean mTestDelayElapsed; // add a timer for testing
|
||||||
private boolean mTestDelayElapsed = true; // no timer
|
private boolean mTestDelayElapsed = true; // no timer
|
||||||
private NotificationManager mNM;
|
|
||||||
|
|
||||||
private Notification mNotif;
|
|
||||||
private Notification mCustomNotif;
|
|
||||||
private PendingIntent mNotifContentIntent;
|
|
||||||
private String mNotificationTitle;
|
|
||||||
private boolean mDisableRegistrationStatus;
|
|
||||||
private CoreListenerStub mListener;
|
private CoreListenerStub mListener;
|
||||||
public static int notifcationsPriority = (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41) ? Notification.PRIORITY_MIN : 0);
|
|
||||||
private WindowManager mWindowManager;
|
private WindowManager mWindowManager;
|
||||||
private LinphoneOverlay mOverlay;
|
private LinphoneOverlay mOverlay;
|
||||||
private Application.ActivityLifecycleCallbacks activityCallbacks;
|
private Application.ActivityLifecycleCallbacks activityCallbacks;
|
||||||
|
|
||||||
private class Notified {
|
private NotificationsManager mNotificationManager;
|
||||||
int notificationId;
|
|
||||||
int numberOfUnreadMessage;
|
public NotificationsManager getNotificationManager() {
|
||||||
|
return mNotificationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HashMap<String, Notified> mChatNotifMap, mCallNotifMap;
|
private String incomingReceivedActivityName;
|
||||||
private int mLastNotificationId;
|
private Class<? extends Activity> incomingReceivedActivity = LinphoneActivity.class;
|
||||||
|
|
||||||
|
public Class<? extends Activity> getIncomingReceivedActivity() {
|
||||||
|
return incomingReceivedActivity;
|
||||||
|
}
|
||||||
|
|
||||||
public void setCurrentlyDisplayedChatRoom(String address) {
|
public void setCurrentlyDisplayedChatRoom(String address) {
|
||||||
if (address != null) {
|
if (address != null) {
|
||||||
resetMessageNotifCount(address);
|
mNotificationManager.resetMessageNotifCount(address);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resetMessageNotifCount(String address) {
|
|
||||||
Notified notif = mChatNotifMap.get(address);
|
|
||||||
if (notif != null) {
|
|
||||||
notif.numberOfUnreadMessage = 0;
|
|
||||||
mNM.cancel(notif.notificationId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,8 +143,6 @@ public final class LinphoneService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
private InactivityChecker mLastChecker;
|
private InactivityChecker mLastChecker;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -275,31 +247,6 @@ public final class LinphoneService extends Service {
|
||||||
getApplication().registerActivityLifecycleCallbacks(activityCallbacks = new ActivityMonitor());
|
getApplication().registerActivityLifecycleCallbacks(activityCallbacks = new ActivityMonitor());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean displayServiceNotification() {
|
|
||||||
return LinphonePreferences.instance().getServiceNotificationVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showServiceNotification() {
|
|
||||||
startForegroundCompat(NOTIF_ID, mNotif);
|
|
||||||
|
|
||||||
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
|
||||||
if (lc == null) return;
|
|
||||||
ProxyConfig lpc = lc.getDefaultProxyConfig();
|
|
||||||
if (lpc != null) {
|
|
||||||
if (lpc.getState() == RegistrationState.Ok) {
|
|
||||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_registered);
|
|
||||||
} else {
|
|
||||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_register_failure);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_started);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void hideServiceNotification() {
|
|
||||||
stopForegroundCompat(NOTIF_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
super.onStartCommand(intent, flags, startId);
|
super.onStartCommand(intent, flags, startId);
|
||||||
|
@ -309,9 +256,10 @@ public final class LinphoneService extends Service {
|
||||||
return START_REDELIVER_INTENT;
|
return START_REDELIVER_INTENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
LinphoneManager.createAndStart(LinphoneService.this);
|
LinphoneManager.createAndStart(this);
|
||||||
|
|
||||||
instance = this; // instance is ready once linphone manager has been created
|
instance = this; // instance is ready once linphone manager has been created
|
||||||
|
mNotificationManager = new NotificationsManager(this);
|
||||||
LinphoneManager.getLc().addListener(mListener = new CoreListenerStub() {
|
LinphoneManager.getLc().addListener(mListener = new CoreListenerStub() {
|
||||||
@Override
|
@Override
|
||||||
public void onCallStateChanged(Core lc, Call call, Call.State state, String message) {
|
public void onCallStateChanged(Core lc, Call call, Call.State state, String message) {
|
||||||
|
@ -321,7 +269,7 @@ public final class LinphoneService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getResources().getBoolean(R.bool.enable_call_notification)) {
|
if (getResources().getBoolean(R.bool.enable_call_notification)) {
|
||||||
displayCallNotification(call);
|
mNotificationManager.displayCallNotification(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == Call.State.IncomingReceived) {
|
if (state == Call.State.IncomingReceived) {
|
||||||
|
@ -339,58 +287,23 @@ public final class LinphoneService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == State.End && call.getCallLog().getStatus() == Call.Status.Missed) {
|
if (state == State.End && call.getCallLog().getStatus() == Call.Status.Missed) {
|
||||||
int missedCallCount = LinphoneManager.getLcIfManagerNotDestroyedOrNull().getMissedCallsCount();
|
mNotificationManager.displayMissedCallNotification(call);
|
||||||
String body;
|
|
||||||
if (missedCallCount > 1) {
|
|
||||||
body = getString(R.string.missed_calls_notif_body).replace("%i", String.valueOf(missedCallCount));
|
|
||||||
} else {
|
|
||||||
Address address = call.getRemoteAddress();
|
|
||||||
LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address);
|
|
||||||
if (c != null) {
|
|
||||||
body = c.getFullName();
|
|
||||||
} else {
|
|
||||||
body = address.getDisplayName();
|
|
||||||
if (body == null) {
|
|
||||||
body = address.asStringUriOnly();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Intent missedCallNotifIntent = new Intent(LinphoneService.this, incomingReceivedActivity);
|
|
||||||
missedCallNotifIntent.putExtra("GoToHistory", true);
|
|
||||||
PendingIntent intent = PendingIntent.getActivity(LinphoneService.this, 0, missedCallNotifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
||||||
Notification notif = Compatibility.createMissedCallNotification(instance, getString(R.string.missed_calls_notif_title), body, intent);
|
|
||||||
notifyWrapper(MISSED_NOTIF_ID, notif);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onGlobalStateChanged(Core lc, GlobalState state, String message) {
|
public void onGlobalStateChanged(Core lc, GlobalState state, String message) {
|
||||||
if (!mDisableRegistrationStatus && state == GlobalState.On && displayServiceNotification()) {
|
//TODO global state if ON
|
||||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_started);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRegistrationStateChanged(Core lc, ProxyConfig cfg, RegistrationState state, String smessage) {
|
public void onRegistrationStateChanged(Core lc, ProxyConfig cfg, RegistrationState state, String smessage) {
|
||||||
if (!mDisableRegistrationStatus) {
|
//TODO registration status
|
||||||
if (displayServiceNotification() && state == RegistrationState.Ok && LinphoneManager.getLc().getDefaultProxyConfig() != null && LinphoneManager.getLc().getDefaultProxyConfig().getState() == RegistrationState.Ok) {
|
|
||||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_registered);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (displayServiceNotification() && (state == RegistrationState.Failed || state == RegistrationState.Cleared) && (LinphoneManager.getLc().getDefaultProxyConfig() == null || !(LinphoneManager.getLc().getDefaultProxyConfig().getState() == RegistrationState.Ok))) {
|
|
||||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_register_failure);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (displayServiceNotification() && state == RegistrationState.None) {
|
|
||||||
sendNotification(IC_LEVEL_ORANGE, R.string.notification_started);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (displayServiceNotification() || (Version.sdkAboveOrEqual(Version.API26_O_80) && intent.getBooleanExtra("ForceStartForeground", false))) {
|
if (Version.sdkAboveOrEqual(Version.API26_O_80) && intent.getBooleanExtra("ForceStartForeground", false)) {
|
||||||
startForegroundCompat(NOTIF_ID, mNotif);
|
mNotificationManager.startForeground();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Version.sdkAboveOrEqual(Version.API26_O_80)
|
if (!Version.sdkAboveOrEqual(Version.API26_O_80)
|
||||||
|
@ -426,13 +339,8 @@ public final class LinphoneService extends Service {
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
mLastNotificationId = 8; // To not interfere with other notifs ids
|
|
||||||
mChatNotifMap = new HashMap<>();
|
|
||||||
mCallNotifMap = new HashMap<>();
|
|
||||||
|
|
||||||
setupActivityMonitor();
|
setupActivityMonitor();
|
||||||
// In case restart after a crash. Main in LinphoneActivity
|
|
||||||
mNotificationTitle = getString(R.string.service_name);
|
|
||||||
|
|
||||||
// Needed in order for the two next calls to succeed, libraries must have been loaded first
|
// Needed in order for the two next calls to succeed, libraries must have been loaded first
|
||||||
LinphonePreferences.instance().setContext(getBaseContext());
|
LinphonePreferences.instance().setContext(getBaseContext());
|
||||||
|
@ -445,27 +353,6 @@ public final class LinphoneService extends Service {
|
||||||
dumpDeviceInformation();
|
dumpDeviceInformation();
|
||||||
dumpInstalledLinphoneInformation();
|
dumpInstalledLinphoneInformation();
|
||||||
|
|
||||||
//Disable service notification for Android O
|
|
||||||
if ((Version.sdkAboveOrEqual(Version.API26_O_80))) {
|
|
||||||
LinphonePreferences.instance().setServiceNotificationVisibility(false);
|
|
||||||
mDisableRegistrationStatus = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
|
||||||
mNM.cancelAll();
|
|
||||||
Compatibility.createNotificationChannels(this);
|
|
||||||
|
|
||||||
Intent notifIntent = new Intent(this, incomingReceivedActivity);
|
|
||||||
notifIntent.putExtra("Notification", true);
|
|
||||||
mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
||||||
|
|
||||||
Bitmap bm = null;
|
|
||||||
try {
|
|
||||||
bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
mNotif = Compatibility.createNotification(this, mNotificationTitle, "", R.drawable.linphone_notification_icon, R.mipmap.ic_launcher, bm, mNotifContentIntent, true, notifcationsPriority);
|
|
||||||
|
|
||||||
incomingReceivedActivityName = LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived();
|
incomingReceivedActivityName = LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived();
|
||||||
try {
|
try {
|
||||||
incomingReceivedActivity = (Class<? extends Activity>) Class.forName(incomingReceivedActivityName);
|
incomingReceivedActivity = (Class<? extends Activity>) Class.forName(incomingReceivedActivityName);
|
||||||
|
@ -473,13 +360,6 @@ public final class LinphoneService extends Service {
|
||||||
Log.e(e);
|
Log.e(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
mStartForeground = getClass().getMethod("startForeground", mStartFgSign);
|
|
||||||
mStopForeground = getClass().getMethod("stopForeground", mStopFgSign);
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
Log.e(e, "Couldn't find startForeground or stopForeground");
|
|
||||||
}
|
|
||||||
|
|
||||||
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,249 +384,6 @@ public final class LinphoneService extends Service {
|
||||||
mOverlay = null;
|
mOverlay = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displayCallNotification(Call call) {
|
|
||||||
if (call == null) return;
|
|
||||||
|
|
||||||
Address address = call.getRemoteAddress();
|
|
||||||
String addressAsString = address.asStringUriOnly();
|
|
||||||
Notified notif = mCallNotifMap.get(addressAsString);
|
|
||||||
if (notif == null) {
|
|
||||||
notif = new Notified();
|
|
||||||
notif.notificationId = mLastNotificationId;
|
|
||||||
mLastNotificationId += 1;
|
|
||||||
mCallNotifMap.put(addressAsString, notif);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!displayServiceNotification()) {
|
|
||||||
if (call.getCore().getCallsNb() == 0) {
|
|
||||||
hideServiceNotification();
|
|
||||||
} else {
|
|
||||||
showServiceNotification();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int notificationTextId;
|
|
||||||
int iconId;
|
|
||||||
switch (call.getState()) {
|
|
||||||
case Released:
|
|
||||||
case End:
|
|
||||||
mNM.cancel(notif.notificationId);
|
|
||||||
mCallNotifMap.remove(addressAsString);
|
|
||||||
return;
|
|
||||||
case Paused:
|
|
||||||
case PausedByRemote:
|
|
||||||
case Pausing:
|
|
||||||
iconId = R.drawable.topbar_call_notification;
|
|
||||||
notificationTextId = R.string.incall_notif_paused;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (call.getCurrentParams().videoEnabled()) {
|
|
||||||
iconId = R.drawable.topbar_videocall_notification;
|
|
||||||
notificationTextId = R.string.incall_notif_video;
|
|
||||||
} else {
|
|
||||||
iconId = R.drawable.topbar_call_notification;
|
|
||||||
notificationTextId = R.string.incall_notif_active;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
|
|
||||||
Uri pictureUri = contact != null ? contact.getPhotoUri() : null;
|
|
||||||
Bitmap bm;
|
|
||||||
try {
|
|
||||||
bm = MediaStore.Images.Media.getBitmap(getContentResolver(), pictureUri);
|
|
||||||
} catch (Exception e) {
|
|
||||||
bm = BitmapFactory.decodeResource(getResources(), R.drawable.avatar);
|
|
||||||
}
|
|
||||||
String name = LinphoneUtils.getAddressDisplayName(address);
|
|
||||||
|
|
||||||
boolean showAnswerAction = call.getState() == State.IncomingReceived || call.getState() == State.IncomingEarlyMedia;
|
|
||||||
Intent notifIntent = new Intent(this, incomingReceivedActivity);
|
|
||||||
notifIntent.putExtra("Notification", true);
|
|
||||||
mNotifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
||||||
Notification notification = Compatibility.createInCallNotification(getApplicationContext(), notif.notificationId, showAnswerAction, mNotificationTitle, getString(notificationTextId), iconId, bm, name, mNotifContentIntent);
|
|
||||||
|
|
||||||
notifyWrapper(notif.notificationId, notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSipUriForCallNotificationId(int notificationId) {
|
|
||||||
for (String addr : mCallNotifMap.keySet()) {
|
|
||||||
if (mCallNotifMap.get(addr).notificationId == notificationId) {
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public void addNotification(Intent onClickIntent, int iconResourceID, String title, String message) {
|
|
||||||
addCustomNotification(onClickIntent, iconResourceID, title, message, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addCustomNotification(Intent onClickIntent, int iconResourceID, String title, String message, boolean isOngoingEvent) {
|
|
||||||
PendingIntent notifContentIntent = PendingIntent.getActivity(this, 0, onClickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
||||||
|
|
||||||
Bitmap bm = null;
|
|
||||||
try {
|
|
||||||
bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
mCustomNotif = Compatibility.createNotification(this, title, message, iconResourceID, 0, bm, notifContentIntent, isOngoingEvent, notifcationsPriority);
|
|
||||||
|
|
||||||
mCustomNotif.defaults |= Notification.DEFAULT_VIBRATE;
|
|
||||||
mCustomNotif.defaults |= Notification.DEFAULT_SOUND;
|
|
||||||
mCustomNotif.defaults |= Notification.DEFAULT_LIGHTS;
|
|
||||||
|
|
||||||
notifyWrapper(CUSTOM_NOTIF_ID, mCustomNotif);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void displayGroupChatMessageNotification(String subject, String conferenceAddress, String fromName, Uri fromPictureUri, String message, String localIdentity) {
|
|
||||||
Intent notifIntent = new Intent(this, LinphoneActivity.class);
|
|
||||||
notifIntent.putExtra("GoToChat", true);
|
|
||||||
notifIntent.putExtra("ChatContactSipUri", conferenceAddress);
|
|
||||||
notifIntent.putExtra("LocalIdentity", localIdentity);
|
|
||||||
|
|
||||||
PendingIntent notifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
||||||
|
|
||||||
Notified notif = mChatNotifMap.get(conferenceAddress);
|
|
||||||
if (notif != null) {
|
|
||||||
notif.numberOfUnreadMessage += 1;
|
|
||||||
} else {
|
|
||||||
notif = new Notified();
|
|
||||||
notif.numberOfUnreadMessage = 1;
|
|
||||||
notif.notificationId = mLastNotificationId;
|
|
||||||
mLastNotificationId += 1;
|
|
||||||
mChatNotifMap.put(conferenceAddress, notif);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bitmap bm;
|
|
||||||
if (fromPictureUri != null) {
|
|
||||||
try {
|
|
||||||
bm = MediaStore.Images.Media.getBitmap(getContentResolver(), fromPictureUri);
|
|
||||||
} catch (Exception e) {
|
|
||||||
bm = BitmapFactory.decodeResource(getResources(), R.drawable.chat_group_avatar);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bm = BitmapFactory.decodeResource(getResources(), R.drawable.topbar_avatar);
|
|
||||||
}
|
|
||||||
Notification notification = Compatibility.createMessageNotification(getApplicationContext(), notif.notificationId, notif.numberOfUnreadMessage, subject,
|
|
||||||
getString(R.string.group_chat_notif).replace("%1", fromName).replace("%2", message), bm, notifContentIntent);
|
|
||||||
|
|
||||||
notifyWrapper(notif.notificationId, notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void displayMessageNotification(String fromSipUri, String fromName, Uri fromPictureUri, String message, String localIdentity) {
|
|
||||||
Intent notifIntent = new Intent(this, LinphoneActivity.class);
|
|
||||||
notifIntent.putExtra("GoToChat", true);
|
|
||||||
notifIntent.putExtra("ChatContactSipUri", fromSipUri);
|
|
||||||
notifIntent.putExtra("LocalIdentity", localIdentity);
|
|
||||||
PendingIntent notifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
||||||
|
|
||||||
if (fromName == null) {
|
|
||||||
fromName = fromSipUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
Notified notif = mChatNotifMap.get(fromSipUri);
|
|
||||||
if (notif != null) {
|
|
||||||
notif.numberOfUnreadMessage += 1;
|
|
||||||
} else {
|
|
||||||
notif = new Notified();
|
|
||||||
notif.numberOfUnreadMessage = 1;
|
|
||||||
notif.notificationId = mLastNotificationId;
|
|
||||||
mLastNotificationId += 1;
|
|
||||||
mChatNotifMap.put(fromSipUri, notif);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bitmap bm;
|
|
||||||
if (fromPictureUri != null) {
|
|
||||||
try {
|
|
||||||
bm = MediaStore.Images.Media.getBitmap(getContentResolver(), fromPictureUri);
|
|
||||||
} catch (Exception e) {
|
|
||||||
bm = BitmapFactory.decodeResource(getResources(), R.drawable.topbar_avatar);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bm = BitmapFactory.decodeResource(getResources(), R.drawable.topbar_avatar);
|
|
||||||
}
|
|
||||||
Notification notification = Compatibility.createMessageNotification(getApplicationContext(), notif.notificationId, notif.numberOfUnreadMessage, fromName, message, bm, notifContentIntent);
|
|
||||||
|
|
||||||
notifyWrapper(notif.notificationId, notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendNotification(Notification notif, int notificationId) {
|
|
||||||
notifyWrapper(notificationId, notif);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSipUriForNotificationId(int notificationId) {
|
|
||||||
for (String addr : mChatNotifMap.keySet()) {
|
|
||||||
if (mChatNotifMap.get(addr).notificationId == notificationId) {
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void displayInappNotification(String message) {
|
|
||||||
Intent notifIntent = new Intent(this, LinphoneActivity.class);
|
|
||||||
notifIntent.putExtra("GoToInapp", true);
|
|
||||||
|
|
||||||
PendingIntent notifContentIntent = PendingIntent.getActivity(this, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
||||||
mNotif = Compatibility.createSimpleNotification(getApplicationContext(), getString(R.string.inapp_notification_title), message, notifContentIntent);
|
|
||||||
|
|
||||||
notifyWrapper(NOTIF_ID, mNotif);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Class<?>[] mSetFgSign = new Class[]{boolean.class};
|
|
||||||
private static final Class<?>[] mStartFgSign = new Class[]{
|
|
||||||
int.class, Notification.class};
|
|
||||||
private static final Class<?>[] mStopFgSign = new Class[]{boolean.class};
|
|
||||||
|
|
||||||
private Method mStartForeground;
|
|
||||||
private Method mStopForeground;
|
|
||||||
private Object[] mSetForegroundArgs = new Object[1];
|
|
||||||
private Object[] mStartForegroundArgs = new Object[2];
|
|
||||||
private Object[] mStopForegroundArgs = new Object[1];
|
|
||||||
private String incomingReceivedActivityName;
|
|
||||||
private Class<? extends Activity> incomingReceivedActivity = LinphoneActivity.class;
|
|
||||||
|
|
||||||
void invokeMethod(Method method, Object[] args) {
|
|
||||||
try {
|
|
||||||
method.invoke(this, args);
|
|
||||||
} catch (InvocationTargetException e) {
|
|
||||||
// Should not happen.
|
|
||||||
Log.w(e, "Unable to invoke method");
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
// Should not happen.
|
|
||||||
Log.w(e, "Unable to invoke method");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a wrapper around the new startForeground method, using the older
|
|
||||||
* APIs if it is not available.
|
|
||||||
*/
|
|
||||||
void startForegroundCompat(int id, Notification notification) {
|
|
||||||
// If we have the new startForeground API, then use it.
|
|
||||||
if (mStartForeground != null) {
|
|
||||||
mStartForegroundArgs[0] = Integer.valueOf(id);
|
|
||||||
mStartForegroundArgs[1] = notification;
|
|
||||||
invokeMethod(mStartForeground, mStartForegroundArgs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a wrapper around the new stopForeground method, using the older
|
|
||||||
* APIs if it is not available.
|
|
||||||
*/
|
|
||||||
void stopForegroundCompat(int id) {
|
|
||||||
// If we have the new stopForeground API, then use it.
|
|
||||||
if (mStopForeground != null) {
|
|
||||||
mStopForegroundArgs[0] = Boolean.TRUE;
|
|
||||||
invokeMethod(mStopForeground, mStopForegroundArgs);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dumpDeviceInformation() {
|
private void dumpDeviceInformation() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("DEVICE=").append(Build.DEVICE).append("\n");
|
sb.append("DEVICE=").append(Build.DEVICE).append("\n");
|
||||||
|
@ -775,38 +412,6 @@ public final class LinphoneService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void sendNotification(int level, int textId) {
|
|
||||||
String text = getString(textId);
|
|
||||||
if (text.contains("%s") && LinphoneManager.getLc() != null) {
|
|
||||||
// Test for null lc is to avoid a NPE when Android mess up badly with the String resources.
|
|
||||||
ProxyConfig lpc = LinphoneManager.getLc().getDefaultProxyConfig();
|
|
||||||
String id = lpc != null ? lpc.getIdentityAddress().asString() : "";
|
|
||||||
text = String.format(text, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
Bitmap bm = null;
|
|
||||||
try {
|
|
||||||
bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
mNotif = Compatibility.createNotification(this, mNotificationTitle, text, R.drawable.status_level, 0, bm, mNotifContentIntent, true, notifcationsPriority);
|
|
||||||
notifyWrapper(NOTIF_ID, mNotif);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap notifier to avoid setting the linphone icons while the service
|
|
||||||
* is stopping. When the (rare) bug is triggered, the linphone icon is
|
|
||||||
* present despite the service is not running. To trigger it one could
|
|
||||||
* stop linphone as soon as it is started. Transport configured with TLS.
|
|
||||||
*/
|
|
||||||
private synchronized void notifyWrapper(int id, Notification notification) {
|
|
||||||
if (instance != null && notification != null) {
|
|
||||||
mNM.notify(id, notification);
|
|
||||||
} else {
|
|
||||||
Log.i("Service not ready, discarding notification");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBinder onBind(Intent intent) {
|
public IBinder onBind(Intent intent) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -849,8 +454,7 @@ public final class LinphoneService extends Service {
|
||||||
LinphoneManager.destroy();
|
LinphoneManager.destroy();
|
||||||
|
|
||||||
// Make sure our notification is gone.
|
// Make sure our notification is gone.
|
||||||
stopForegroundCompat(NOTIF_ID);
|
mNotificationManager.destroy();
|
||||||
mNM.cancelAll();
|
|
||||||
|
|
||||||
// This will prevent the app from crashing if the service gets killed in background mode
|
// This will prevent the app from crashing if the service gets killed in background mode
|
||||||
if (LinphoneActivity.isInstanciated()) {
|
if (LinphoneActivity.isInstanciated()) {
|
||||||
|
@ -875,8 +479,8 @@ public final class LinphoneService extends Service {
|
||||||
protected void onIncomingReceived() {
|
protected void onIncomingReceived() {
|
||||||
//wakeup linphone
|
//wakeup linphone
|
||||||
startActivity(new Intent()
|
startActivity(new Intent()
|
||||||
.setClass(this, incomingReceivedActivity)
|
.setClass(this, incomingReceivedActivity)
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -698,10 +698,9 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
|
||||||
changeCurrentFragment(FragmentsAvailable.CREATE_CHAT, extras);
|
changeCurrentFragment(FragmentsAvailable.CREATE_CHAT, extras);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void goToChat(String sipUri, Bundle shareInfos, String localIdentity) {
|
public void goToChat(String sipUri, Bundle shareInfos) {
|
||||||
Bundle extras = new Bundle();
|
Bundle extras = new Bundle();
|
||||||
extras.putString("SipUri", sipUri);
|
extras.putString("SipUri", sipUri);
|
||||||
extras.putString("LocalIdentity", localIdentity);
|
|
||||||
|
|
||||||
if (shareInfos != null) {
|
if (shareInfos != null) {
|
||||||
if (shareInfos.getString("fileSharedUri") != null)
|
if (shareInfos.getString("fileSharedUri") != null)
|
||||||
|
@ -1382,9 +1381,6 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
|
||||||
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||||
if (lc != null) {
|
if (lc != null) {
|
||||||
lc.addListener(mListener);
|
lc.addListener(mListener);
|
||||||
if (!LinphoneService.instance().displayServiceNotification()) {
|
|
||||||
lc.refreshRegisters();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTablet()) {
|
if (isTablet()) {
|
||||||
|
@ -1483,12 +1479,11 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
|
||||||
Bundle extras = intent.getExtras();
|
Bundle extras = intent.getExtras();
|
||||||
if (extras != null && extras.getBoolean("GoToChat", false)) {
|
if (extras != null && extras.getBoolean("GoToChat", false)) {
|
||||||
String sipUri = extras.getString("ChatContactSipUri");
|
String sipUri = extras.getString("ChatContactSipUri");
|
||||||
String localIdentity = extras.getString("LocalIdentity");
|
|
||||||
intent.putExtra("DoNotGoToCallActivity", true);
|
intent.putExtra("DoNotGoToCallActivity", true);
|
||||||
if (sipUri == null) {
|
if (sipUri == null) {
|
||||||
goToChatList();
|
goToChatList();
|
||||||
} else {
|
} else {
|
||||||
goToChat(sipUri, extras, localIdentity);
|
goToChat(sipUri, extras);
|
||||||
}
|
}
|
||||||
} else if (extras != null && extras.getBoolean("GoToHistory", false)) {
|
} else if (extras != null && extras.getBoolean("GoToHistory", false)) {
|
||||||
intent.putExtra("DoNotGoToCallActivity", true);
|
intent.putExtra("DoNotGoToCallActivity", true);
|
||||||
|
@ -1496,7 +1491,7 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
|
||||||
} else if (extras != null && extras.getBoolean("GoToInapp", false)) {
|
} else if (extras != null && extras.getBoolean("GoToInapp", false)) {
|
||||||
intent.putExtra("DoNotGoToCallActivity", true);
|
intent.putExtra("DoNotGoToCallActivity", true);
|
||||||
displayInapp();
|
displayInapp();
|
||||||
} else if (extras != null && extras.getBoolean("Notification", false)) {
|
} else if (extras != null && extras.getBoolean("Notifiable", false)) {
|
||||||
if (LinphoneManager.getLc().getCallsNb() > 0) {
|
if (LinphoneManager.getLc().getCallsNb() > 0) {
|
||||||
startIncallActivity();
|
startIncallActivity();
|
||||||
}
|
}
|
||||||
|
@ -1840,9 +1835,9 @@ public class LinphoneActivity extends LinphoneGenericActivity implements OnClick
|
||||||
LinphonePreferences.instance().setInappPopupTime(String.valueOf(newDate));
|
LinphonePreferences.instance().setInappPopupTime(String.valueOf(newDate));
|
||||||
}
|
}
|
||||||
if (isTrialAccount) {
|
if (isTrialAccount) {
|
||||||
LinphoneService.instance().displayInappNotification(String.format(getString(R.string.inapp_notification_trial_expire), date));
|
LinphoneService.instance().getNotificationManager().displayInappNotification(String.format(getString(R.string.inapp_notification_trial_expire), date));
|
||||||
} else {
|
} else {
|
||||||
LinphoneService.instance().displayInappNotification(String.format(getString(R.string.inapp_notification_account_expire), date));
|
LinphoneService.instance().getNotificationManager().displayInappNotification(String.format(getString(R.string.inapp_notification_account_expire), date));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,7 +213,7 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
||||||
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
|
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
|
||||||
if (newState == ChatRoom.State.Created) {
|
if (newState == ChatRoom.State.Created) {
|
||||||
mWaitLayout.setVisibility(View.GONE);
|
mWaitLayout.setVisibility(View.GONE);
|
||||||
LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), mShareInfos, cr.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), mShareInfos);
|
||||||
} else if (newState == ChatRoom.State.CreationFailed) {
|
} else if (newState == ChatRoom.State.CreationFailed) {
|
||||||
mWaitLayout.setVisibility(View.GONE);
|
mWaitLayout.setVisibility(View.GONE);
|
||||||
LinphoneActivity.instance().displayChatRoomError();
|
LinphoneActivity.instance().displayChatRoomError();
|
||||||
|
@ -468,7 +468,7 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
||||||
if (createEncryptedChatRoom && lpc != null && lpc.getConferenceFactoryUri() != null) {
|
if (createEncryptedChatRoom && lpc != null && lpc.getConferenceFactoryUri() != null) {
|
||||||
mChatRoom = lc.findOneToOneChatRoom(lpc.getIdentityAddress(), ca.getAddress(), true);
|
mChatRoom = lc.findOneToOneChatRoom(lpc.getIdentityAddress(), ca.getAddress(), true);
|
||||||
if (mChatRoom != null) {
|
if (mChatRoom != null) {
|
||||||
LinphoneActivity.instance().goToChat(mChatRoom.getPeerAddress().asStringUriOnly(), mShareInfos, mChatRoom.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(mChatRoom.getPeerAddress().asStringUriOnly(), mShareInfos);
|
||||||
} else {
|
} else {
|
||||||
mChatRoom = lc.createClientGroupChatRoom(getString(R.string.dummy_group_chat_subject), !createEncryptedChatRoom, createEncryptedChatRoom);
|
mChatRoom = lc.createClientGroupChatRoom(getString(R.string.dummy_group_chat_subject), !createEncryptedChatRoom, createEncryptedChatRoom);
|
||||||
mChatRoom.addListener(mChatRoomCreationListener);
|
mChatRoom.addListener(mChatRoomCreationListener);
|
||||||
|
@ -487,11 +487,11 @@ public class ChatCreationFragment extends Fragment implements View.OnClickListen
|
||||||
participants[0] = ca.getAddress();
|
participants[0] = ca.getAddress();
|
||||||
mChatRoom.addParticipants(participants);
|
mChatRoom.addParticipants(participants);
|
||||||
} else {
|
} else {
|
||||||
LinphoneActivity.instance().goToChat(mChatRoom.getPeerAddress().asStringUriOnly(), mShareInfos, mChatRoom.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(mChatRoom.getPeerAddress().asStringUriOnly(), mShareInfos);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ChatRoom chatRoom = lc.getChatRoom(ca.getAddress());
|
ChatRoom chatRoom = lc.getChatRoom(ca.getAddress());
|
||||||
LinphoneActivity.instance().goToChat(chatRoom.getPeerAddress().asStringUriOnly(), mShareInfos, chatRoom.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(chatRoom.getPeerAddress().asStringUriOnly(), mShareInfos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -161,7 +161,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
||||||
mChatRoomsAdapter.toggleSelection(position);
|
mChatRoomsAdapter.toggleSelection(position);
|
||||||
} else {
|
} else {
|
||||||
ChatRoom room = (ChatRoom) mChatRoomsAdapter.getItem(position);
|
ChatRoom room = (ChatRoom) mChatRoomsAdapter.getItem(position);
|
||||||
LinphoneActivity.instance().goToChat(room.getPeerAddress().asString(), null, room.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(room.getPeerAddress().asString(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
||||||
ChatRoomsAdapter adapter = (ChatRoomsAdapter) mChatRoomsList.getAdapter();
|
ChatRoomsAdapter adapter = (ChatRoomsAdapter) mChatRoomsList.getAdapter();
|
||||||
if (adapter != null && adapter.getItemCount() > 0) {
|
if (adapter != null && adapter.getItemCount() > 0) {
|
||||||
ChatRoom room = (ChatRoom) adapter.getItem(0);
|
ChatRoom room = (ChatRoom) adapter.getItem(0);
|
||||||
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null, room.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
|
||||||
} else {
|
} else {
|
||||||
LinphoneActivity.instance().displayEmptyFragment();
|
LinphoneActivity.instance().displayEmptyFragment();
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ public class DevicesFragment extends Fragment {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (LinphoneActivity.instance().isTablet()) {
|
if (LinphoneActivity.instance().isTablet()) {
|
||||||
LinphoneActivity.instance().goToChat(mRoomUri, null, mRoom.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(mRoomUri, null);
|
||||||
} else {
|
} else {
|
||||||
LinphoneActivity.instance().onBackPressed();
|
LinphoneActivity.instance().onBackPressed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -951,11 +951,11 @@ public class GroupChatFragment extends Fragment implements ChatRoomListener, Con
|
||||||
if (LinphoneActivity.instance().isOnBackground()) {
|
if (LinphoneActivity.instance().isOnBackground()) {
|
||||||
if (!getResources().getBoolean(R.bool.disable_chat_message_notification)) {
|
if (!getResources().getBoolean(R.bool.disable_chat_message_notification)) {
|
||||||
if (contact != null) {
|
if (contact != null) {
|
||||||
LinphoneService.instance().displayMessageNotification(from.asStringUriOnly(),
|
LinphoneService.instance().getNotificationManager().displayMessageNotification(from.asStringUriOnly(),
|
||||||
contact.getFullName(), contact.getThumbnailUri(), getString(R.string.message_cant_be_decrypted_notif), cr.getLocalAddress().asString());
|
contact.getFullName(), contact.getThumbnailUri(), getString(R.string.message_cant_be_decrypted_notif), cr.getLocalAddress());
|
||||||
} else {
|
} else {
|
||||||
LinphoneService.instance().displayMessageNotification(from.asStringUriOnly(),
|
LinphoneService.instance().getNotificationManager().displayMessageNotification(from.asStringUriOnly(),
|
||||||
from.getUsername(), null, getString(R.string.message_cant_be_decrypted_notif), cr.getLocalAddress().asString());
|
from.getUsername(), null, getString(R.string.message_cant_be_decrypted_notif), cr.getLocalAddress());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (LinphoneManager.getLc().limeEnabled() == LimeState.Mandatory) {
|
} else if (LinphoneManager.getLc().limeEnabled() == LimeState.Mandatory) {
|
||||||
|
|
|
@ -159,7 +159,7 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (mIsAlreadyCreatedGroup) {
|
if (mIsAlreadyCreatedGroup) {
|
||||||
if (LinphoneActivity.instance().isTablet()) {
|
if (LinphoneActivity.instance().isTablet()) {
|
||||||
LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asStringUriOnly(), mShareInfos, mChatRoom.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asStringUriOnly(), mShareInfos);
|
||||||
} else {
|
} else {
|
||||||
getFragmentManager().popBackStack();
|
getFragmentManager().popBackStack();
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (mChatRoom != null) {
|
if (mChatRoom != null) {
|
||||||
mChatRoom.leave();
|
mChatRoom.leave();
|
||||||
LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asString(), null, mChatRoom.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asString(), null);
|
||||||
} else {
|
} else {
|
||||||
Log.e("Can't leave, chatRoom for address " + mGroupChatRoomAddress.asString() + " is null...");
|
Log.e("Can't leave, chatRoom for address " + mGroupChatRoomAddress.asString() + " is null...");
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,7 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
||||||
// This will remove both the creation fragment and the group info fragment from the back stack
|
// This will remove both the creation fragment and the group info fragment from the back stack
|
||||||
getFragmentManager().popBackStack();
|
getFragmentManager().popBackStack();
|
||||||
getFragmentManager().popBackStack();
|
getFragmentManager().popBackStack();
|
||||||
LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), mShareInfos, cr.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), mShareInfos);
|
||||||
} else if (newState == ChatRoom.State.CreationFailed) {
|
} else if (newState == ChatRoom.State.CreationFailed) {
|
||||||
mWaitLayout.setVisibility(View.GONE);
|
mWaitLayout.setVisibility(View.GONE);
|
||||||
LinphoneActivity.instance().displayChatRoomError();
|
LinphoneActivity.instance().displayChatRoomError();
|
||||||
|
@ -322,7 +322,7 @@ public class GroupInfoFragment extends Fragment implements ChatRoomListener {
|
||||||
toAdd.toArray(participantsToAdd);
|
toAdd.toArray(participantsToAdd);
|
||||||
mChatRoom.addParticipants(participantsToAdd);
|
mChatRoom.addParticipants(participantsToAdd);
|
||||||
|
|
||||||
LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asString(), null, mChatRoom.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(mGroupChatRoomAddress.asString(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class ImdnFragment extends Fragment {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
if (LinphoneActivity.instance().isTablet()) {
|
if (LinphoneActivity.instance().isTablet()) {
|
||||||
LinphoneActivity.instance().goToChat(mRoomUri, null, mRoom.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(mRoomUri, null);
|
||||||
} else {
|
} else {
|
||||||
LinphoneActivity.instance().onBackPressed();
|
LinphoneActivity.instance().onBackPressed();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,23 +2,22 @@ package org.linphone.compatibility;
|
||||||
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.FragmentTransaction;
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationChannel;
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.RemoteInput;
|
import android.app.RemoteInput;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
|
|
||||||
import org.linphone.R;
|
import org.linphone.R;
|
||||||
import org.linphone.receivers.NotificationBroadcastReceiver;
|
import org.linphone.notifications.Notifiable;
|
||||||
|
import org.linphone.notifications.NotifiableMessage;
|
||||||
|
import org.linphone.notifications.NotificationBroadcastReceiver;
|
||||||
|
|
||||||
import static org.linphone.compatibility.Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION;
|
import static org.linphone.compatibility.Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION;
|
||||||
import static org.linphone.compatibility.Compatibility.INTENT_CALL_ID;
|
import static org.linphone.compatibility.Compatibility.INTENT_CALL_ID;
|
||||||
import static org.linphone.compatibility.Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION;
|
import static org.linphone.compatibility.Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION;
|
||||||
|
import static org.linphone.compatibility.Compatibility.INTENT_LOCAL_IDENTITY;
|
||||||
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
|
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
|
||||||
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
|
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
|
||||||
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
|
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
|
||||||
|
@ -52,23 +51,17 @@ public class ApiTwentyFourPlus {
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Notification createMessageNotification(Context context, int notificationId, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
public static Notification createMessageNotification(Context context, Notifiable notif, Bitmap contactIcon, PendingIntent intent) {
|
||||||
String title;
|
|
||||||
if (msgCount == 1) {
|
|
||||||
title = msgSender;
|
|
||||||
} else {
|
|
||||||
title = context.getString(R.string.unread_messages).replace("%i", String.valueOf(msgCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
|
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
|
||||||
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
|
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
|
||||||
|
|
||||||
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
|
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
|
||||||
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
|
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
|
||||||
replyIntent.putExtra(INTENT_NOTIF_ID, notificationId);
|
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
|
||||||
|
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
|
||||||
|
|
||||||
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context,
|
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context,
|
||||||
notificationId, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
notif.getNotificationId(), replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
Notification.Action action = new Notification.Action.Builder(R.drawable.chat_send_over,
|
Notification.Action action = new Notification.Action.Builder(R.drawable.chat_send_over,
|
||||||
context.getString(R.string.notification_reply_label), replyPendingIntent)
|
context.getString(R.string.notification_reply_label), replyPendingIntent)
|
||||||
|
@ -76,9 +69,13 @@ public class ApiTwentyFourPlus {
|
||||||
.setAllowGeneratedReplies(true)
|
.setAllowGeneratedReplies(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
Notification.MessagingStyle style = new Notification.MessagingStyle(notif.getMyself());
|
||||||
|
for (NotifiableMessage message : notif.getMessages()) {
|
||||||
|
style.addMessage(message.getMessage(), message.getTime(), message.getSender());
|
||||||
|
}
|
||||||
|
style.setConversationTitle(notif.getGroupTitle());
|
||||||
|
|
||||||
return new Notification.Builder(context)
|
return new Notification.Builder(context)
|
||||||
.setContentTitle(title)
|
|
||||||
.setContentText(msg)
|
|
||||||
.setSmallIcon(R.drawable.topbar_chat_notification)
|
.setSmallIcon(R.drawable.topbar_chat_notification)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setContentIntent(intent)
|
.setContentIntent(intent)
|
||||||
|
@ -87,10 +84,11 @@ public class ApiTwentyFourPlus {
|
||||||
.setCategory(Notification.CATEGORY_MESSAGE)
|
.setCategory(Notification.CATEGORY_MESSAGE)
|
||||||
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
||||||
.setPriority(Notification.PRIORITY_HIGH)
|
.setPriority(Notification.PRIORITY_HIGH)
|
||||||
.setNumber(msgCount)
|
.setNumber(notif.getMessages().size())
|
||||||
.setWhen(System.currentTimeMillis())
|
.setWhen(System.currentTimeMillis())
|
||||||
.setShowWhen(true)
|
.setShowWhen(true)
|
||||||
.setColor(context.getColor(R.color.notification_color_led))
|
.setColor(context.getColor(R.color.notification_color_led))
|
||||||
|
.setStyle(style)
|
||||||
.addAction(action)
|
.addAction(action)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,15 +11,16 @@ import android.app.RemoteInput;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
|
|
||||||
import org.linphone.R;
|
import org.linphone.R;
|
||||||
import org.linphone.mediastream.Log;
|
import org.linphone.notifications.Notifiable;
|
||||||
import org.linphone.receivers.NotificationBroadcastReceiver;
|
import org.linphone.notifications.NotifiableMessage;
|
||||||
|
import org.linphone.notifications.NotificationBroadcastReceiver;
|
||||||
|
|
||||||
import static org.linphone.compatibility.Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION;
|
import static org.linphone.compatibility.Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION;
|
||||||
import static org.linphone.compatibility.Compatibility.INTENT_CALL_ID;
|
import static org.linphone.compatibility.Compatibility.INTENT_CALL_ID;
|
||||||
import static org.linphone.compatibility.Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION;
|
import static org.linphone.compatibility.Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION;
|
||||||
|
import static org.linphone.compatibility.Compatibility.INTENT_LOCAL_IDENTITY;
|
||||||
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
|
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
|
||||||
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
|
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
|
||||||
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
|
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
|
||||||
|
@ -83,23 +84,17 @@ public class ApiTwentySixPlus {
|
||||||
notificationManager.createNotificationChannel(channel);
|
notificationManager.createNotificationChannel(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Notification createMessageNotification(Context context, int notificationId, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
public static Notification createMessageNotification(Context context, Notifiable notif, Bitmap contactIcon, PendingIntent intent) {
|
||||||
String title;
|
|
||||||
if (msgCount == 1) {
|
|
||||||
title = msgSender;
|
|
||||||
} else {
|
|
||||||
title = context.getString(R.string.unread_messages).replace("%i", String.valueOf(msgCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
|
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
|
||||||
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
|
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
|
||||||
|
|
||||||
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
|
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
|
||||||
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
|
replyIntent.setAction(INTENT_REPLY_NOTIF_ACTION);
|
||||||
replyIntent.putExtra(INTENT_NOTIF_ID, notificationId);
|
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
|
||||||
|
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
|
||||||
|
|
||||||
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context,
|
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context,
|
||||||
notificationId, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
notif.getNotificationId(), replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
Notification.Action action = new Notification.Action.Builder(R.drawable.chat_send_over,
|
Notification.Action action = new Notification.Action.Builder(R.drawable.chat_send_over,
|
||||||
context.getString(R.string.notification_reply_label), replyPendingIntent)
|
context.getString(R.string.notification_reply_label), replyPendingIntent)
|
||||||
|
@ -107,9 +102,13 @@ public class ApiTwentySixPlus {
|
||||||
.setAllowGeneratedReplies(true)
|
.setAllowGeneratedReplies(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
Notification.MessagingStyle style = new Notification.MessagingStyle(notif.getMyself());
|
||||||
|
for (NotifiableMessage message : notif.getMessages()) {
|
||||||
|
style.addMessage(message.getMessage(), message.getTime(), message.getSender());
|
||||||
|
}
|
||||||
|
style.setConversationTitle(notif.getGroupTitle());
|
||||||
|
|
||||||
return new Notification.Builder(context, context.getString(R.string.notification_channel_id))
|
return new Notification.Builder(context, context.getString(R.string.notification_channel_id))
|
||||||
.setContentTitle(title)
|
|
||||||
.setContentText(msg)
|
|
||||||
.setSmallIcon(R.drawable.topbar_chat_notification)
|
.setSmallIcon(R.drawable.topbar_chat_notification)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setContentIntent(intent)
|
.setContentIntent(intent)
|
||||||
|
@ -118,10 +117,11 @@ public class ApiTwentySixPlus {
|
||||||
.setCategory(Notification.CATEGORY_MESSAGE)
|
.setCategory(Notification.CATEGORY_MESSAGE)
|
||||||
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
||||||
.setPriority(Notification.PRIORITY_HIGH)
|
.setPriority(Notification.PRIORITY_HIGH)
|
||||||
.setNumber(msgCount)
|
.setNumber(notif.getMessages().size())
|
||||||
.setWhen(System.currentTimeMillis())
|
.setWhen(System.currentTimeMillis())
|
||||||
.setShowWhen(true)
|
.setShowWhen(true)
|
||||||
.setColor(context.getColor(R.color.notification_color_led))
|
.setColor(context.getColor(R.color.notification_color_led))
|
||||||
|
.setStyle(style)
|
||||||
.addAction(action)
|
.addAction(action)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import android.app.AlarmManager;
|
|
||||||
import android.app.FragmentTransaction;
|
import android.app.FragmentTransaction;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
@ -26,15 +25,11 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.PowerManager;
|
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.text.Html;
|
|
||||||
import android.text.Spanned;
|
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.linphone.mediastream.Version;
|
import org.linphone.mediastream.Version;
|
||||||
|
import org.linphone.notifications.Notifiable;
|
||||||
|
|
||||||
public class Compatibility {
|
public class Compatibility {
|
||||||
public static final String KEY_TEXT_REPLY = "key_text_reply";
|
public static final String KEY_TEXT_REPLY = "key_text_reply";
|
||||||
|
@ -43,6 +38,7 @@ public class Compatibility {
|
||||||
public static final String INTENT_REPLY_NOTIF_ACTION = "org.linphone.REPLY_ACTION";
|
public static final String INTENT_REPLY_NOTIF_ACTION = "org.linphone.REPLY_ACTION";
|
||||||
public static final String INTENT_HANGUP_CALL_NOTIF_ACTION = "org.linphone.HANGUP_CALL_ACTION";
|
public static final String INTENT_HANGUP_CALL_NOTIF_ACTION = "org.linphone.HANGUP_CALL_ACTION";
|
||||||
public static final String INTENT_ANSWER_CALL_NOTIF_ACTION = "org.linphone.ANSWER_CALL_ACTION";
|
public static final String INTENT_ANSWER_CALL_NOTIF_ACTION = "org.linphone.ANSWER_CALL_ACTION";
|
||||||
|
public static final String INTENT_LOCAL_IDENTITY = "LOCAL_IDENTITY";
|
||||||
|
|
||||||
public static void createNotificationChannels(Context context) {
|
public static void createNotificationChannels(Context context) {
|
||||||
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
|
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
|
||||||
|
@ -65,13 +61,13 @@ public class Compatibility {
|
||||||
return ApiTwentyOnePlus.createMissedCallNotification(context, title, text, intent);
|
return ApiTwentyOnePlus.createMissedCallNotification(context, title, text, intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Notification createMessageNotification(Context context, int notificationId, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
public static Notification createMessageNotification(Context context, Notifiable notif, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
||||||
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
|
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
|
||||||
return ApiTwentySixPlus.createMessageNotification(context, notificationId, msgCount, msgSender, msg, contactIcon, intent);
|
return ApiTwentySixPlus.createMessageNotification(context, notif, contactIcon, intent);
|
||||||
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
|
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
|
||||||
return ApiTwentyFourPlus.createMessageNotification(context, notificationId, msgCount, msgSender, msg, contactIcon, intent);
|
return ApiTwentyFourPlus.createMessageNotification(context, notif, contactIcon, intent);
|
||||||
}
|
}
|
||||||
return ApiTwentyOnePlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent);
|
return ApiTwentyOnePlus.createMessageNotification(context, notif.getMessages().size(), msgSender, msg, contactIcon, intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Notification createRepliedNotification(Context context, String reply) {
|
public static Notification createRepliedNotification(Context context, String reply) {
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
|
||||||
if (defaultProxyConfig != null) {
|
if (defaultProxyConfig != null) {
|
||||||
ChatRoom room = lc.findOneToOneChatRoom(defaultProxyConfig.getContact(), participant, isSecured);
|
ChatRoom room = lc.findOneToOneChatRoom(defaultProxyConfig.getContact(), participant, isSecured);
|
||||||
if (room != null) {
|
if (room != null) {
|
||||||
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null, room.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
|
||||||
} else {
|
} else {
|
||||||
if (defaultProxyConfig.getConferenceFactoryUri() != null && (isSecured || !LinphonePreferences.instance().useBasicChatRoomFor1To1())) {
|
if (defaultProxyConfig.getConferenceFactoryUri() != null && (isSecured || !LinphonePreferences.instance().useBasicChatRoomFor1To1())) {
|
||||||
mWaitLayout.setVisibility(View.VISIBLE);
|
mWaitLayout.setVisibility(View.VISIBLE);
|
||||||
|
@ -96,7 +96,7 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
|
||||||
mChatRoom.addParticipants(participants);
|
mChatRoom.addParticipants(participants);
|
||||||
} else {
|
} else {
|
||||||
room = lc.getChatRoom(participant);
|
room = lc.getChatRoom(participant);
|
||||||
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null, room.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
|
||||||
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
|
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
|
||||||
if (newState == ChatRoom.State.Created) {
|
if (newState == ChatRoom.State.Created) {
|
||||||
mWaitLayout.setVisibility(View.GONE);
|
mWaitLayout.setVisibility(View.GONE);
|
||||||
LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), null, cr.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), null);
|
||||||
} else if (newState == ChatRoom.State.CreationFailed) {
|
} else if (newState == ChatRoom.State.CreationFailed) {
|
||||||
mWaitLayout.setVisibility(View.GONE);
|
mWaitLayout.setVisibility(View.GONE);
|
||||||
LinphoneActivity.instance().displayChatRoomError();
|
LinphoneActivity.instance().displayChatRoomError();
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class FirebaseIdService extends FirebaseInstanceIdService {
|
||||||
public void onTokenRefresh() {
|
public void onTokenRefresh() {
|
||||||
// Get updated InstanceID token.
|
// Get updated InstanceID token.
|
||||||
final String refreshedToken = FirebaseInstanceId.getInstance().getToken();
|
final String refreshedToken = FirebaseInstanceId.getInstance().getToken();
|
||||||
android.util.Log.i("FirebaseIdService", "[Push Notification] Refreshed token: " + refreshedToken);
|
android.util.Log.i("FirebaseIdService", "[Push Notifiable] Refreshed token: " + refreshedToken);
|
||||||
|
|
||||||
LinphoneUtils.dispatchOnUIThread(new Runnable() {
|
LinphoneUtils.dispatchOnUIThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -36,10 +36,10 @@ public class FirebaseMessaging extends FirebaseMessagingService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessageReceived(RemoteMessage remoteMessage) {
|
public void onMessageReceived(RemoteMessage remoteMessage) {
|
||||||
android.util.Log.i("FirebaseMessaging", "[Push Notification] Received");
|
android.util.Log.i("FirebaseMessaging", "[Push Notifiable] Received");
|
||||||
|
|
||||||
if (!LinphoneService.isReady()) {
|
if (!LinphoneService.isReady()) {
|
||||||
android.util.Log.i("FirebaseMessaging", "[Push Notification] Starting Service");
|
android.util.Log.i("FirebaseMessaging", "[Push Notifiable] Starting Service");
|
||||||
startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
||||||
} else if (LinphoneManager.isInstanciated() && LinphoneManager.getLc().getCallsNb() == 0) {
|
} else if (LinphoneManager.isInstanciated() && LinphoneManager.getLc().getCallsNb() == 0) {
|
||||||
LinphoneUtils.dispatchOnUIThread(new Runnable() {
|
LinphoneUtils.dispatchOnUIThread(new Runnable() {
|
||||||
|
|
|
@ -109,7 +109,7 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
|
||||||
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
|
public void onStateChanged(ChatRoom cr, ChatRoom.State newState) {
|
||||||
if (newState == ChatRoom.State.Created) {
|
if (newState == ChatRoom.State.Created) {
|
||||||
mWaitLayout.setVisibility(View.GONE);
|
mWaitLayout.setVisibility(View.GONE);
|
||||||
LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), null, cr.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(cr.getPeerAddress().asStringUriOnly(), null);
|
||||||
} else if (newState == ChatRoom.State.CreationFailed) {
|
} else if (newState == ChatRoom.State.CreationFailed) {
|
||||||
mWaitLayout.setVisibility(View.GONE);
|
mWaitLayout.setVisibility(View.GONE);
|
||||||
LinphoneActivity.instance().displayChatRoomError();
|
LinphoneActivity.instance().displayChatRoomError();
|
||||||
|
@ -198,7 +198,7 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
|
||||||
Address participant = Factory.instance().createAddress(sipUri);
|
Address participant = Factory.instance().createAddress(sipUri);
|
||||||
ChatRoom room = lc.findOneToOneChatRoom(lc.getDefaultProxyConfig().getContact(), participant, false);
|
ChatRoom room = lc.findOneToOneChatRoom(lc.getDefaultProxyConfig().getContact(), participant, false);
|
||||||
if (room != null) {
|
if (room != null) {
|
||||||
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null, room.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
|
||||||
} else {
|
} else {
|
||||||
ProxyConfig lpc = lc.getDefaultProxyConfig();
|
ProxyConfig lpc = lc.getDefaultProxyConfig();
|
||||||
if (lpc != null && lpc.getConferenceFactoryUri() != null && !LinphonePreferences.instance().useBasicChatRoomFor1To1()) {
|
if (lpc != null && lpc.getConferenceFactoryUri() != null && !LinphonePreferences.instance().useBasicChatRoomFor1To1()) {
|
||||||
|
@ -208,7 +208,7 @@ public class HistoryDetailFragment extends Fragment implements OnClickListener {
|
||||||
mChatRoom.addParticipant(participant);
|
mChatRoom.addParticipant(participant);
|
||||||
} else {
|
} else {
|
||||||
room = lc.getChatRoom(participant);
|
room = lc.getChatRoom(participant);
|
||||||
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null, room.getLocalAddress().asString());
|
LinphoneActivity.instance().goToChat(room.getPeerAddress().asStringUriOnly(), null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (id == R.id.add_contact) {
|
} else if (id == R.id.add_contact) {
|
||||||
|
|
|
@ -1362,9 +1362,9 @@ public class SettingsFragment extends PreferencesListFragment {
|
||||||
boolean value = (Boolean) newValue;
|
boolean value = (Boolean) newValue;
|
||||||
mPrefs.setServiceNotificationVisibility(value);
|
mPrefs.setServiceNotificationVisibility(value);
|
||||||
if (value) {
|
if (value) {
|
||||||
LinphoneService.instance().showServiceNotification();
|
LinphoneService.instance().getNotificationManager().startForeground();
|
||||||
} else {
|
} else {
|
||||||
LinphoneService.instance().hideServiceNotification();
|
LinphoneService.instance().getNotificationManager().stopForeground();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
86
app/src/main/java/org/linphone/notifications/Notifiable.java
Normal file
86
app/src/main/java/org/linphone/notifications/Notifiable.java
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
package org.linphone.notifications;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Notifiable.java
|
||||||
|
Copyright (C) 2018 Belledonne Communications, Grenoble, France
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Notifiable {
|
||||||
|
int mNotificationId;
|
||||||
|
List<NotifiableMessage> mMessages;
|
||||||
|
boolean mIsGroup;
|
||||||
|
String mGroupTitle;
|
||||||
|
String mLocalIdentity;
|
||||||
|
String mMyself;
|
||||||
|
|
||||||
|
public Notifiable(int id) {
|
||||||
|
mNotificationId = id;
|
||||||
|
mMessages = new ArrayList<>();
|
||||||
|
mIsGroup = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNotificationId() {
|
||||||
|
return mNotificationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetMessages() {
|
||||||
|
mMessages = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMessage(NotifiableMessage notifMessage) {
|
||||||
|
mMessages.add(notifMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<NotifiableMessage> getMessages() {
|
||||||
|
return mMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGroup() {
|
||||||
|
return mIsGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsGroup(boolean isGroup) {
|
||||||
|
mIsGroup = isGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGroupTitle() {
|
||||||
|
return mGroupTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupTitle(String title) {
|
||||||
|
mGroupTitle = title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMyself() {
|
||||||
|
return mMyself;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMyself(String myself) {
|
||||||
|
mMyself = myself;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocalIdentity() {
|
||||||
|
return mLocalIdentity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalIdentity(String localIdentity) {
|
||||||
|
mLocalIdentity = localIdentity;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package org.linphone.notifications;
|
||||||
|
|
||||||
|
/*
|
||||||
|
NotifiableMessage.java
|
||||||
|
Copyright (C) 2018 Belledonne Communications, Grenoble, France
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class NotifiableMessage {
|
||||||
|
String mMessage;
|
||||||
|
String mSender;
|
||||||
|
long mTime;
|
||||||
|
|
||||||
|
public NotifiableMessage(String message, String sender, long time) {
|
||||||
|
mMessage = message;
|
||||||
|
mSender = sender;
|
||||||
|
mTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return mMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSender() {
|
||||||
|
return mSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTime() {
|
||||||
|
return mTime;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package org.linphone.receivers;
|
package org.linphone.notifications;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NotificationBroadcastReceiver.java
|
NotificationBroadcastReceiver.java
|
||||||
|
@ -29,48 +29,82 @@ import android.os.Bundle;
|
||||||
|
|
||||||
import org.linphone.LinphoneManager;
|
import org.linphone.LinphoneManager;
|
||||||
import org.linphone.LinphoneService;
|
import org.linphone.LinphoneService;
|
||||||
|
import org.linphone.R;
|
||||||
import org.linphone.activities.LinphoneActivity;
|
import org.linphone.activities.LinphoneActivity;
|
||||||
import org.linphone.compatibility.Compatibility;
|
import org.linphone.compatibility.Compatibility;
|
||||||
import org.linphone.core.Address;
|
import org.linphone.core.Address;
|
||||||
import org.linphone.core.Call;
|
import org.linphone.core.Call;
|
||||||
import org.linphone.core.ChatMessage;
|
import org.linphone.core.ChatMessage;
|
||||||
|
import org.linphone.core.ChatMessageListenerStub;
|
||||||
import org.linphone.core.ChatRoom;
|
import org.linphone.core.ChatRoom;
|
||||||
import org.linphone.core.Core;
|
import org.linphone.core.Core;
|
||||||
import org.linphone.core.ProxyConfig;
|
import org.linphone.core.ProxyConfig;
|
||||||
import org.linphone.core.Reason;
|
import org.linphone.mediastream.Log;
|
||||||
|
|
||||||
public class NotificationBroadcastReceiver extends BroadcastReceiver {
|
public class NotificationBroadcastReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(final Context context, Intent intent) {
|
||||||
|
final int notifId = intent.getIntExtra(Compatibility.INTENT_NOTIF_ID, 0);
|
||||||
|
final String localyIdentity = intent.getStringExtra(Compatibility.INTENT_LOCAL_IDENTITY);
|
||||||
|
|
||||||
if (intent.getAction() == Compatibility.INTENT_REPLY_NOTIF_ACTION) {
|
if (intent.getAction() == Compatibility.INTENT_REPLY_NOTIF_ACTION) {
|
||||||
String reply = getMessageText(intent).toString();
|
final String reply = getMessageText(intent).toString();
|
||||||
if (reply == null) return;
|
if (reply == null) {
|
||||||
Notification replied = Compatibility.createRepliedNotification(context, reply);
|
Log.e("Couldn't get reply text");
|
||||||
if (replied == null) return;
|
onError(context, notifId);
|
||||||
int notifId = intent.getIntExtra(Compatibility.INTENT_NOTIF_ID, 0);
|
return;
|
||||||
String remoteSipAddr = LinphoneService.instance().getSipUriForNotificationId(notifId);
|
}
|
||||||
|
String remoteSipAddr = LinphoneService.instance().getNotificationManager().getSipUriForNotificationId(notifId);
|
||||||
|
|
||||||
Core core = LinphoneManager.getLc();
|
Core core = LinphoneManager.getLc();
|
||||||
if (core == null) return;
|
if (core == null) {
|
||||||
ProxyConfig proxyConfig = core.getDefaultProxyConfig();
|
Log.e("Couldn't get Core instance");
|
||||||
if (proxyConfig == null) return;
|
onError(context, notifId);
|
||||||
Address localAddr = proxyConfig.getIdentityAddress();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Address remoteAddr = core.interpretUrl(remoteSipAddr);
|
Address remoteAddr = core.interpretUrl(remoteSipAddr);
|
||||||
if (localAddr == null || remoteAddr == null) return;
|
if (remoteAddr == null) {
|
||||||
|
Log.e("Couldn't interpret remote address " + remoteSipAddr);
|
||||||
|
onError(context, notifId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Address localAddr = core.interpretUrl(localyIdentity);
|
||||||
|
if (localAddr == null) {
|
||||||
|
Log.e("Couldn't interpret local address " + localyIdentity);
|
||||||
|
onError(context, notifId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ChatRoom room = core.findChatRoom(remoteAddr, localAddr);
|
ChatRoom room = core.findChatRoom(remoteAddr, localAddr);
|
||||||
if (room == null) return;
|
if (room == null) {
|
||||||
|
Log.e("Couldn't find chat room for remote address " + remoteSipAddr + " and local address " + localyIdentity);
|
||||||
|
onError(context, notifId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
room.markAsRead();
|
room.markAsRead();
|
||||||
if (LinphoneActivity.isInstanciated()) {
|
if (LinphoneActivity.isInstanciated()) {
|
||||||
LinphoneActivity.instance().displayMissedChats(LinphoneManager.getInstance().getUnreadMessageCount());
|
LinphoneActivity.instance().displayMissedChats(LinphoneManager.getInstance().getUnreadMessageCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatMessage msg = room.createMessage(reply);
|
ChatMessage msg = room.createMessage(reply);
|
||||||
msg.send();
|
msg.send();
|
||||||
|
msg.setListener(new ChatMessageListenerStub() {
|
||||||
LinphoneService.instance().sendNotification(replied, notifId);
|
@Override
|
||||||
|
public void onMsgStateChanged(ChatMessage msg, ChatMessage.State state) {
|
||||||
|
if (state == ChatMessage.State.Delivered) {
|
||||||
|
Notification replied = Compatibility.createRepliedNotification(context, reply);
|
||||||
|
LinphoneService.instance().getNotificationManager().sendNotification(notifId, replied);
|
||||||
|
} else if (state == ChatMessage.State.NotDelivered) {
|
||||||
|
Log.e("Couldn't send reply, message is not delivered");
|
||||||
|
onError(context, notifId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
} else if (intent.getAction() == Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION || intent.getAction() == Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION) {
|
} else if (intent.getAction() == Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION || intent.getAction() == Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION) {
|
||||||
int callId = intent.getIntExtra(Compatibility.INTENT_CALL_ID, 0);
|
String remoteAddr = LinphoneService.instance().getNotificationManager().getSipUriForCallNotificationId(notifId);
|
||||||
String remoteAddr = LinphoneService.instance().getSipUriForCallNotificationId(callId);
|
|
||||||
|
|
||||||
Core core = LinphoneManager.getLc();
|
Core core = LinphoneManager.getLc();
|
||||||
if (core == null) return;
|
if (core == null) return;
|
||||||
|
@ -85,6 +119,11 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onError(Context context, int notifId) {
|
||||||
|
Notification replyError = Compatibility.createRepliedNotification(context, context.getString(R.string.error));
|
||||||
|
LinphoneService.instance().getNotificationManager().sendNotification(notifId, replyError);
|
||||||
|
}
|
||||||
|
|
||||||
@TargetApi(20)
|
@TargetApi(20)
|
||||||
private CharSequence getMessageText(Intent intent) {
|
private CharSequence getMessageText(Intent intent) {
|
||||||
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
|
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
|
|
@ -0,0 +1,308 @@
|
||||||
|
package org.linphone.notifications;
|
||||||
|
|
||||||
|
/*
|
||||||
|
NotificationsManager.java
|
||||||
|
Copyright (C) 2018 Belledonne Communications, Grenoble, France
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.provider.MediaStore;
|
||||||
|
|
||||||
|
import org.linphone.LinphoneManager;
|
||||||
|
import org.linphone.LinphonePreferences;
|
||||||
|
import org.linphone.LinphoneService;
|
||||||
|
import org.linphone.LinphoneUtils;
|
||||||
|
import org.linphone.R;
|
||||||
|
import org.linphone.activities.LinphoneActivity;
|
||||||
|
import org.linphone.compatibility.Compatibility;
|
||||||
|
import org.linphone.contacts.ContactsManager;
|
||||||
|
import org.linphone.contacts.LinphoneContact;
|
||||||
|
import org.linphone.core.Address;
|
||||||
|
import org.linphone.core.Call;
|
||||||
|
import org.linphone.mediastream.Version;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import static android.content.Context.NOTIFICATION_SERVICE;
|
||||||
|
|
||||||
|
public class NotificationsManager {
|
||||||
|
private static final int SERVICE_NOTIF_ID = 1;
|
||||||
|
private static final int MISSED_CALLS_NOTIF_ID = 2;
|
||||||
|
private static final int IN_APP_NOTIF_ID = 3;
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private NotificationManager mNM;
|
||||||
|
private HashMap<String, Notifiable> mChatNotifMap, mCallNotifMap;
|
||||||
|
private int mLastNotificationId;
|
||||||
|
private PendingIntent mPendingIntent;
|
||||||
|
private Notification mServiceNotification;
|
||||||
|
|
||||||
|
public NotificationsManager(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
mChatNotifMap = new HashMap<>();
|
||||||
|
mCallNotifMap = new HashMap<>();
|
||||||
|
|
||||||
|
mNM = (NotificationManager) mContext.getSystemService(NOTIFICATION_SERVICE);
|
||||||
|
mNM.cancelAll();
|
||||||
|
|
||||||
|
mLastNotificationId = 5; // Do not conflict with hardcoded notifications ids !
|
||||||
|
|
||||||
|
Compatibility.createNotificationChannels(mContext);
|
||||||
|
|
||||||
|
Intent notifIntent = new Intent(mContext, LinphoneService.instance().getIncomingReceivedActivity());
|
||||||
|
notifIntent.putExtra("Notifiable", true);
|
||||||
|
mPendingIntent = PendingIntent.getActivity(mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
//Disable service notification for Android O
|
||||||
|
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
|
||||||
|
LinphonePreferences.instance().setServiceNotificationVisibility(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap bm = null;
|
||||||
|
try {
|
||||||
|
bm = BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.ic_launcher);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
mServiceNotification = Compatibility.createNotification(mContext, mContext.getString(R.string.service_name), "",
|
||||||
|
R.drawable.linphone_notification_icon, R.mipmap.ic_launcher, bm, mPendingIntent, true,
|
||||||
|
Notification.PRIORITY_MIN);
|
||||||
|
|
||||||
|
if (isServiceNotificationDisplayed()) {
|
||||||
|
startForeground();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
mNM.cancelAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startForeground() {
|
||||||
|
LinphoneService.instance().startForeground(SERVICE_NOTIF_ID, mServiceNotification);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopForeground() {
|
||||||
|
LinphoneService.instance().stopForeground(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendNotification(int id, Notification notif) {
|
||||||
|
mNM.notify(id, notif);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetMessageNotifCount(String address) {
|
||||||
|
Notifiable notif = mChatNotifMap.get(address);
|
||||||
|
if (notif != null) {
|
||||||
|
notif.resetMessages();
|
||||||
|
mNM.cancel(notif.getNotificationId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isServiceNotificationDisplayed() {
|
||||||
|
return LinphonePreferences.instance().getServiceNotificationVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSipUriForNotificationId(int notificationId) {
|
||||||
|
for (String addr : mChatNotifMap.keySet()) {
|
||||||
|
if (mChatNotifMap.get(addr).getNotificationId() == notificationId) {
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void displayGroupChatMessageNotification(String subject, String conferenceAddress, String fromName, Uri fromPictureUri, String message, Address localIdentity) {
|
||||||
|
Intent notifIntent = new Intent(mContext, LinphoneActivity.class);
|
||||||
|
notifIntent.putExtra("GoToChat", true);
|
||||||
|
notifIntent.putExtra("ChatContactSipUri", conferenceAddress);
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
Notifiable notif = mChatNotifMap.get(conferenceAddress);
|
||||||
|
NotifiableMessage notifMessage = new NotifiableMessage(message, fromName, 0);
|
||||||
|
if (notif == null) {
|
||||||
|
notif = new Notifiable(mLastNotificationId);
|
||||||
|
mLastNotificationId += 1;
|
||||||
|
mChatNotifMap.put(conferenceAddress, notif);
|
||||||
|
}
|
||||||
|
notif.addMessage(notifMessage);
|
||||||
|
notif.setIsGroup(true);
|
||||||
|
notif.setGroupTitle(subject);
|
||||||
|
notif.setMyself(LinphoneUtils.getAddressDisplayName(localIdentity));
|
||||||
|
notif.setLocalIdentity(localIdentity.asString());
|
||||||
|
|
||||||
|
Bitmap bm;
|
||||||
|
if (fromPictureUri != null) {
|
||||||
|
try {
|
||||||
|
bm = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), fromPictureUri);
|
||||||
|
} catch (Exception e) {
|
||||||
|
bm = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.chat_group_avatar);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bm = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.topbar_avatar);
|
||||||
|
}
|
||||||
|
Notification notification = Compatibility.createMessageNotification(mContext, notif, subject,
|
||||||
|
mContext.getString(R.string.group_chat_notif).replace("%1", fromName).replace("%2", message), bm, pendingIntent);
|
||||||
|
sendNotification(notif.getNotificationId(), notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void displayMessageNotification(String fromSipUri, String fromName, Uri fromPictureUri, String message, Address localIdentity) {
|
||||||
|
Intent notifIntent = new Intent(mContext, LinphoneActivity.class);
|
||||||
|
notifIntent.putExtra("GoToChat", true);
|
||||||
|
notifIntent.putExtra("ChatContactSipUri", fromSipUri);
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
if (fromName == null) {
|
||||||
|
fromName = fromSipUri;
|
||||||
|
}
|
||||||
|
|
||||||
|
Notifiable notif = mChatNotifMap.get(fromSipUri);
|
||||||
|
NotifiableMessage notifMessage = new NotifiableMessage(message, fromName, 0);
|
||||||
|
if (notif == null) {
|
||||||
|
notif = new Notifiable(mLastNotificationId);
|
||||||
|
mLastNotificationId += 1;
|
||||||
|
mChatNotifMap.put(fromSipUri, notif);
|
||||||
|
}
|
||||||
|
notif.addMessage(notifMessage);
|
||||||
|
notif.setIsGroup(false);
|
||||||
|
notif.setMyself(LinphoneUtils.getAddressDisplayName(localIdentity));
|
||||||
|
notif.setLocalIdentity(localIdentity.asString());
|
||||||
|
|
||||||
|
Bitmap bm;
|
||||||
|
if (fromPictureUri != null) {
|
||||||
|
try {
|
||||||
|
bm = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), fromPictureUri);
|
||||||
|
} catch (Exception e) {
|
||||||
|
bm = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.topbar_avatar);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bm = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.topbar_avatar);
|
||||||
|
}
|
||||||
|
Notification notification = Compatibility.createMessageNotification(mContext, notif, fromName, message, bm, pendingIntent);
|
||||||
|
sendNotification(notif.getNotificationId(), notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void displayMissedCallNotification(Call call) {
|
||||||
|
Intent missedCallNotifIntent = new Intent(mContext, LinphoneService.instance().getIncomingReceivedActivity());
|
||||||
|
missedCallNotifIntent.putExtra("GoToHistory", true);
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, missedCallNotifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
int missedCallCount = LinphoneManager.getLcIfManagerNotDestroyedOrNull().getMissedCallsCount();
|
||||||
|
String body;
|
||||||
|
if (missedCallCount > 1) {
|
||||||
|
body = mContext.getString(R.string.missed_calls_notif_body).replace("%i", String.valueOf(missedCallCount));
|
||||||
|
} else {
|
||||||
|
Address address = call.getRemoteAddress();
|
||||||
|
LinphoneContact c = ContactsManager.getInstance().findContactFromAddress(address);
|
||||||
|
if (c != null) {
|
||||||
|
body = c.getFullName();
|
||||||
|
} else {
|
||||||
|
body = address.getDisplayName();
|
||||||
|
if (body == null) {
|
||||||
|
body = address.asStringUriOnly();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Notification notif = Compatibility.createMissedCallNotification(mContext, mContext.getString(R.string.missed_calls_notif_title), body, pendingIntent);
|
||||||
|
sendNotification(MISSED_CALLS_NOTIF_ID, notif);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void displayCallNotification(Call call) {
|
||||||
|
if (call == null) return;
|
||||||
|
|
||||||
|
Address address = call.getRemoteAddress();
|
||||||
|
String addressAsString = address.asStringUriOnly();
|
||||||
|
Notifiable notif = mCallNotifMap.get(addressAsString);
|
||||||
|
if (notif == null) {
|
||||||
|
notif = new Notifiable(mLastNotificationId);
|
||||||
|
mLastNotificationId += 1;
|
||||||
|
mCallNotifMap.put(addressAsString, notif);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isServiceNotificationDisplayed()) {
|
||||||
|
if (call.getCore().getCallsNb() == 0) {
|
||||||
|
stopForeground();
|
||||||
|
} else {
|
||||||
|
startForeground();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int notificationTextId;
|
||||||
|
int iconId;
|
||||||
|
switch (call.getState()) {
|
||||||
|
case Released:
|
||||||
|
case End:
|
||||||
|
mNM.cancel(notif.getNotificationId());
|
||||||
|
mCallNotifMap.remove(addressAsString);
|
||||||
|
return;
|
||||||
|
case Paused:
|
||||||
|
case PausedByRemote:
|
||||||
|
case Pausing:
|
||||||
|
iconId = R.drawable.topbar_call_notification;
|
||||||
|
notificationTextId = R.string.incall_notif_paused;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (call.getCurrentParams().videoEnabled()) {
|
||||||
|
iconId = R.drawable.topbar_videocall_notification;
|
||||||
|
notificationTextId = R.string.incall_notif_video;
|
||||||
|
} else {
|
||||||
|
iconId = R.drawable.topbar_call_notification;
|
||||||
|
notificationTextId = R.string.incall_notif_active;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
|
||||||
|
Uri pictureUri = contact != null ? contact.getPhotoUri() : null;
|
||||||
|
Bitmap bm;
|
||||||
|
try {
|
||||||
|
bm = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), pictureUri);
|
||||||
|
} catch (Exception e) {
|
||||||
|
bm = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.avatar);
|
||||||
|
}
|
||||||
|
String name = LinphoneUtils.getAddressDisplayName(address);
|
||||||
|
|
||||||
|
boolean showAnswerAction = call.getState() == Call.State.IncomingReceived || call.getState() == Call.State.IncomingEarlyMedia;
|
||||||
|
Notification notification = Compatibility.createInCallNotification(mContext, notif.getNotificationId(),
|
||||||
|
showAnswerAction, mContext.getString(R.string.service_name),
|
||||||
|
mContext.getString(notificationTextId), iconId, bm, name, mPendingIntent);
|
||||||
|
|
||||||
|
sendNotification(notif.getNotificationId(), notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSipUriForCallNotificationId(int notificationId) {
|
||||||
|
for (String addr : mCallNotifMap.keySet()) {
|
||||||
|
if (mCallNotifMap.get(addr).getNotificationId() == notificationId) {
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void displayInappNotification(String message) {
|
||||||
|
Intent notifIntent = new Intent(mContext, LinphoneActivity.class);
|
||||||
|
notifIntent.putExtra("GoToInapp", true);
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, notifIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
Notification notif = Compatibility.createSimpleNotification(mContext, mContext.getString(R.string.inapp_notification_title), message, pendingIntent);
|
||||||
|
|
||||||
|
sendNotification(IN_APP_NOTIF_ID, notif);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue