From 2c62a0428609ca23ee065ab6ff9b2ce83d3479f1 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 24 Jul 2018 13:30:54 +0200 Subject: [PATCH] Attempt to fix issue with startForeground for Android 8+ --- src/android/org/linphone/LinphoneService.java | 126 +++++++++--------- .../org/linphone/receivers/BootReceiver.java | 1 + 2 files changed, 67 insertions(+), 60 deletions(-) diff --git a/src/android/org/linphone/LinphoneService.java b/src/android/org/linphone/LinphoneService.java index 3f0a4bdaa..fc5bf8f5f 100644 --- a/src/android/org/linphone/LinphoneService.java +++ b/src/android/org/linphone/LinphoneService.java @@ -310,59 +310,13 @@ public final class LinphoneService extends Service { stopForegroundCompat(NOTIF_ID); } - @SuppressWarnings("unchecked") @Override - public void onCreate() { - super.onCreate(); - mLastNotificationId = 8; // To not interfere with other notifs ids - mChatNotifMap = new HashMap(); - - 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 - LinphonePreferences.instance().setContext(getBaseContext()); - Factory.instance().setLogCollectionPath(getFilesDir().getAbsolutePath()); - boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); - LinphoneUtils.initLoggingService(isDebugEnabled, getString(R.string.app_name)); - - // Dump some debugging information to the logs - Log.i(START_LINPHONE_LOGS); - dumpDeviceInformation(); - 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.cancel(INCALL_NOTIF_ID); // in case of crash the icon is not removed - Compatibility.CreateChannel(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); + public int onStartCommand(Intent intent, int flags, int startId) { + super.onStartCommand(intent, flags, startId); LinphoneManager.createAndStart(LinphoneService.this); instance = this; // instance is ready once linphone manager has been created - incomingReceivedActivityName = LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived(); - try { - incomingReceivedActivity = (Class) Class.forName(incomingReceivedActivityName); - } catch (ClassNotFoundException e) { - Log.e(e); - } - LinphoneManager.getLc().addListener(mListener = new CoreListenerStub() { @Override public void onCallStateChanged(Core lc, Call call, Call.State state, String message) { @@ -451,12 +405,8 @@ public final class LinphoneService extends Service { } }); - - try { - mStartForeground = getClass().getMethod("startForeground", mStartFgSign); - mStopForeground = getClass().getMethod("stopForeground", mStopFgSign); - } catch (NoSuchMethodException e) { - Log.e(e, "Couldn't find startForeground or stopForeground"); + if (displayServiceNotification() || (Version.sdkAboveOrEqual(Version.API26_O_80) && intent.getBooleanExtra("ForceStartForeground", false))) { + startForegroundCompat(NOTIF_ID, mNotif); } if (!Version.sdkAboveOrEqual(Version.API26_O_80) @@ -464,10 +414,6 @@ public final class LinphoneService extends Service { getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, ContactsManager.getInstance()); } - if (displayServiceNotification()) { - startForegroundCompat(NOTIF_ID, mNotif); - } - if (!mTestDelayElapsed) { // Only used when testing. Simulates a 5 seconds delay for launching service mHandler.postDelayed(new Runnable() { @@ -478,11 +424,71 @@ public final class LinphoneService extends Service { } //make sure the application will at least wakes up every 10 mn - Intent intent = new Intent(this, KeepAliveReceiver.class); - PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); + Intent keepAliveIntent = new Intent(this, KeepAliveReceiver.class); + PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, keepAliveIntent, PendingIntent.FLAG_ONE_SHOT); AlarmManager alarmManager = ((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)); Compatibility.scheduleAlarm(alarmManager, AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 600000, keepAlivePendingIntent); + return START_STICKY; + } + + @SuppressWarnings("unchecked") + @Override + public void onCreate() { + super.onCreate(); + mLastNotificationId = 8; // To not interfere with other notifs ids + mChatNotifMap = new HashMap(); + + 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 + LinphonePreferences.instance().setContext(getBaseContext()); + Factory.instance().setLogCollectionPath(getFilesDir().getAbsolutePath()); + boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled(); + LinphoneUtils.initLoggingService(isDebugEnabled, getString(R.string.app_name)); + + // Dump some debugging information to the logs + Log.i(START_LINPHONE_LOGS); + dumpDeviceInformation(); + 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.cancel(INCALL_NOTIF_ID); // in case of crash the icon is not removed + Compatibility.CreateChannel(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(); + try { + incomingReceivedActivity = (Class) Class.forName(incomingReceivedActivityName); + } catch (ClassNotFoundException 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); } diff --git a/src/android/org/linphone/receivers/BootReceiver.java b/src/android/org/linphone/receivers/BootReceiver.java index 360382a8d..340206aec 100644 --- a/src/android/org/linphone/receivers/BootReceiver.java +++ b/src/android/org/linphone/receivers/BootReceiver.java @@ -42,6 +42,7 @@ public class BootReceiver extends BroadcastReceiver { if (autostart) { Intent lLinphoneServiceIntent = new Intent(Intent.ACTION_MAIN); lLinphoneServiceIntent.setClass(context, LinphoneService.class); + lLinphoneServiceIntent.putExtra("ForceStartForeground", true); Compatibility.startService(context, lLinphoneServiceIntent); } }