From 4c2b325676f25a973d5b74d69f78f7bd3b8392be Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Wed, 4 Oct 2017 00:40:59 +0900 Subject: [PATCH] Move all notification handling into common file --- .../syncthingandroid/DaggerComponent.java | 6 + .../syncthingandroid/SyncthingModule.java | 8 + .../activities/RestartActivity.java | 25 +-- .../receiver/AppConfigReceiver.java | 41 +---- .../service/EventProcessor.java | 18 +-- .../service/NotificationHandler.java | 145 ++++++++++++++++++ .../syncthingandroid/service/RestApi.java | 14 +- .../service/SyncthingRunnable.java | 27 +--- .../service/SyncthingService.java | 61 +------- .../syncthingandroid/util/ConfigXml.java | 1 - 10 files changed, 189 insertions(+), 157 deletions(-) create mode 100644 src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java diff --git a/src/main/java/com/nutomic/syncthingandroid/DaggerComponent.java b/src/main/java/com/nutomic/syncthingandroid/DaggerComponent.java index 28921cbe..02e85917 100644 --- a/src/main/java/com/nutomic/syncthingandroid/DaggerComponent.java +++ b/src/main/java/com/nutomic/syncthingandroid/DaggerComponent.java @@ -3,8 +3,11 @@ package com.nutomic.syncthingandroid; import com.nutomic.syncthingandroid.activities.FirstStartActivity; import com.nutomic.syncthingandroid.activities.FolderPickerActivity; import com.nutomic.syncthingandroid.activities.MainActivity; +import com.nutomic.syncthingandroid.receiver.AppConfigReceiver; import com.nutomic.syncthingandroid.service.DeviceStateHolder; import com.nutomic.syncthingandroid.service.EventProcessor; +import com.nutomic.syncthingandroid.service.NotificationHandler; +import com.nutomic.syncthingandroid.service.RestApi; import com.nutomic.syncthingandroid.service.SyncthingRunnable; import com.nutomic.syncthingandroid.service.SyncthingService; import com.nutomic.syncthingandroid.util.Languages; @@ -26,4 +29,7 @@ public interface DaggerComponent { void inject(DeviceStateHolder deviceStateHolder); void inject(EventProcessor eventProcessor); void inject(SyncthingRunnable syncthingRunnable); + void inject(NotificationHandler notificationHandler); + void inject(AppConfigReceiver appConfigReceiver); + void inject(RestApi restApi); } diff --git a/src/main/java/com/nutomic/syncthingandroid/SyncthingModule.java b/src/main/java/com/nutomic/syncthingandroid/SyncthingModule.java index 70a9ae77..c06c8a01 100644 --- a/src/main/java/com/nutomic/syncthingandroid/SyncthingModule.java +++ b/src/main/java/com/nutomic/syncthingandroid/SyncthingModule.java @@ -3,6 +3,8 @@ package com.nutomic.syncthingandroid; import android.content.SharedPreferences; import android.preference.PreferenceManager; +import com.nutomic.syncthingandroid.service.NotificationHandler; + import javax.inject.Singleton; import dagger.Module; @@ -22,4 +24,10 @@ public class SyncthingModule { public SharedPreferences getPreferences() { return PreferenceManager.getDefaultSharedPreferences(mApp); } + + @Provides + @Singleton + public NotificationHandler getNotificationHandler() { + return new NotificationHandler(mApp); + } } diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/RestartActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/RestartActivity.java index b403a2b4..27f104ec 100644 --- a/src/main/java/com/nutomic/syncthingandroid/activities/RestartActivity.java +++ b/src/main/java/com/nutomic/syncthingandroid/activities/RestartActivity.java @@ -1,16 +1,10 @@ package com.nutomic.syncthingandroid.activities; import android.app.AlertDialog; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; import android.os.Bundle; -import android.support.v4.app.NotificationCompat; import com.nutomic.syncthingandroid.R; -import com.nutomic.syncthingandroid.service.SyncthingService; +import com.nutomic.syncthingandroid.service.NotificationHandler; /** * Shows restart dialog. @@ -20,8 +14,6 @@ import com.nutomic.syncthingandroid.service.SyncthingService; */ public class RestartActivity extends SyncthingActivity { - public static final int NOTIFICATION_RESTART = 2; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -48,20 +40,7 @@ public class RestartActivity extends SyncthingActivity { * Creates a notification prompting the user to restart the app. */ private void createRestartNotification() { - Intent intent = new Intent(this, SyncthingService.class) - .setAction(SyncthingService.ACTION_RESTART); - PendingIntent pi = PendingIntent.getService(this, 0, intent, 0); - - Notification n = new NotificationCompat.Builder(this) - .setContentTitle(getString(R.string.restart_title)) - .setContentText(getString(R.string.restart_notification_text)) - .setSmallIcon(R.drawable.ic_stat_notify) - .setContentIntent(pi) - .build(); - n.flags |= Notification.FLAG_ONLY_ALERT_ONCE | Notification.FLAG_AUTO_CANCEL; - NotificationManager nm = (NotificationManager) - getSystemService(Context.NOTIFICATION_SERVICE); - nm.notify(NOTIFICATION_RESTART, n); + new NotificationHandler(getService()).showRestartNotification(); getApi().setRestartPostponed(); } diff --git a/src/main/java/com/nutomic/syncthingandroid/receiver/AppConfigReceiver.java b/src/main/java/com/nutomic/syncthingandroid/receiver/AppConfigReceiver.java index 81e1311c..01bf0169 100644 --- a/src/main/java/com/nutomic/syncthingandroid/receiver/AppConfigReceiver.java +++ b/src/main/java/com/nutomic/syncthingandroid/receiver/AppConfigReceiver.java @@ -1,25 +1,21 @@ package com.nutomic.syncthingandroid.receiver; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.os.Build; -import android.support.v4.app.NotificationCompat; -import com.nutomic.syncthingandroid.R; -import com.nutomic.syncthingandroid.activities.MainActivity; +import com.nutomic.syncthingandroid.SyncthingApp; +import com.nutomic.syncthingandroid.service.NotificationHandler; import com.nutomic.syncthingandroid.service.SyncthingService; +import javax.inject.Inject; + /** * Broadcast-receiver to control and configure SyncThing remotely * * Created by sqrt-1764 on 25.03.16. */ public class AppConfigReceiver extends BroadcastReceiver { - private static final int ID_NOTIFICATION_BACKGROUND_ACTIVE = 3; /** * Start the Syncthing-Service @@ -33,8 +29,11 @@ public class AppConfigReceiver extends BroadcastReceiver { */ public static final String ACTION_STOP = "com.nutomic.syncthingandroid.action.STOP"; + @Inject NotificationHandler mNotificationHandler; + @Override public void onReceive(Context context, Intent intent) { + ((SyncthingApp) context.getApplicationContext()).component().inject(this); switch (intent.getAction()) { case ACTION_START: context.startService(new Intent(context, SyncthingService.class)); @@ -42,31 +41,7 @@ public class AppConfigReceiver extends BroadcastReceiver { case ACTION_STOP: if (SyncthingService.alwaysRunInBackground(context)) { - final String msg = context.getString(R.string.appconfig_receiver_background_enabled); - - Context appContext = context.getApplicationContext(); - - NotificationCompat.Builder nb = new NotificationCompat.Builder(context) - .setContentText(msg) - .setTicker(msg) - .setStyle(new NotificationCompat.BigTextStyle().bigText(msg)) - .setContentTitle(context.getText(context.getApplicationInfo().labelRes)) - .setSmallIcon(R.drawable.ic_stat_notify) - .setAutoCancel(true) - .setContentIntent(PendingIntent.getActivity(appContext, - 0, - new Intent(appContext, MainActivity.class), - PendingIntent.FLAG_UPDATE_CURRENT)); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - nb.setCategory(Notification.CATEGORY_ERROR); // Only supported in API 21 or better - } - - NotificationManager nm = - (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); - - nm.notify(ID_NOTIFICATION_BACKGROUND_ACTIVE, nb.build()); - + mNotificationHandler.showStopSyncthingWarningNotification(); } else { context.stopService(new Intent(context, SyncthingService.class)); } diff --git a/src/main/java/com/nutomic/syncthingandroid/service/EventProcessor.java b/src/main/java/com/nutomic/syncthingandroid/service/EventProcessor.java index 480c036f..dd4b9cbf 100644 --- a/src/main/java/com/nutomic/syncthingandroid/service/EventProcessor.java +++ b/src/main/java/com/nutomic/syncthingandroid/service/EventProcessor.java @@ -1,7 +1,5 @@ package com.nutomic.syncthingandroid.service; -import android.app.Notification; -import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; @@ -9,8 +7,6 @@ import android.content.SharedPreferences; import android.net.Uri; import android.os.Handler; import android.os.Looper; -import android.preference.PreferenceManager; -import android.support.v4.app.NotificationCompat; import android.util.Log; import com.annimon.stream.Stream; @@ -56,6 +52,7 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene private final Context mContext; private final RestApi mApi; @Inject SharedPreferences mPreferences; + @Inject NotificationHandler mNotificationHandler; public EventProcessor(Context context, RestApi api) { ((SyncthingApp) context.getApplicationContext()).component().inject(this); @@ -200,20 +197,9 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene } private void notify(String text, PendingIntent pi) { - NotificationManager nm = (NotificationManager) - mContext.getSystemService(Context.NOTIFICATION_SERVICE); - Notification n = new NotificationCompat.Builder(mContext) - .setContentTitle(mContext.getString(R.string.app_name)) - .setContentText(text) - .setStyle(new NotificationCompat.BigTextStyle() - .bigText(text)) - .setContentIntent(pi) - .setSmallIcon(R.drawable.ic_stat_notify) - .setAutoCancel(true) - .build(); // HACK: Use a random, deterministic ID between 1000 and 2000 to avoid duplicate // notifications. int notificationId = 1000 + text.hashCode() % 1000; - nm.notify(notificationId, n); + mNotificationHandler.showEventNotification(text, pi, notificationId); } } diff --git a/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java b/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java new file mode 100644 index 00000000..decc4aa5 --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java @@ -0,0 +1,145 @@ +package com.nutomic.syncthingandroid.service; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.support.v4.app.NotificationCompat; + +import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.SyncthingApp; +import com.nutomic.syncthingandroid.activities.FirstStartActivity; +import com.nutomic.syncthingandroid.activities.MainActivity; + +import javax.inject.Inject; + +public class NotificationHandler { + + private static final int ID_PERSISTENT = 1; + private static final int ID_RESTART = 2; + private static final int ID_STOP_BACKGROUND_WARNING = 3; + private static final int ID_CRASH = 9; + + private final Context mContext; + @Inject SharedPreferences mPreferences; + private final NotificationManager mNotificationManager; + + public NotificationHandler(Context context) { + ((SyncthingApp) context.getApplicationContext()).component().inject(this); + mContext = context; + mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); + } + + /** + * Shows or hides the persistent notification based on running state and + * {@link SyncthingService#PREF_NOTIFICATION_TYPE}. + */ + public void updatePersistentNotification(SyncthingService service, SyncthingService.State currentState) { + String type = mPreferences.getString(SyncthingService.PREF_NOTIFICATION_TYPE, "low_priority"); + boolean foreground = mPreferences.getBoolean(SyncthingService.PREF_FOREGROUND_SERVICE, false); + if ("none".equals(type) && foreground) { + // foreground priority requires any notification + // so this ensures that we either have a "default" or "low_priority" notification, + // but not "none". + type = "low_priority"; + } + if ((currentState == SyncthingService.State.ACTIVE || currentState == SyncthingService.State.STARTING) && + !type.equals("none")) { + // Launch FirstStartActivity instead of MainActivity so we can request permission if + // necessary. + PendingIntent pi = PendingIntent.getActivity(mContext, 0, + new Intent(mContext, FirstStartActivity.class), 0); + NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext) + .setContentTitle(mContext.getString(R.string.syncthing_active)) + .setSmallIcon(R.drawable.ic_stat_notify) + .setOngoing(true) + .setContentIntent(pi); + if (type.equals("low_priority")) + builder.setPriority(NotificationCompat.PRIORITY_MIN); + + if (foreground) { + builder.setContentText(mContext.getString(R.string.syncthing_active_foreground)); + service.startForeground(ID_PERSISTENT, builder.build()); + } else { + service.stopForeground(false); // ensure no longer running with foreground priority + mNotificationManager.notify(ID_PERSISTENT, builder.build()); + } + } else { + // ensure no longer running with foreground priority + cancelPersistentNotification(service); + } + } + + public void cancelPersistentNotification(SyncthingService service) { + service.stopForeground(false); + mNotificationManager.cancel(ID_PERSISTENT); + } + + public void showCrashedNotification(Intent intent) { + if (mPreferences.getBoolean("notify_crashes", false)) { + Notification n = new NotificationCompat.Builder(mContext) + .setContentTitle(mContext.getString(R.string.notification_crash_title)) + .setContentText(mContext.getString(R.string.notification_crash_text)) + .setSmallIcon(R.drawable.ic_stat_notify) + .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0)) + .setAutoCancel(true) + .build(); + mNotificationManager.notify(ID_CRASH, n); + } + } + + public void showEventNotification(String text, PendingIntent pi, int id) { + Notification n = new NotificationCompat.Builder(mContext) + .setContentTitle(mContext.getString(R.string.app_name)) + .setContentText(text) + .setStyle(new NotificationCompat.BigTextStyle() + .bigText(text)) + .setContentIntent(pi) + .setSmallIcon(R.drawable.ic_stat_notify) + .setAutoCancel(true) + .build(); + mNotificationManager.notify(id, n); + } + + public void showRestartNotification() { + Intent intent = new Intent(mContext, SyncthingService.class) + .setAction(SyncthingService.ACTION_RESTART); + PendingIntent pi = PendingIntent.getService(mContext, 0, intent, 0); + + Notification n = new NotificationCompat.Builder(mContext) + .setContentTitle(mContext.getString(R.string.restart_title)) + .setContentText(mContext.getString(R.string.restart_notification_text)) + .setSmallIcon(R.drawable.ic_stat_notify) + .setContentIntent(pi) + .build(); + n.flags |= Notification.FLAG_ONLY_ALERT_ONCE | Notification.FLAG_AUTO_CANCEL; + mNotificationManager.notify(ID_RESTART, n); + } + + public void cancelRestartNotification() { + mNotificationManager.cancel(ID_RESTART); + } + + public void showStopSyncthingWarningNotification() { + final String msg = mContext.getString(R.string.appconfig_receiver_background_enabled); + NotificationCompat.Builder nb = new NotificationCompat.Builder(mContext) + .setContentText(msg) + .setTicker(msg) + .setStyle(new NotificationCompat.BigTextStyle().bigText(msg)) + .setContentTitle(mContext.getText(mContext.getApplicationInfo().labelRes)) + .setSmallIcon(R.drawable.ic_stat_notify) + .setAutoCancel(true) + .setContentIntent(PendingIntent.getActivity(mContext, 0, + new Intent(mContext, MainActivity.class), + PendingIntent.FLAG_UPDATE_CURRENT)); + + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + nb.setCategory(Notification.CATEGORY_ERROR); + } + mNotificationManager.notify(ID_STOP_BACKGROUND_WARNING, nb.build()); + } +} diff --git a/src/main/java/com/nutomic/syncthingandroid/service/RestApi.java b/src/main/java/com/nutomic/syncthingandroid/service/RestApi.java index 0f1ca7b2..4fff5500 100644 --- a/src/main/java/com/nutomic/syncthingandroid/service/RestApi.java +++ b/src/main/java/com/nutomic/syncthingandroid/service/RestApi.java @@ -1,7 +1,6 @@ package com.nutomic.syncthingandroid.service; import android.app.Activity; -import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.util.Log; @@ -17,6 +16,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.nutomic.syncthingandroid.BuildConfig; +import com.nutomic.syncthingandroid.SyncthingApp; import com.nutomic.syncthingandroid.activities.RestartActivity; import com.nutomic.syncthingandroid.http.GetRequest; import com.nutomic.syncthingandroid.http.PostConfigRequest; @@ -43,6 +43,8 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import javax.inject.Inject; + /** * Provides functions to interact with the syncthing REST API. */ @@ -100,8 +102,11 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, */ private final HashMap mCachedModelInfo = new HashMap<>(); + @Inject NotificationHandler mNotificationHandler; + public RestApi(Context context, URL url, String apiKey, OnApiAvailableListener apiListener, OnConfigChangedListener configListener) { + ((SyncthingApp) context.getApplicationContext()).component().inject(this); mContext = context; mUrl = url; mApiKey = apiKey; @@ -195,13 +200,8 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener, }); } - /** - * Stops syncthing and cancels notification. - */ public void shutdown() { - NotificationManager nm = (NotificationManager) - mContext.getSystemService(Context.NOTIFICATION_SERVICE); - nm.cancel(RestartActivity.NOTIFICATION_RESTART); + mNotificationHandler.cancelRestartNotification(); mRestartPostponed = false; } diff --git a/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java b/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java index 0798a30e..7833d284 100644 --- a/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java +++ b/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java @@ -1,21 +1,16 @@ package com.nutomic.syncthingandroid.service; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Environment; import android.os.PowerManager; -import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; import com.google.common.base.Charsets; import com.google.common.io.Files; -import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.SyncthingApp; import java.io.BufferedReader; @@ -50,7 +45,6 @@ public class SyncthingRunnable implements Runnable { private static final String TAG_KILL = "SyncthingRunnableKill"; private static final String BINARY_NAME = "libsyncthing.so"; private static final int LOG_FILE_MAX_LINES = 10; - private static final int NOTIFICATION_ID_CRASH = 9; private static final AtomicReference mSyncthing = new AtomicReference<>(); private final Context mContext; @@ -59,6 +53,7 @@ public class SyncthingRunnable implements Runnable { private final File mLogFile; @Inject SharedPreferences mPreferences; private final boolean mUseRoot; + @Inject NotificationHandler mNotificationHandler; public enum Command { generate, // Generate keys, a config file and immediately exit. @@ -146,22 +141,10 @@ public class SyncthingRunnable implements Runnable { break; default: Log.w(TAG, "Syncthing has crashed (exit code " + ret + ")"); - if (mPreferences.getBoolean("notify_crashes", false)) { - // Show notification to inform user about crash. - Intent intent = new Intent(); - intent.setAction(android.content.Intent.ACTION_VIEW); - intent.setDataAndType(Uri.fromFile(mLogFile), "text/plain"); - Notification n = new NotificationCompat.Builder(mContext) - .setContentTitle(mContext.getString(R.string.notification_crash_title)) - .setContentText(mContext.getString(R.string.notification_crash_text)) - .setSmallIcon(R.drawable.ic_stat_notify) - .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0)) - .setAutoCancel(true) - .build(); - NotificationManager nm = (NotificationManager) - mContext.getSystemService(Context.NOTIFICATION_SERVICE); - nm.notify(NOTIFICATION_ID_CRASH, n); - } + // Show notification to inform user about crash. + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(Uri.fromFile(mLogFile), "text/plain"); + mNotificationHandler.showCrashedNotification(intent); } } catch (IOException | InterruptedException e) { Log.e(TAG, "Failed to execute syncthing binary or read output", e); diff --git a/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java b/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java index 8bd58caa..fcf7e57e 100644 --- a/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java +++ b/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java @@ -1,7 +1,5 @@ package com.nutomic.syncthingandroid.service; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; @@ -16,7 +14,6 @@ import android.os.IBinder; import android.os.PowerManager; import android.preference.PreferenceManager; import android.support.annotation.Nullable; -import android.support.v4.app.NotificationCompat; import android.util.Log; import android.widget.Toast; @@ -25,7 +22,6 @@ import com.annimon.stream.Stream; import com.google.common.io.Files; import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.SyncthingApp; -import com.nutomic.syncthingandroid.activities.FirstStartActivity; import com.nutomic.syncthingandroid.http.PollWebGuiAvailableTask; import com.nutomic.syncthingandroid.model.Folder; import com.nutomic.syncthingandroid.receiver.NetworkReceiver; @@ -95,12 +91,10 @@ public class SyncthingService extends Service implements public static final String PREF_SYNC_ONLY_CHARGING = "sync_only_charging"; public static final String PREF_RESPECT_BATTERY_SAVING = "respect_battery_saving"; public static final String PREF_USE_ROOT = "use_root"; - private static final String PREF_NOTIFICATION_TYPE = "notification_type"; + public static final String PREF_NOTIFICATION_TYPE = "notification_type"; public static final String PREF_USE_WAKE_LOCK = "wakelock_while_binary_running"; public static final String PREF_FOREGROUND_SERVICE = "run_as_foreground_service"; - private static final int NOTIFICATION_ACTIVE = 1; - /** * Callback for when the Syncthing web interface becomes first available after service start. */ @@ -149,6 +143,8 @@ public class SyncthingService extends Service implements private final NetworkReceiver mNetworkReceiver = new NetworkReceiver(); private final BroadcastReceiver mPowerSaveModeChangedReceiver = new PowerSaveModeChangedReceiver(); + @Inject NotificationHandler mNotificationHandler; + /** * Object that can be locked upon when accessing mCurrentState * Currently used to male onDestroy() and PollWebGuiAvailableTaskImpl.onPostExcecute() tread-safe @@ -220,53 +216,10 @@ public class SyncthingService extends Service implements } } - /** - * Shows or hides the persistent notification based on running state and - * {@link #PREF_NOTIFICATION_TYPE}. - */ - private void updateNotification() { - String type = mPreferences.getString(PREF_NOTIFICATION_TYPE, "low_priority"); - boolean foreground = mPreferences.getBoolean(PREF_FOREGROUND_SERVICE, false); - if ("none".equals(type) && foreground) { - // foreground priority requires any notification - // so this ensures that we either have a "default" or "low_priority" notification, - // but not "none". - type = "low_priority"; - } - NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - if ((mCurrentState == State.ACTIVE || mCurrentState == State.STARTING) && - !type.equals("none")) { - Context appContext = getApplicationContext(); - // Launch FirstStartActivity instead of MainActivity so we can request permission if - // necessary. - PendingIntent pi = PendingIntent.getActivity(appContext, 0, - new Intent(appContext, FirstStartActivity.class), 0); - NotificationCompat.Builder builder = new NotificationCompat.Builder(appContext) - .setContentTitle(getString(R.string.syncthing_active)) - .setSmallIcon(R.drawable.ic_stat_notify) - .setOngoing(true) - .setContentIntent(pi); - if (type.equals("low_priority")) - builder.setPriority(NotificationCompat.PRIORITY_MIN); - - if (foreground) { - builder.setContentText(getString(R.string.syncthing_active_foreground)); - startForeground(NOTIFICATION_ACTIVE, builder.build()); - } else { - stopForeground(false); // ensure no longer running with foreground priority - nm.notify(NOTIFICATION_ACTIVE, builder.build()); - } - } else { - // ensure no longer running with foreground priority - stopForeground(false); - nm.cancel(NOTIFICATION_ACTIVE); - } - } - @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (key.equals(PREF_NOTIFICATION_TYPE) || key.equals(PREF_FOREGROUND_SERVICE)) - updateNotification(); + mNotificationHandler.updatePersistentNotification(this, mCurrentState); else if (key.equals(PREF_SYNC_ONLY_CHARGING) || key.equals(PREF_SYNC_ONLY_WIFI) || key.equals(PREF_SYNC_ONLY_WIFI_SSIDS) || key.equals(PREF_RESPECT_BATTERY_SAVING)) { updateState(); @@ -338,7 +291,6 @@ public class SyncthingService extends Service implements pollWebGui(); mSyncthingRunnable = new SyncthingRunnable(SyncthingService.this, SyncthingRunnable.Command.main); new Thread(mSyncthingRunnable).start(); - updateNotification(); } } @@ -409,9 +361,7 @@ public class SyncthingService extends Service implements if (mApi != null) mApi.shutdown(); - NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - stopForeground(false); - nm.cancel(NOTIFICATION_ACTIVE); + mNotificationHandler.cancelPersistentNotification(this); Stream.of(mObservers).forEach(FolderObserver::stopWatching); mObservers.clear(); @@ -498,6 +448,7 @@ public class SyncthingService extends Service implements */ private void onApiChange(State newState) { mCurrentState = newState; + mNotificationHandler.updatePersistentNotification(this, mCurrentState); for (Iterator i = mOnApiChangeListeners.iterator(); i.hasNext(); ) { OnApiChangeListener listener = i.next(); diff --git a/src/main/java/com/nutomic/syncthingandroid/util/ConfigXml.java b/src/main/java/com/nutomic/syncthingandroid/util/ConfigXml.java index 3324ebad..b186ba9e 100644 --- a/src/main/java/com/nutomic/syncthingandroid/util/ConfigXml.java +++ b/src/main/java/com/nutomic/syncthingandroid/util/ConfigXml.java @@ -8,7 +8,6 @@ import android.util.Log; import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.service.SyncthingRunnable; -import com.nutomic.syncthingandroid.util.Util; import org.mindrot.jbcrypt.BCrypt; import org.w3c.dom.Document;