diff --git a/build.gradle b/build.gradle index 7cd6ad59..fc1adca6 100644 --- a/build.gradle +++ b/build.gradle @@ -33,6 +33,8 @@ dependencies { compile 'com.annimon:stream:1.1.8' compile 'com.android.volley:volley:1.0.0' compile 'com.android.support.constraint:constraint-layout:1.0.2' + compile "com.google.dagger:dagger:2.11" + annotationProcessor "com.google.dagger:dagger-compiler:2.11" androidTestCompile 'com.android.support.test:rules:1.0.1' androidTestCompile 'com.android.support:support-annotations:26.1.0' } diff --git a/src/main/java/com/nutomic/syncthingandroid/DaggerComponent.java b/src/main/java/com/nutomic/syncthingandroid/DaggerComponent.java new file mode 100644 index 00000000..28921cbe --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/DaggerComponent.java @@ -0,0 +1,29 @@ +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.service.DeviceStateHolder; +import com.nutomic.syncthingandroid.service.EventProcessor; +import com.nutomic.syncthingandroid.service.SyncthingRunnable; +import com.nutomic.syncthingandroid.service.SyncthingService; +import com.nutomic.syncthingandroid.util.Languages; + +import javax.inject.Singleton; + +import dagger.Component; + +@Singleton +@Component(modules = {SyncthingModule.class}) +public interface DaggerComponent { + + void inject(SyncthingApp app); + void inject(MainActivity activity); + void inject(FirstStartActivity activity); + void inject(FolderPickerActivity activity); + void inject(Languages languages); + void inject(SyncthingService service); + void inject(DeviceStateHolder deviceStateHolder); + void inject(EventProcessor eventProcessor); + void inject(SyncthingRunnable syncthingRunnable); +} diff --git a/src/main/java/com/nutomic/syncthingandroid/SyncthingApp.java b/src/main/java/com/nutomic/syncthingandroid/SyncthingApp.java index bcbbc5b3..d003e02f 100644 --- a/src/main/java/com/nutomic/syncthingandroid/SyncthingApp.java +++ b/src/main/java/com/nutomic/syncthingandroid/SyncthingApp.java @@ -5,11 +5,21 @@ import android.os.StrictMode; import com.nutomic.syncthingandroid.util.Languages; +import javax.inject.Inject; + public class SyncthingApp extends Application { + @Inject DaggerComponent mComponent; + @Override public void onCreate() { super.onCreate(); + + DaggerDaggerComponent.builder() + .syncthingModule(new SyncthingModule(this)) + .build() + .inject(this); + new Languages(this).setLanguage(this); // Set VM policy to avoid crash when sending folder URI to file manager. @@ -19,4 +29,8 @@ public class SyncthingApp extends Application { .build(); StrictMode.setVmPolicy(policy); } + + public DaggerComponent component() { + return mComponent; + } } diff --git a/src/main/java/com/nutomic/syncthingandroid/SyncthingModule.java b/src/main/java/com/nutomic/syncthingandroid/SyncthingModule.java new file mode 100644 index 00000000..70a9ae77 --- /dev/null +++ b/src/main/java/com/nutomic/syncthingandroid/SyncthingModule.java @@ -0,0 +1,25 @@ +package com.nutomic.syncthingandroid; + +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import javax.inject.Singleton; + +import dagger.Module; +import dagger.Provides; + +@Module +public class SyncthingModule { + + private final SyncthingApp mApp; + + public SyncthingModule(SyncthingApp app) { + mApp = app; + } + + @Provides + @Singleton + public SharedPreferences getPreferences() { + return PreferenceManager.getDefaultSharedPreferences(mApp); + } +} diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/FirstStartActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/FirstStartActivity.java index f2ce75e8..448b264b 100644 --- a/src/main/java/com/nutomic/syncthingandroid/activities/FirstStartActivity.java +++ b/src/main/java/com/nutomic/syncthingandroid/activities/FirstStartActivity.java @@ -6,7 +6,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.Bundle; -import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; @@ -15,13 +14,16 @@ import android.widget.Button; import android.widget.Toast; import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.SyncthingApp; import com.nutomic.syncthingandroid.service.SyncthingService; +import javax.inject.Inject; + public class FirstStartActivity extends Activity implements Button.OnClickListener { private static final int REQUEST_WRITE_STORAGE = 142; - private SharedPreferences mPreferences; + @Inject SharedPreferences mPreferences; /** * Handles activity behaviour depending on {@link #isFirstStart()} and {@link #haveStoragePermission()}. @@ -29,8 +31,8 @@ public class FirstStartActivity extends Activity implements Button.OnClickListen @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + ((SyncthingApp) getApplication()).component().inject(this); startService(new Intent(this, SyncthingService.class)); - mPreferences = PreferenceManager.getDefaultSharedPreferences(this); if (!isFirstStart()) { if (haveStoragePermission()) { diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/FolderPickerActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/FolderPickerActivity.java index 286ad322..444b1474 100644 --- a/src/main/java/com/nutomic/syncthingandroid/activities/FolderPickerActivity.java +++ b/src/main/java/com/nutomic/syncthingandroid/activities/FolderPickerActivity.java @@ -11,7 +11,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.IBinder; -import android.preference.PreferenceManager; import android.support.annotation.NonNull; import android.support.v4.content.ContextCompat; import android.text.TextUtils; @@ -29,6 +28,7 @@ import android.widget.Toast; import com.google.common.collect.Sets; import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.SyncthingApp; import com.nutomic.syncthingandroid.service.SyncthingService; import java.io.File; @@ -37,6 +37,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.Iterator; +import javax.inject.Inject; + /** * Activity that allows selecting a directory in the local file system. */ @@ -52,10 +54,9 @@ public class FolderPickerActivity extends SyncthingActivity public static final int DIRECTORY_REQUEST_CODE = 234; private ListView mListView; - private FileAdapter mFilesAdapter; - private RootsAdapter mRootsAdapter; + @Inject SharedPreferences mPreferences; /** * Location of null means that the list of roots is displayed. @@ -75,6 +76,7 @@ public class FolderPickerActivity extends SyncthingActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + ((SyncthingApp) getApplication()).component().inject(this); setContentView(R.layout.activity_folder_picker); mListView = findViewById(android.R.id.list); @@ -120,8 +122,7 @@ public class FolderPickerActivity extends SyncthingActivity } // Add paths that might not be accessible to Syncthing. - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); - if (sp.getBoolean("advanced_folder_picker", false)) { + if (mPreferences.getBoolean("advanced_folder_picker", false)) { Collections.addAll(roots, new File("/storage/").listFiles()); roots.add(new File("/")); } diff --git a/src/main/java/com/nutomic/syncthingandroid/activities/MainActivity.java b/src/main/java/com/nutomic/syncthingandroid/activities/MainActivity.java index 5224a877..c58d452f 100644 --- a/src/main/java/com/nutomic/syncthingandroid/activities/MainActivity.java +++ b/src/main/java/com/nutomic/syncthingandroid/activities/MainActivity.java @@ -19,7 +19,6 @@ import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.PowerManager; -import android.preference.PreferenceManager; import android.provider.Settings; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; @@ -44,6 +43,7 @@ import android.widget.Toast; import com.annimon.stream.function.Consumer; import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.SyncthingApp; import com.nutomic.syncthingandroid.fragments.DeviceListFragment; import com.nutomic.syncthingandroid.fragments.DrawerFragment; import com.nutomic.syncthingandroid.fragments.FolderListFragment; @@ -54,6 +54,8 @@ import com.nutomic.syncthingandroid.util.Util; import java.util.Date; import java.util.concurrent.TimeUnit; +import javax.inject.Inject; + import static java.lang.Math.min; /** @@ -92,6 +94,7 @@ public class MainActivity extends StateDialogActivity private ActionBarDrawerToggle mDrawerToggle; private DrawerLayout mDrawerLayout; + @Inject SharedPreferences mPreferences; /** * Handles various dialogs based on current state. @@ -121,9 +124,8 @@ public class MainActivity extends StateDialogActivity private void showBatteryOptimizationDialogIfNecessary() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return; - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); - boolean dontShowAgain = sp.getBoolean("battery_optimization_dont_show_again", false); + boolean dontShowAgain = mPreferences.getBoolean("battery_optimization_dont_show_again", false); if (dontShowAgain || mBatteryOptimizationsDialog != null || pm.isIgnoringBatteryOptimizations(getPackageName()) || mBatteryOptimizationDialogDismissed) { @@ -143,12 +145,12 @@ public class MainActivity extends StateDialogActivity // crash reports). Log.w(TAG, "Request ignore battery optimizations not supported", e); Toast.makeText(this, R.string.dialog_disable_battery_optimizations_not_supported, Toast.LENGTH_LONG).show(); - sp.edit().putBoolean("battery_optimization_dont_show_again", true).apply(); + mPreferences.edit().putBoolean("battery_optimization_dont_show_again", true).apply(); } }) .setNeutralButton(R.string.dialog_disable_battery_optimization_later, (d, i) -> mBatteryOptimizationDialogDismissed = true) .setNegativeButton(R.string.dialog_disable_battery_optimization_dont_show_again, (d, i) -> - sp.edit().putBoolean("battery_optimization_dont_show_again", true).apply()) + mPreferences.edit().putBoolean("battery_optimization_dont_show_again", true).apply()) .setOnCancelListener(d -> mBatteryOptimizationDialogDismissed = true) .show(); } @@ -205,6 +207,7 @@ public class MainActivity extends StateDialogActivity */ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + ((SyncthingApp) getApplication()).component().inject(this); setContentView(R.layout.activity_main); mDrawerLayout = findViewById(R.id.drawer_layout); diff --git a/src/main/java/com/nutomic/syncthingandroid/service/DeviceStateHolder.java b/src/main/java/com/nutomic/syncthingandroid/service/DeviceStateHolder.java index 45a89630..641bdd07 100644 --- a/src/main/java/com/nutomic/syncthingandroid/service/DeviceStateHolder.java +++ b/src/main/java/com/nutomic/syncthingandroid/service/DeviceStateHolder.java @@ -7,21 +7,19 @@ import android.content.IntentFilter; import android.content.SharedPreferences; 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.v4.content.LocalBroadcastManager; import android.util.Log; -import com.google.common.base.Joiner; +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.Collections; import java.util.HashSet; import java.util.Set; +import javax.inject.Inject; + /** * Holds information about the current wifi and charging state of the device. * @@ -56,10 +54,10 @@ public class DeviceStateHolder { } private final Context mContext; - private final SharedPreferences mPreferences; private final LocalBroadcastManager mBroadcastManager; private final DeviceStateChangedReceiver mReceiver = new DeviceStateChangedReceiver(); private final OnDeviceStateChangedListener mListener; + @Inject SharedPreferences mPreferences; private boolean mIsAllowedNetworkConnection = false; private String mWifiSsid; @@ -67,8 +65,8 @@ public class DeviceStateHolder { private boolean mIsPowerSaving = true; public DeviceStateHolder(Context context, OnDeviceStateChangedListener listener) { + ((SyncthingApp) context.getApplicationContext()).component().inject(this); mContext = context; - mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); mBroadcastManager = LocalBroadcastManager.getInstance(mContext); mBroadcastManager.registerReceiver(mReceiver, new IntentFilter(ACTION_DEVICE_STATE_CHANGED)); mListener = listener; diff --git a/src/main/java/com/nutomic/syncthingandroid/service/EventProcessor.java b/src/main/java/com/nutomic/syncthingandroid/service/EventProcessor.java index 34b11121..480c036f 100644 --- a/src/main/java/com/nutomic/syncthingandroid/service/EventProcessor.java +++ b/src/main/java/com/nutomic/syncthingandroid/service/EventProcessor.java @@ -15,6 +15,7 @@ import android.util.Log; import com.annimon.stream.Stream; import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.SyncthingApp; import com.nutomic.syncthingandroid.activities.DeviceActivity; import com.nutomic.syncthingandroid.activities.FolderActivity; import com.nutomic.syncthingandroid.model.Device; @@ -24,6 +25,8 @@ import com.nutomic.syncthingandroid.model.Folder; import java.io.File; import java.util.concurrent.TimeUnit; +import javax.inject.Inject; + /** * Run by the syncthing service to convert syncthing events into local broadcasts. * @@ -52,8 +55,10 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene private final Context mContext; private final RestApi mApi; + @Inject SharedPreferences mPreferences; public EventProcessor(Context context, RestApi api) { + ((SyncthingApp) context.getApplicationContext()).component().inject(this); mContext = context; mApi = api; } @@ -62,8 +67,7 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene public void run() { // Restore the last event id if the event processor may have been restartet. if (mLastEventId == 0) { - mLastEventId = PreferenceManager.getDefaultSharedPreferences(mContext) - .getLong(PREF_LAST_SYNC_ID, 0); + mLastEventId = mPreferences.getLong(PREF_LAST_SYNC_ID, 0); } // First check if the event number ran backwards. @@ -163,10 +167,7 @@ public class EventProcessor implements SyncthingService.OnWebGuiAvailableListene mLastEventId = id; // Store the last EventId in case we get killed - final SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); - - //noinspection CommitPrefEdits - sp.edit().putLong(PREF_LAST_SYNC_ID, mLastEventId).apply(); + mPreferences.edit().putLong(PREF_LAST_SYNC_ID, mLastEventId).apply(); } synchronized (mMainThreadHandler) { diff --git a/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java b/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java index d77ff386..0798a30e 100644 --- a/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java +++ b/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java @@ -9,7 +9,6 @@ import android.content.SharedPreferences; import android.net.Uri; import android.os.Environment; import android.os.PowerManager; -import android.preference.PreferenceManager; import android.support.v4.app.NotificationCompat; import android.text.TextUtils; import android.util.Log; @@ -17,6 +16,7 @@ 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; import java.io.BufferedWriter; @@ -33,6 +33,8 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; +import javax.inject.Inject; + import eu.chainfire.libsuperuser.Shell; /** @@ -55,7 +57,7 @@ public class SyncthingRunnable implements Runnable { private final String mSyncthingBinary; private String[] mCommand; private final File mLogFile; - private final SharedPreferences mPreferences; + @Inject SharedPreferences mPreferences; private final boolean mUseRoot; public enum Command { @@ -70,10 +72,10 @@ public class SyncthingRunnable implements Runnable { * @param command Which type of Syncthing command to execute. */ public SyncthingRunnable(Context context, Command command) { + ((SyncthingApp) context.getApplicationContext()).component().inject(this); mContext = context; mSyncthingBinary = mContext.getApplicationInfo().nativeLibraryDir + "/" + BINARY_NAME; mLogFile = new File(mContext.getExternalFilesDir(null), "syncthing.log"); - mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); mUseRoot = mPreferences.getBoolean(SyncthingService.PREF_USE_ROOT, false) && Shell.SU.available(); switch (command) { case generate: @@ -93,7 +95,6 @@ public class SyncthingRunnable implements Runnable { @Override public void run() { trimLogFile(); - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext); int ret; // Make sure Syncthing is executable try { @@ -114,7 +115,7 @@ public class SyncthingRunnable implements Runnable { if (wakeLock != null) wakeLock.acquire(); - HashMap targetEnv = buildEnvironment(sp); + HashMap targetEnv = buildEnvironment(); process = setupAndLaunch(targetEnv); mSyncthing.set(process); @@ -373,11 +374,11 @@ public class SyncthingRunnable implements Runnable { } } - private HashMap buildEnvironment(SharedPreferences sp) { + private HashMap buildEnvironment() { HashMap targetEnv = new HashMap(); // Set home directory to data folder for web GUI folder picker. targetEnv.put("HOME", Environment.getExternalStorageDirectory().getAbsolutePath()); - targetEnv.put("STTRACE", sp.getString("sttrace", "")); + targetEnv.put("STTRACE", mPreferences.getString("sttrace", "")); File externalFilesDir = mContext.getExternalFilesDir(null); if (externalFilesDir != null) targetEnv.put("STGUIASSETS", externalFilesDir.getAbsolutePath() + "/gui"); @@ -386,13 +387,13 @@ public class SyncthingRunnable implements Runnable { // Disable hash benchmark for faster startup. // https://github.com/syncthing/syncthing/issues/4348 targetEnv.put("STHASHING", "minio"); - if (sp.getBoolean("use_tor", false)) { + if (mPreferences.getBoolean("use_tor", false)) { targetEnv.put("all_proxy", "socks5://localhost:9050"); targetEnv.put("ALL_PROXY_NO_FALLBACK", "1"); } - if (sp.getBoolean("use_legacy_hashing", false)) + if (mPreferences.getBoolean("use_legacy_hashing", false)) targetEnv.put("STHASHING", "standard"); - putCustomEnvironmentVariables(targetEnv, sp); + putCustomEnvironmentVariables(targetEnv, mPreferences); return targetEnv; } diff --git a/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java b/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java index 697e8fbe..8bd58caa 100644 --- a/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java +++ b/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java @@ -24,6 +24,7 @@ import com.android.PRNGFixes; 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; @@ -40,6 +41,8 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.concurrent.TimeUnit; +import javax.inject.Inject; + /** * Holds the native syncthing instance and provides an API to access it. */ @@ -162,6 +165,8 @@ public class SyncthingService extends Service implements private SyncthingRunnable mSyncthingRunnable; + @Inject SharedPreferences mPreferences; + /** * Handles intents, either {@link #ACTION_RESTART}, or intents having * {@link DeviceStateHolder#EXTRA_IS_ALLOWED_NETWORK_CONNECTION} or @@ -220,9 +225,8 @@ public class SyncthingService extends Service implements * {@link #PREF_NOTIFICATION_TYPE}. */ private void updateNotification() { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); - String type = sp.getString(PREF_NOTIFICATION_TYPE, "low_priority"); - boolean foreground = sp.getBoolean(PREF_FOREGROUND_SERVICE, false); + 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, @@ -276,6 +280,7 @@ public class SyncthingService extends Service implements public void onCreate() { super.onCreate(); PRNGFixes.apply(); + ((SyncthingApp) getApplication()).component().inject(this); mDeviceStateHolder = new DeviceStateHolder(SyncthingService.this, this::updateState); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { @@ -290,8 +295,7 @@ public class SyncthingService extends Service implements new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } updateState(); - PreferenceManager.getDefaultSharedPreferences(this) - .registerOnSharedPreferenceChangeListener(this); + mPreferences.registerOnSharedPreferenceChangeListener(this); } /** @@ -383,8 +387,7 @@ public class SyncthingService extends Service implements } } - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); - sp.unregisterOnSharedPreferenceChangeListener(this); + mPreferences.unregisterOnSharedPreferenceChangeListener(this); mDeviceStateHolder.shutdown(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) unregisterReceiver(mPowerSaveModeChangedReceiver); diff --git a/src/main/java/com/nutomic/syncthingandroid/util/Languages.java b/src/main/java/com/nutomic/syncthingandroid/util/Languages.java index 3f211ccf..148b9d01 100644 --- a/src/main/java/com/nutomic/syncthingandroid/util/Languages.java +++ b/src/main/java/com/nutomic/syncthingandroid/util/Languages.java @@ -13,6 +13,7 @@ import android.preference.PreferenceManager; import android.text.TextUtils; import com.nutomic.syncthingandroid.R; +import com.nutomic.syncthingandroid.SyncthingApp; import java.util.Arrays; import java.util.Collections; @@ -22,6 +23,8 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; +import javax.inject.Inject; + /** * Based on https://gitlab.com/fdroid/fdroidclient/blob/master/app/src/main/java/org/fdroid/fdroid/Languages.java */ @@ -32,7 +35,7 @@ public final class Languages { private static final Locale DEFAULT_LOCALE; public static final String PREFERENCE_LANGUAGE = "pref_current_language"; - private final SharedPreferences mPreferences; + @Inject SharedPreferences mPreferences; private static Map mAvailableLanguages; static { @@ -40,6 +43,7 @@ public final class Languages { } public Languages(Context context) { + ((SyncthingApp) context.getApplicationContext()).component().inject(this); Map tmpMap = new TreeMap<>(); List locales = Arrays.asList(LOCALES_TO_TEST); // Capitalize language names @@ -56,7 +60,6 @@ public final class Languages { /* SYSTEM_DEFAULT is a fake one for displaying in a chooser menu. */ tmpMap.put(USE_SYSTEM_DEFAULT, context.getString(R.string.pref_language_default)); mAvailableLanguages = Collections.unmodifiableMap(tmpMap); - mPreferences = PreferenceManager.getDefaultSharedPreferences(context); } /**