diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java b/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java index 9f0e92ad24..8f42c88404 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsNotifications.java @@ -52,6 +52,8 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared private Button btnManage; private Button btnManageDefault; private Button btnManageService; + private SwitchCompat swBackground; + private CheckBox cbNotifyActionTrash; private CheckBox cbNotifyActionJunk; private CheckBox cbNotifyActionBlockSender; @@ -106,6 +108,8 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared btnManage = view.findViewById(R.id.btnManage); btnManageDefault = view.findViewById(R.id.btnManageDefault); btnManageService = view.findViewById(R.id.btnManageService); + swBackground = view.findViewById(R.id.swBackground); + cbNotifyActionTrash = view.findViewById(R.id.cbNotifyActionTrash); cbNotifyActionJunk = view.findViewById(R.id.cbNotifyActionJunk); cbNotifyActionBlockSender = view.findViewById(R.id.cbNotifyActionBlockSender); @@ -180,6 +184,14 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared } }); + swBackground.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("background_service", checked).apply(); + ServiceSynchronize.eval(getContext(), "background=" + checked); + } + }); + cbNotifyActionTrash.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean checked) { @@ -406,6 +418,8 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared boolean pro = ActivityBilling.isPro(getContext()); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + swBackground.setChecked(prefs.getBoolean("background_service", false)); + cbNotifyActionTrash.setChecked(prefs.getBoolean("notify_trash", true) || !pro); cbNotifyActionJunk.setChecked(prefs.getBoolean("notify_junk", false) && pro); cbNotifyActionBlockSender.setChecked(prefs.getBoolean("notify_block_sender", false) && pro); diff --git a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java index e82a801342..23a8685913 100644 --- a/app/src/main/java/eu/faircode/email/ServiceSynchronize.java +++ b/app/src/main/java/eu/faircode/email/ServiceSynchronize.java @@ -136,7 +136,13 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences public void onCreate() { EntityLog.log(this, "Service create version=" + BuildConfig.VERSION_NAME); super.onCreate(); - startForeground(Helper.NOTIFICATION_SYNCHRONIZE, getNotificationService(null, null).build()); + + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + boolean background_service = prefs.getBoolean("background_service", false); + if (background_service) + stopForeground(true); + else + startForeground(Helper.NOTIFICATION_SYNCHRONIZE, getNotificationService(null, null).build()); handler = new Handler(); @@ -278,10 +284,13 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences WorkerFts.cancel(ServiceSynchronize.this); } - try { - NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - nm.notify(Helper.NOTIFICATION_SYNCHRONIZE, getNotificationService(lastAccounts, lastOperations).build()); - } catch (Throwable ex) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ServiceSynchronize.this); + boolean background_service = prefs.getBoolean("background_service", false); + if (!background_service) + try { + NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + nm.notify(Helper.NOTIFICATION_SYNCHRONIZE, getNotificationService(lastAccounts, lastOperations).build()); + } catch (Throwable ex) { /* java.lang.NullPointerException: Attempt to invoke interface method 'java.util.Iterator java.lang.Iterable.iterator()' on a null object reference at android.app.ApplicationPackageManager.getUserIfProfile(ApplicationPackageManager.java:2167) @@ -293,8 +302,8 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences at androidx.core.app.NotificationCompatBuilder.build(SourceFile:247) at androidx.core.app.NotificationCompat$Builder.build(SourceFile:1677) */ - Log.w(ex); - } + Log.w(ex); + } } if (!runService) @@ -420,8 +429,6 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences } }); - final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - final TwoStateOwner cowner = new TwoStateOwner(this, "liveUnseenNotify"); db.folder().liveSynchronizing().observe(this, new Observer() { @@ -666,7 +673,13 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences Log.logExtras(intent); super.onStartCommand(intent, flags, startId); - startForeground(Helper.NOTIFICATION_SYNCHRONIZE, getNotificationService(null, null).build()); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + boolean background_service = prefs.getBoolean("background_service", false); + if (background_service) + stopForeground(true); + else + startForeground(Helper.NOTIFICATION_SYNCHRONIZE, getNotificationService(null, null).build()); if (action != null) try { @@ -1701,12 +1714,16 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences "Updated network=" + network + " capabilities " + capabilities + " suitable=" + lastSuitable); - try { - NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); - nm.notify(Helper.NOTIFICATION_SYNCHRONIZE, getNotificationService(lastAccounts, lastOperations).build()); - } catch (Throwable ex) { - Log.w(ex); - } + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ServiceSynchronize.this); + boolean background_service = prefs.getBoolean("background_service", false); + if (!background_service) + try { + NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + nm.notify(Helper.NOTIFICATION_SYNCHRONIZE, getNotificationService(lastAccounts, lastOperations).build()); + } catch (Throwable ex) { + Log.w(ex); + } } } }; @@ -1962,14 +1979,14 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences } static void eval(Context context, String reason) { - ContextCompat.startForegroundService(context, + start(context, new Intent(context, ServiceSynchronize.class) .setAction("eval") .putExtra("reason", reason)); } static void reload(Context context, Long account, boolean force, String reason) { - ContextCompat.startForegroundService(context, + start(context, new Intent(context, ServiceSynchronize.class) .setAction("reload") .putExtra("account", account == null ? -1 : account) @@ -1978,14 +1995,23 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences } static void reschedule(Context context) { - ContextCompat.startForegroundService(context, + start(context, new Intent(context, ServiceSynchronize.class) .setAction("alarm")); } static void watchdog(Context context) { - ContextCompat.startForegroundService(context, + start(context, new Intent(context, ServiceSynchronize.class) .setAction("watchdog")); } + + private static void start(Context context, Intent intent) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean background_service = prefs.getBoolean("background_service", false); + if (background_service) + context.startService(intent); + else + ContextCompat.startForegroundService(context, intent); + } } diff --git a/app/src/main/res/layout/fragment_options_notifications.xml b/app/src/main/res/layout/fragment_options_notifications.xml index 45ff3547c6..92687b32a8 100644 --- a/app/src/main/res/layout/fragment_options_notifications.xml +++ b/app/src/main/res/layout/fragment_options_notifications.xml @@ -94,6 +94,30 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/btnManageService" /> + + + + + app:layout_constraintTop_toBottomOf="@id/tvBackgroundHint" /> Manage notifications Default channel Service channel + Use background service + A background service can be stopped by Android at any time, but doesn\'t require a status bar notification Show launcher icon with number of new messages Let the number of new messages match the number of notifications