diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 78451542..d5fc515b 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -108,18 +108,6 @@
android:value=".activities.MainActivity" />
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/java/com/nutomic/syncthingandroid/DaggerComponent.java b/src/main/java/com/nutomic/syncthingandroid/DaggerComponent.java
index 02e85917..9e1d851f 100644
--- a/src/main/java/com/nutomic/syncthingandroid/DaggerComponent.java
+++ b/src/main/java/com/nutomic/syncthingandroid/DaggerComponent.java
@@ -3,6 +3,7 @@ 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.activities.SettingsActivity;
import com.nutomic.syncthingandroid.receiver.AppConfigReceiver;
import com.nutomic.syncthingandroid.service.DeviceStateHolder;
import com.nutomic.syncthingandroid.service.EventProcessor;
@@ -32,4 +33,5 @@ public interface DaggerComponent {
void inject(NotificationHandler notificationHandler);
void inject(AppConfigReceiver appConfigReceiver);
void inject(RestApi restApi);
+ void inject(SettingsActivity.SettingsFragment fragment);
}
diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java
index 50d5fb9e..3996ad84 100644
--- a/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java
+++ b/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java
@@ -2,6 +2,7 @@ package com.nutomic.syncthingandroid.activities;
import android.app.AlertDialog;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Build;
@@ -12,6 +13,7 @@ import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
+import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
@@ -19,10 +21,12 @@ import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.nutomic.syncthingandroid.R;
+import com.nutomic.syncthingandroid.SyncthingApp;
import com.nutomic.syncthingandroid.model.Config;
import com.nutomic.syncthingandroid.model.Device;
import com.nutomic.syncthingandroid.model.Options;
import com.nutomic.syncthingandroid.service.Constants;
+import com.nutomic.syncthingandroid.service.NotificationHandler;
import com.nutomic.syncthingandroid.service.RestApi;
import com.nutomic.syncthingandroid.service.SyncthingService;
import com.nutomic.syncthingandroid.util.Languages;
@@ -31,6 +35,8 @@ import com.nutomic.syncthingandroid.views.WifiSsidPreference;
import java.security.InvalidParameterException;
+import javax.inject.Inject;
+
import eu.chainfire.libsuperuser.Shell;
public class SettingsActivity extends SyncthingActivity {
@@ -46,7 +52,7 @@ public class SettingsActivity extends SyncthingActivity {
public static class SettingsFragment extends PreferenceFragment
implements SyncthingActivity.OnServiceConnectedListener,
SyncthingService.OnApiChangeListener, Preference.OnPreferenceChangeListener,
- Preference.OnPreferenceClickListener {
+ Preference.OnPreferenceClickListener, SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "SettingsFragment";
private static final String KEY_STTRACE = "sttrace";
@@ -54,6 +60,9 @@ public class SettingsActivity extends SyncthingActivity {
private static final String KEY_IMPORT_CONFIG = "import_config";
private static final String KEY_STRESET = "streset";
+ @Inject NotificationHandler mNotificationHandler;
+ @Inject SharedPreferences mPreferences;
+
private CheckBoxPreference mAlwaysRunInBackground;
private CheckBoxPreference mSyncOnlyCharging;
private CheckBoxPreference mSyncOnlyWifi;
@@ -84,6 +93,14 @@ public class SettingsActivity extends SyncthingActivity {
private Options mOptions;
private Config.Gui mGui;
+ @Override
+ public void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ((SyncthingApp) getActivity().getApplication()).component().inject(this);
+ ((SyncthingActivity) getActivity()).registerOnServiceConnectedListener(this);
+ mPreferences.registerOnSharedPreferenceChangeListener(this);
+ }
+
/**
* Loads layout, sets version from Rest API.
*
@@ -93,8 +110,6 @@ public class SettingsActivity extends SyncthingActivity {
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- ((SyncthingActivity) getActivity()).registerOnServiceConnectedListener(this);
-
addPreferencesFromResource(R.xml.app_settings);
PreferenceScreen screen = getPreferenceScreen();
mAlwaysRunInBackground =
@@ -228,6 +243,7 @@ public class SettingsActivity extends SyncthingActivity {
@Override
public void onDestroy() {
super.onDestroy();
+ mPreferences.unregisterOnSharedPreferenceChangeListener(this);
if (mSyncthingService != null)
mSyncthingService.unregisterOnApiChangeListener(this);
}
@@ -394,6 +410,13 @@ public class SettingsActivity extends SyncthingActivity {
}
}
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if (key.equals(Constants.PREF_NOTIFICATION_TYPE) || key.equals(Constants.PREF_FOREGROUND_SERVICE)) {
+ mNotificationHandler.updatePersistentNotification(mSyncthingService);
+ }
+ }
+
/**
* Enables or disables {@link #mUseRoot} preference depending whether root is available.
*/
diff --git a/src/main/java/com/nutomic/syncthingandroid/receiver/BatteryReceiver.java b/src/main/java/com/nutomic/syncthingandroid/receiver/BatteryReceiver.java
index 27536956..3c705dc3 100644
--- a/src/main/java/com/nutomic/syncthingandroid/receiver/BatteryReceiver.java
+++ b/src/main/java/com/nutomic/syncthingandroid/receiver/BatteryReceiver.java
@@ -29,9 +29,6 @@ public class BatteryReceiver extends BroadcastReceiver {
Intent i = new Intent(DeviceStateHolder.ACTION_DEVICE_STATE_CHANGED);
i.putExtra(DeviceStateHolder.EXTRA_IS_CHARGING, isCharging);
lbm.sendBroadcast(i);
-
- // Make sure service is running.
- BootReceiver.startServiceCompat(context);
}
/**
diff --git a/src/main/java/com/nutomic/syncthingandroid/receiver/BootReceiver.java b/src/main/java/com/nutomic/syncthingandroid/receiver/BootReceiver.java
index e97eddee..7b9b2afb 100644
--- a/src/main/java/com/nutomic/syncthingandroid/receiver/BootReceiver.java
+++ b/src/main/java/com/nutomic/syncthingandroid/receiver/BootReceiver.java
@@ -27,7 +27,7 @@ public class BootReceiver extends BroadcastReceiver {
*
* https://stackoverflow.com/a/44505719/1837158
*/
- public static void startServiceCompat(Context context) {
+ private static void startServiceCompat(Context context) {
// This method is called from {@link DeviceStateHolder#DeviceStateHolder()}, make sure it
// is only executed if run in background is enabled.
if (!DeviceStateHolder.alwaysRunInBackground(context))
diff --git a/src/main/java/com/nutomic/syncthingandroid/receiver/NetworkReceiver.java b/src/main/java/com/nutomic/syncthingandroid/receiver/NetworkReceiver.java
index dd359eda..91fc46ba 100644
--- a/src/main/java/com/nutomic/syncthingandroid/receiver/NetworkReceiver.java
+++ b/src/main/java/com/nutomic/syncthingandroid/receiver/NetworkReceiver.java
@@ -42,9 +42,6 @@ public class NetworkReceiver extends BroadcastReceiver {
Intent intent = new Intent(DeviceStateHolder.ACTION_DEVICE_STATE_CHANGED);
intent.putExtra(DeviceStateHolder.EXTRA_IS_ALLOWED_NETWORK_CONNECTION, isAllowedConnection);
lbm.sendBroadcast(intent);
-
- // Make sure service is running.
- BootReceiver.startServiceCompat(context);
}
}
diff --git a/src/main/java/com/nutomic/syncthingandroid/service/DeviceStateHolder.java b/src/main/java/com/nutomic/syncthingandroid/service/DeviceStateHolder.java
index d877ff79..657eb6db 100644
--- a/src/main/java/com/nutomic/syncthingandroid/service/DeviceStateHolder.java
+++ b/src/main/java/com/nutomic/syncthingandroid/service/DeviceStateHolder.java
@@ -5,18 +5,24 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
+import android.os.Build;
+import android.os.PowerManager;
import android.preference.PreferenceManager;
+import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
+import com.google.common.collect.Lists;
import com.nutomic.syncthingandroid.SyncthingApp;
import com.nutomic.syncthingandroid.receiver.BatteryReceiver;
import com.nutomic.syncthingandroid.receiver.NetworkReceiver;
import com.nutomic.syncthingandroid.receiver.PowerSaveModeChangedReceiver;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import javax.inject.Inject;
@@ -27,7 +33,7 @@ import javax.inject.Inject;
* This information is actively read on instance creation, and then updated from intents
* that are passed with {@link #ACTION_DEVICE_STATE_CHANGED}.
*/
-public class DeviceStateHolder {
+public class DeviceStateHolder implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = "DeviceStateHolder";
@@ -68,25 +74,87 @@ public class DeviceStateHolder {
private final OnDeviceStateChangedListener mListener;
@Inject SharedPreferences mPreferences;
- private boolean mIsAllowedNetworkConnection = false;
+ private @Nullable NetworkReceiver mNetworkReceiver;
+ private @Nullable BatteryReceiver mBatteryReceiver;
+ private @Nullable BroadcastReceiver mPowerSaveModeChangedReceiver;
+
+ private boolean mIsAllowedNetworkConnection;
private String mWifiSsid;
- private boolean mIsCharging = false;
- private boolean mIsPowerSaving = true;
+ private boolean mIsCharging;
+ private boolean mIsPowerSaving;
public DeviceStateHolder(Context context, OnDeviceStateChangedListener listener) {
((SyncthingApp) context.getApplicationContext()).component().inject(this);
mContext = context;
mBroadcastManager = LocalBroadcastManager.getInstance(mContext);
mBroadcastManager.registerReceiver(mReceiver, new IntentFilter(ACTION_DEVICE_STATE_CHANGED));
+ mPreferences.registerOnSharedPreferenceChangeListener(this);
mListener = listener;
-
- BatteryReceiver.updateInitialChargingStatus(mContext);
- NetworkReceiver.updateNetworkStatus(mContext);
- PowerSaveModeChangedReceiver.updatePowerSavingState(mContext);
+ updateReceivers();
}
public void shutdown() {
mBroadcastManager.unregisterReceiver(mReceiver);
+ mPreferences.unregisterOnSharedPreferenceChangeListener(this);
+
+ unregisterReceiver(mNetworkReceiver);
+ unregisterReceiver(mBatteryReceiver);
+ unregisterReceiver(mPowerSaveModeChangedReceiver);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ List watched = Lists.newArrayList(Constants.PREF_SYNC_ONLY_CHARGING,
+ Constants.PREF_SYNC_ONLY_WIFI, Constants.PREF_RESPECT_BATTERY_SAVING,
+ Constants.PREF_SYNC_ONLY_WIFI_SSIDS);
+ if (watched.contains(key)) {
+ updateReceivers();
+ }
+ }
+
+ private void updateReceivers() {
+ if (mPreferences.getBoolean(Constants.PREF_SYNC_ONLY_WIFI, false)) {
+ Log.i(TAG, "Listening for network state changes");
+ NetworkReceiver.updateNetworkStatus(mContext);
+ mNetworkReceiver = new NetworkReceiver();
+ mContext.registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
+ } else {
+ Log.i(TAG, "Stopped listening to network state changes");
+ unregisterReceiver(mNetworkReceiver);
+ mNetworkReceiver = null;
+ }
+
+ if (mPreferences.getBoolean(Constants.PREF_SYNC_ONLY_CHARGING, false)) {
+ Log.i(TAG, "Listening to battery state changes");
+ BatteryReceiver.updateInitialChargingStatus(mContext);
+ mBatteryReceiver = new BatteryReceiver();
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_POWER_CONNECTED);
+ filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
+ mContext.registerReceiver(mBatteryReceiver, filter);
+ } else {
+ Log.i(TAG, "Stopped listening to battery state changes");
+ unregisterReceiver(mBatteryReceiver);
+ mBatteryReceiver = null;
+ }
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
+ mPreferences.getBoolean("respect_battery_saving", true)) {
+ Log.i(TAG, "Listening to power saving changes");
+ PowerSaveModeChangedReceiver.updatePowerSavingState(mContext);
+ mPowerSaveModeChangedReceiver = new PowerSaveModeChangedReceiver();
+ mContext.registerReceiver(mPowerSaveModeChangedReceiver,
+ new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
+ } else {
+ Log.i(TAG, "Stopped listening to power saving changes");
+ unregisterReceiver(mPowerSaveModeChangedReceiver);
+ mPowerSaveModeChangedReceiver = null;
+ }
+ }
+
+ private void unregisterReceiver(BroadcastReceiver receiver) {
+ if (receiver != null)
+ mContext.unregisterReceiver(receiver);
}
private class DeviceStateChangedReceiver extends BroadcastReceiver {
@@ -154,7 +222,6 @@ public class DeviceStateHolder {
}
}
}
- Log.d(TAG, "Wifi not connected");
return false;
}
diff --git a/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java b/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java
index 9fc8c39c..8b3ee155 100644
--- a/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java
+++ b/src/main/java/com/nutomic/syncthingandroid/service/NotificationHandler.java
@@ -39,7 +39,7 @@ public class NotificationHandler {
* Shows or hides the persistent notification based on running state and
* {@link Constants#PREF_NOTIFICATION_TYPE}.
*/
- public void updatePersistentNotification(SyncthingService service, SyncthingService.State currentState) {
+ public void updatePersistentNotification(SyncthingService service) {
String type = mPreferences.getString(Constants.PREF_NOTIFICATION_TYPE, "low_priority");
boolean foreground = mPreferences.getBoolean(Constants.PREF_FOREGROUND_SERVICE, false);
@@ -57,8 +57,8 @@ public class NotificationHandler {
type = "low_priority";
}
- boolean syncthingRunning = currentState == SyncthingService.State.ACTIVE ||
- currentState == SyncthingService.State.STARTING;
+ boolean syncthingRunning = service.getCurrentState() == SyncthingService.State.ACTIVE ||
+ service.getCurrentState() == SyncthingService.State.STARTING;
if (foreground || (syncthingRunning && !type.equals("none"))) {
// Launch FirstStartActivity instead of MainActivity so we can request permission if
// necessary.
diff --git a/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java b/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java
index 12d0ced0..828b25af 100644
--- a/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java
+++ b/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java
@@ -1,15 +1,10 @@
package com.nutomic.syncthingandroid.service;
import android.app.Service;
-import android.content.BroadcastReceiver;
import android.content.Intent;
-import android.content.IntentFilter;
import android.content.SharedPreferences;
-import android.net.ConnectivityManager;
import android.os.AsyncTask;
-import android.os.Build;
import android.os.IBinder;
-import android.os.PowerManager;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;
@@ -21,8 +16,6 @@ import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.SyncthingApp;
import com.nutomic.syncthingandroid.http.PollWebGuiAvailableTask;
import com.nutomic.syncthingandroid.model.Folder;
-import com.nutomic.syncthingandroid.receiver.NetworkReceiver;
-import com.nutomic.syncthingandroid.receiver.PowerSaveModeChangedReceiver;
import com.nutomic.syncthingandroid.util.ConfigXml;
import com.nutomic.syncthingandroid.util.FolderObserver;
@@ -38,8 +31,7 @@ import javax.inject.Inject;
/**
* Holds the native syncthing instance and provides an API to access it.
*/
-public class SyncthingService extends Service implements
- SharedPreferences.OnSharedPreferenceChangeListener {
+public class SyncthingService extends Service {
private static final String TAG = "SyncthingService";
@@ -96,8 +88,6 @@ public class SyncthingService extends Service implements
private final LinkedList mObservers = new LinkedList<>();
private final HashSet mOnApiChangeListeners = new HashSet<>();
private final SyncthingServiceBinder mBinder = new SyncthingServiceBinder(this);
- private final NetworkReceiver mNetworkReceiver = new NetworkReceiver();
- private final BroadcastReceiver mPowerSaveModeChangedReceiver = new PowerSaveModeChangedReceiver();
@Inject NotificationHandler mNotificationHandler;
@Inject SharedPreferences mPreferences;
@@ -167,16 +157,6 @@ public class SyncthingService extends Service implements
}
}
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (key.equals(Constants.PREF_NOTIFICATION_TYPE) || key.equals(Constants.PREF_FOREGROUND_SERVICE))
- mNotificationHandler.updatePersistentNotification(this, mCurrentState);
- else if (key.equals(Constants.PREF_SYNC_ONLY_CHARGING) || key.equals(Constants.PREF_SYNC_ONLY_WIFI)
- || key.equals(Constants.PREF_SYNC_ONLY_WIFI_SSIDS) || key.equals(Constants.PREF_RESPECT_BATTERY_SAVING)) {
- updateState();
- }
- }
-
/**
* Starts the native binary.
*/
@@ -187,20 +167,8 @@ public class SyncthingService extends Service implements
((SyncthingApp) getApplication()).component().inject(this);
mDeviceStateHolder = new DeviceStateHolder(SyncthingService.this, this::updateState);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- registerReceiver(mPowerSaveModeChangedReceiver,
- new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
- }
- // Android 7 ignores network receiver that was set in manifest
- // https://github.com/syncthing/syncthing-android/issues/783
- // https://developer.android.com/about/versions/nougat/android-7.0-changes.html#bg-opt
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- registerReceiver(mNetworkReceiver,
- new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
- }
updateState();
- mPreferences.registerOnSharedPreferenceChangeListener(this);
- mNotificationHandler.updatePersistentNotification(this, mCurrentState);
+ mNotificationHandler.updatePersistentNotification(this);
}
/**
@@ -278,7 +246,6 @@ public class SyncthingService extends Service implements
*/
@Override
public void onDestroy() {
-
synchronized (mStateLock) {
if (mCurrentState == State.INIT || mCurrentState == State.STARTING) {
Log.i(TAG, "Delay shutting down service until initialisation of Syncthing finished");
@@ -290,12 +257,7 @@ public class SyncthingService extends Service implements
}
}
- mPreferences.unregisterOnSharedPreferenceChangeListener(this);
mDeviceStateHolder.shutdown();
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
- unregisterReceiver(mPowerSaveModeChangedReceiver);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
- unregisterReceiver(mNetworkReceiver);
}
/**
@@ -399,7 +361,7 @@ public class SyncthingService extends Service implements
*/
private void onApiChange(State newState) {
mCurrentState = newState;
- mNotificationHandler.updatePersistentNotification(this, mCurrentState);
+ mNotificationHandler.updatePersistentNotification(this);
for (Iterator i = mOnApiChangeListeners.iterator();
i.hasNext(); ) {
OnApiChangeListener listener = i.next();