Preferences refactor

This commit is contained in:
serso 2016-02-29 20:50:47 +01:00
parent e87ac84323
commit fd16aad605
7 changed files with 151 additions and 110 deletions

View File

@ -9,25 +9,20 @@ import android.os.Looper;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.util.Log; import android.util.Log;
import com.squareup.otto.Bus; import com.squareup.otto.Bus;
import com.squareup.otto.GeneratedHandlerFinder; import com.squareup.otto.GeneratedHandlerFinder;
import org.solovyev.android.UiThreadExecutor;
import org.solovyev.android.checkout.Billing;
import org.solovyev.android.checkout.Checkout;
import org.solovyev.android.checkout.Inventory;
import org.solovyev.android.checkout.ProductTypes;
import org.solovyev.android.checkout.Products;
import org.solovyev.android.checkout.RobotmediaDatabase;
import org.solovyev.android.checkout.RobotmediaInventory;
import org.solovyev.android.plotter.Plot;
import org.solovyev.android.plotter.Plotter;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
import jscl.JsclMathEngine; import jscl.JsclMathEngine;
import org.solovyev.android.UiThreadExecutor;
import org.solovyev.android.checkout.*;
import org.solovyev.android.plotter.Plot;
import org.solovyev.android.plotter.Plotter;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Named;
import javax.inject.Singleton;
import java.io.File; import java.io.File;
import java.util.Collections; import java.util.Collections;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@ -35,11 +30,6 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.inject.Named;
import javax.inject.Singleton;
@Module @Module
public class AppModule { public class AppModule {
@ -52,6 +42,7 @@ public class AppModule {
public static final String DIR_FILES = "dir-files"; public static final String DIR_FILES = "dir-files";
public static final String PREFS_FLOATING = "prefs-floating"; public static final String PREFS_FLOATING = "prefs-floating";
public static final String PREFS_TABS = "prefs-tabs"; public static final String PREFS_TABS = "prefs-tabs";
public static final String PREFS_UI = "prefs-ui";
@NonNull @NonNull
private final Application application; private final Application application;
@ -98,6 +89,13 @@ public class AppModule {
return application.getSharedPreferences("tabs", Context.MODE_PRIVATE); return application.getSharedPreferences("tabs", Context.MODE_PRIVATE);
} }
@Provides
@Singleton
@Named(PREFS_UI)
SharedPreferences provideUiPreferences() {
return application.getSharedPreferences("ui", Context.MODE_PRIVATE);
}
@Provides @Provides
@Singleton @Singleton
@Named(THREAD_INIT) @Named(THREAD_INIT)

View File

@ -22,32 +22,22 @@
package org.solovyev.android.calculator; package org.solovyev.android.calculator;
import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.CardView; import android.support.v7.widget.CardView;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.text.method.LinkMovementMethod;
import android.view.*; import android.view.*;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.TextView;
import butterknife.Bind; import butterknife.Bind;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import org.solovyev.android.Activities; import org.solovyev.android.Activities;
import org.solovyev.android.Android;
import org.solovyev.android.calculator.converter.ConverterFragment; import org.solovyev.android.calculator.converter.ConverterFragment;
import org.solovyev.android.calculator.history.History; import org.solovyev.android.calculator.history.History;
import org.solovyev.android.calculator.keyboard.PartialKeyboardUi; import org.solovyev.android.calculator.keyboard.PartialKeyboardUi;
import org.solovyev.android.calculator.wizard.CalculatorWizards;
import org.solovyev.android.prefs.Preference;
import org.solovyev.android.wizard.Wizard;
import org.solovyev.android.wizard.Wizards;
import org.solovyev.common.Objects;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -57,8 +47,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
import static org.solovyev.android.calculator.Preferences.Gui.keepScreenOn; import static org.solovyev.android.calculator.Preferences.Gui.keepScreenOn;
import static org.solovyev.android.calculator.release.ReleaseNotes.hasReleaseNotes;
import static org.solovyev.android.wizard.WizardUi.*;
public class CalculatorActivity extends BaseActivity implements SharedPreferences.OnSharedPreferenceChangeListener, Toolbar.OnMenuItemClickListener { public class CalculatorActivity extends BaseActivity implements SharedPreferences.OnSharedPreferenceChangeListener, Toolbar.OnMenuItemClickListener {
@ -74,6 +62,8 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference
History history; History history;
@Inject @Inject
ActivityLauncher launcher; ActivityLauncher launcher;
@Inject
StartupHelper startupHelper;
@Nullable @Nullable
@Bind(R.id.partial_keyboard) @Bind(R.id.partial_keyboard)
View partialKeyboard; View partialKeyboard;
@ -90,75 +80,6 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference
super(R.layout.activity_main); super(R.layout.activity_main);
} }
private static void firstTimeInit(@Nonnull SharedPreferences preferences, @Nonnull Context context) {
final SharedPreferences.Editor editor = preferences.edit();
final Integer appOpenedCounter = Preferences.appOpenedCounter.getPreference(preferences);
Preferences.appOpenedCounter.putPreference(editor, appOpenedCounter == null ? 1 : appOpenedCounter + 1);
final Integer savedVersion = Preferences.appVersion.getPreference(preferences);
final int appVersion = Android.getAppVersionCode(context);
Preferences.appVersion.putPreference(editor, appVersion);
editor.apply();
if (!App.isMonkeyRunner(context)) {
boolean dialogShown = false;
final Wizards wizards = App.getWizards();
final Wizard wizard = wizards.getWizard(CalculatorWizards.FIRST_TIME_WIZARD);
if (wizard.isStarted() && !wizard.isFinished()) {
continueWizard(wizards, wizard.getName(), context);
dialogShown = true;
} else {
if (Objects.areEqual(savedVersion, Preferences.appVersion.getDefaultValue())) {
// new start
startWizard(wizards, context);
dialogShown = true;
} else {
if (savedVersion < appVersion) {
final boolean showReleaseNotes = Preferences.Gui.showReleaseNotes.getPreference(preferences);
if (showReleaseNotes && hasReleaseNotes(context, savedVersion + 1)) {
final Bundle bundle = new Bundle();
bundle.putInt(CalculatorWizards.RELEASE_NOTES_VERSION, savedVersion);
context.startActivity(createLaunchIntent(wizards, CalculatorWizards.RELEASE_NOTES, context, bundle));
dialogShown = true;
}
}
}
}
//Log.d(this.getClass().getName(), "Application was opened " + appOpenedCounter + " time!");
if (!dialogShown) {
if (appOpenedCounter != null && appOpenedCounter > 30) {
dialogShown = showSpecialWindow(preferences, Preferences.Gui.feedbackWindowShown, R.layout.feedback, R.id.feedbackText, context);
}
}
}
}
private static boolean showSpecialWindow(@Nonnull SharedPreferences preferences, @Nonnull Preference<Boolean> specialWindowShownPref, int layoutId, int textViewId, @Nonnull Context context) {
boolean result = false;
final Boolean specialWindowShown = specialWindowShownPref.getPreference(preferences);
if (specialWindowShown != null && !specialWindowShown) {
final LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
final View view = layoutInflater.inflate(layoutId, null);
final TextView feedbackTextView = (TextView) view.findViewById(textViewId);
feedbackTextView.setMovementMethod(LinkMovementMethod.getInstance());
final AlertDialog.Builder builder = new AlertDialog.Builder(context, App.getTheme().alertDialogTheme).setView(view);
builder.setPositiveButton(android.R.string.ok, null);
builder.create().show();
result = true;
specialWindowShownPref.putPreference(preferences, true);
}
return result;
}
@Override @Override
public void onCreate(@Nullable Bundle savedInstanceState) { public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -183,7 +104,7 @@ public class CalculatorActivity extends BaseActivity implements SharedPreference
useBackAsPrev = Preferences.Gui.useBackAsPrevious.getPreference(preferences); useBackAsPrev = Preferences.Gui.useBackAsPrevious.getPreference(preferences);
if (savedInstanceState == null) { if (savedInstanceState == null) {
firstTimeInit(preferences, this); startupHelper.onMainActivityOpened(this);
} }
toggleOrientationChange(); toggleOrientationChange();

View File

@ -170,7 +170,7 @@ public class CalculatorApplication extends android.app.Application implements Sh
} }
// then we should set default preferences // then we should set default preferences
Preferences.setDefaultValues(this, preferences); Preferences.init(this, preferences);
// and change application's theme/language is needed // and change application's theme/language is needed
final Preferences.Gui.Theme theme = Preferences.Gui.getTheme(preferences); final Preferences.Gui.Theme theme = Preferences.Gui.getTheme(preferences);

View File

@ -161,7 +161,7 @@ public class Engine implements SharedPreferences.OnSharedPreferenceChangeListene
} else { } else {
oldVersion = 0; oldVersion = 0;
} }
final int newVersion = Preferences.version.getPreference(preferences); final int newVersion = Preferences.version.getDefaultValue();
if (oldVersion == newVersion) { if (oldVersion == newVersion) {
return; return;
} }

View File

@ -63,19 +63,26 @@ import static org.solovyev.android.prefs.IntegerPreference.DEF_VALUE;
public final class Preferences { public final class Preferences {
public static final Preference<Integer> appVersion = IntegerPreference.of("application.version", DEF_VALUE); public static final Preference<Integer> version = IntegerPreference.of("version", 2);
public static final Preference<Integer> appOpenedCounter = IntegerPreference.of("app_opened_counter", 0);
private Preferences() { private Preferences() {
throw new AssertionError(); throw new AssertionError();
} }
static void setDefaultValues(@Nonnull Application application, @Nonnull SharedPreferences preferences) { static void init(@Nonnull Application application, @Nonnull SharedPreferences preferences) {
final int version = Preferences.appVersion.getPreference(preferences); int oldVersion;
if (version == DEF_VALUE) { if (version.isSet(preferences)) {
oldVersion = version.getPreference(preferences);
} else if (Deleted.appVersion.isSet(preferences)) {
oldVersion = 1;
} else {
oldVersion = 0;
}
if (oldVersion == 0) {
final SharedPreferences.Editor editor = preferences.edit(); final SharedPreferences.Editor editor = preferences.edit();
setInitialDefaultValues(application, preferences, editor); setInitialDefaultValues(application, preferences, editor);
editor.apply(); editor.apply();
} else if (version <= 143) { } else if (oldVersion == 1) {
final SharedPreferences.Editor editor = preferences.edit(); final SharedPreferences.Editor editor = preferences.edit();
if (!Gui.vibrateOnKeypress.isSet(preferences)) { if (!Gui.vibrateOnKeypress.isSet(preferences)) {
//noinspection deprecation //noinspection deprecation
@ -89,6 +96,9 @@ public final class Preferences {
migratePreference(preferences, editor, Gui.showReleaseNotes, Deleted.showReleaseNotes); migratePreference(preferences, editor, Gui.showReleaseNotes, Deleted.showReleaseNotes);
migratePreference(preferences, editor, Gui.showEqualsButton, Deleted.showEqualsButton); migratePreference(preferences, editor, Gui.showEqualsButton, Deleted.showEqualsButton);
migratePreference(preferences, editor, Gui.rotateScreen, Deleted.autoOrientation); migratePreference(preferences, editor, Gui.rotateScreen, Deleted.autoOrientation);
migratePreference(preferences, editor, UiPreferences.rateUsShown, Deleted.feedbackWindowShown);
migratePreference(preferences, editor, UiPreferences.opened, Deleted.appOpenedCounter);
migratePreference(preferences, editor, UiPreferences.version, Deleted.appVersion);
final Gui.Layout layout = Deleted.layout.getPreference(preferences); final Gui.Layout layout = Deleted.layout.getPreference(preferences);
if (layout == Gui.Layout.main_cellphone) { if (layout == Gui.Layout.main_cellphone) {
Gui.layout.putDefault(editor); Gui.layout.putDefault(editor);
@ -97,6 +107,7 @@ public final class Preferences {
} else if (layout == Gui.Layout.simple_mobile) { } else if (layout == Gui.Layout.simple_mobile) {
Gui.layout.putPreference(editor, Gui.Layout.simple); Gui.layout.putPreference(editor, Gui.Layout.simple);
} }
version.putDefault(editor);
editor.apply(); editor.apply();
} }
} }
@ -136,7 +147,6 @@ public final class Preferences {
Gui.theme.tryPutDefault(preferences, editor); Gui.theme.tryPutDefault(preferences, editor);
Gui.layout.tryPutDefault(preferences, editor); Gui.layout.tryPutDefault(preferences, editor);
Gui.feedbackWindowShown.tryPutDefault(preferences, editor);
Gui.showReleaseNotes.tryPutDefault(preferences, editor); Gui.showReleaseNotes.tryPutDefault(preferences, editor);
Gui.useBackAsPrevious.tryPutDefault(preferences, editor); Gui.useBackAsPrevious.tryPutDefault(preferences, editor);
Gui.showEqualsButton.tryPutDefault(preferences, editor); Gui.showEqualsButton.tryPutDefault(preferences, editor);
@ -154,6 +164,7 @@ public final class Preferences {
Onscreen.theme.tryPutDefault(preferences, editor); Onscreen.theme.tryPutDefault(preferences, editor);
Widget.theme.tryPutDefault(preferences, editor); Widget.theme.tryPutDefault(preferences, editor);
version.putDefault(editor);
final ContentResolver cr = application.getContentResolver(); final ContentResolver cr = application.getContentResolver();
if (cr != null) { if (cr != null) {
@ -275,12 +286,14 @@ public final class Preferences {
public static final Preference<AngleUnit> preferredAngleUnits = StringPreference.ofEnum("preferred_angle_units", Engine.Preferences.angleUnit.getDefaultValue(), AngleUnit.class); public static final Preference<AngleUnit> preferredAngleUnits = StringPreference.ofEnum("preferred_angle_units", Engine.Preferences.angleUnit.getDefaultValue(), AngleUnit.class);
} }
public static class App {
}
public static class Gui { public static class Gui {
public static final Preference<Theme> theme = StringPreference.ofEnum("gui.theme", Theme.material_theme, Theme.class); public static final Preference<Theme> theme = StringPreference.ofEnum("gui.theme", Theme.material_theme, Theme.class);
public static final Preference<Layout> layout = StringPreference.ofEnum("gui.layout", Layout.simple, Layout.class); public static final Preference<Layout> layout = StringPreference.ofEnum("gui.layout", Layout.simple, Layout.class);
public static final Preference<String> language = StringPreference.of("gui.language", Languages.SYSTEM_LANGUAGE_CODE); public static final Preference<String> language = StringPreference.of("gui.language", Languages.SYSTEM_LANGUAGE_CODE);
public static final Preference<Boolean> feedbackWindowShown = BooleanPreference.of("feedback_window_shown", false);
public static final Preference<Boolean> showReleaseNotes = BooleanPreference.of("gui.showReleaseNotes", true); public static final Preference<Boolean> showReleaseNotes = BooleanPreference.of("gui.showReleaseNotes", true);
public static final Preference<Boolean> useBackAsPrevious = BooleanPreference.of("gui.useBackAsPrevious", false); public static final Preference<Boolean> useBackAsPrevious = BooleanPreference.of("gui.useBackAsPrevious", false);
public static final Preference<Boolean> showEqualsButton = BooleanPreference.of("gui.showEqualsButton", true); public static final Preference<Boolean> showEqualsButton = BooleanPreference.of("gui.showEqualsButton", true);
@ -407,6 +420,8 @@ public final class Preferences {
} }
private static class Deleted { private static class Deleted {
static final Preference<Integer> appVersion = IntegerPreference.of("application.version", DEF_VALUE);
static final Preference<Boolean> feedbackWindowShown = BooleanPreference.of("feedback_window_shown", false);
static final Preference<Long> hapticFeedback = NumberToStringPreference.of("hapticFeedback", 60L, Long.class); static final Preference<Long> hapticFeedback = NumberToStringPreference.of("hapticFeedback", 60L, Long.class);
static final Preference<Boolean> colorDisplay = BooleanPreference.of("org.solovyev.android.calculator.CalculatorModel_color_display", true); static final Preference<Boolean> colorDisplay = BooleanPreference.of("org.solovyev.android.calculator.CalculatorModel_color_display", true);
static final Preference<Boolean> preventScreenFromFading = BooleanPreference.of("preventScreenFromFading", true); static final Preference<Boolean> preventScreenFromFading = BooleanPreference.of("preventScreenFromFading", true);
@ -416,5 +431,6 @@ public final class Preferences {
static final Preference<Boolean> usePrevAsBack = BooleanPreference.of("org.solovyev.android.calculator.CalculatorActivity_use_back_button_as_prev", false); static final Preference<Boolean> usePrevAsBack = BooleanPreference.of("org.solovyev.android.calculator.CalculatorActivity_use_back_button_as_prev", false);
static final Preference<Boolean> showEqualsButton = BooleanPreference.of("showEqualsButton", true); static final Preference<Boolean> showEqualsButton = BooleanPreference.of("showEqualsButton", true);
static final Preference<Boolean> autoOrientation = BooleanPreference.of("autoOrientation", true); static final Preference<Boolean> autoOrientation = BooleanPreference.of("autoOrientation", true);
static final Preference<Integer> appOpenedCounter = IntegerPreference.of("app_opened_counter", 0);
} }
} }

View File

@ -0,0 +1,91 @@
package org.solovyev.android.calculator;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import org.solovyev.android.Android;
import org.solovyev.android.calculator.wizard.CalculatorWizards;
import org.solovyev.android.wizard.Wizard;
import org.solovyev.android.wizard.Wizards;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import static org.solovyev.android.calculator.release.ReleaseNotes.hasReleaseNotes;
import static org.solovyev.android.wizard.WizardUi.*;
@Singleton
public class StartupHelper {
@Named(AppModule.PREFS_UI)
@Inject
SharedPreferences uiPreferences;
@Inject
SharedPreferences preferences;
@Inject
public StartupHelper() {
}
public void onMainActivityOpened(@NonNull AppCompatActivity activity) {
final SharedPreferences.Editor editor = uiPreferences.edit();
final Integer opened = UiPreferences.opened.getPreference(uiPreferences);
UiPreferences.opened.putPreference(editor, opened == null ? 1 : opened + 1);
if (!App.isMonkeyRunner(activity)) {
handleOnMainActivityOpened(activity, editor, opened == null ? 0 : opened);
}
editor.apply();
}
private void handleOnMainActivityOpened(@NonNull AppCompatActivity activity, @NonNull SharedPreferences.Editor editor, int opened) {
final int currentVersion = Android.getAppVersionCode(activity);
final Wizards wizards = App.getWizards();
final Wizard wizard = wizards.getWizard(CalculatorWizards.FIRST_TIME_WIZARD);
if (wizard.isStarted() && !wizard.isFinished()) {
UiPreferences.version.putPreference(editor, currentVersion);
continueWizard(wizards, wizard.getName(), activity);
return;
}
if (!UiPreferences.version.isSet(preferences)) {
// new start
startWizard(wizards, activity);
UiPreferences.version.putPreference(editor, currentVersion);
return;
}
final Integer savedVersion = UiPreferences.version.getPreference(uiPreferences);
if (savedVersion < currentVersion) {
UiPreferences.version.putPreference(editor, currentVersion);
if (Preferences.Gui.showReleaseNotes.getPreference(preferences) && hasReleaseNotes(activity, savedVersion + 1)) {
final Bundle bundle = new Bundle();
bundle.putInt(CalculatorWizards.RELEASE_NOTES_VERSION, savedVersion);
activity.startActivity(createLaunchIntent(wizards, CalculatorWizards.RELEASE_NOTES, activity, bundle));
return;
}
}
if (opened > 30 && !UiPreferences.rateUsShown.getPreference(uiPreferences)) {
final LayoutInflater layoutInflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
final View view = layoutInflater.inflate(R.layout.feedback, null);
final TextView feedbackTextView = (TextView) view.findViewById(R.id.feedbackText);
feedbackTextView.setMovementMethod(LinkMovementMethod.getInstance());
final AlertDialog.Builder builder = new AlertDialog.Builder(activity, App.getTheme().alertDialogTheme).setView(view);
builder.setPositiveButton(android.R.string.ok, null);
builder.create().show();
UiPreferences.rateUsShown.putPreference(editor, true);
}
}
}

View File

@ -0,0 +1,15 @@
package org.solovyev.android.calculator;
import android.support.annotation.NonNull;
import org.solovyev.android.prefs.BooleanPreference;
import org.solovyev.android.prefs.IntegerPreference;
import org.solovyev.android.prefs.Preference;
final class UiPreferences {
@NonNull
public static final Preference<Integer> opened = IntegerPreference.of("opened", 0);
@NonNull
public static final Preference<Integer> version = IntegerPreference.of("version", IntegerPreference.DEF_VALUE);
@NonNull
public static final Preference<Boolean> rateUsShown = BooleanPreference.of("rateUsShown", false);
}