Add setttings (#74)

This commit is contained in:
Rafał Borcz 2018-04-08 16:15:05 +02:00 committed by Mikołaj Pich
parent cb6afb137f
commit 0aa8c5605d
20 changed files with 318 additions and 57 deletions

View File

@ -72,6 +72,7 @@ dependencies {
implementation "com.android.support:design:$supportVersion"
implementation "com.android.support:cardview-v7:$supportVersion"
implementation "com.android.support:customtabs:$supportVersion"
implementation "com.android.support:preference-v14:$supportVersion"
implementation "com.firebase:firebase-jobdispatcher:$firebaseJob"
implementation "org.apache.commons:commons-lang3:$apacheLang"
implementation "org.apache.commons:commons-collections4:$apacheCollections"

View File

@ -68,6 +68,31 @@ public class Repository implements RepositoryContract {
return sharedPref.getCurrentUserId();
}
@Override
public int getStartupTab() {
return sharedPref.getStartupTab();
}
@Override
public int getServicesInterval() {
return sharedPref.getServicesInterval();
}
@Override
public boolean isServicesEnable() {
return sharedPref.isServicesEnable();
}
@Override
public boolean isNotifyEnable() {
return sharedPref.isNotifyEnable();
}
@Override
public boolean isMobileDisable() {
return sharedPref.isMobileDisable();
}
@Override
public String[] getSymbolsKeysArray() {
return resources.getSymbolsKeysArray();

View File

@ -21,6 +21,16 @@ public interface RepositoryContract extends ResourcesContract, AccountSyncContra
long getCurrentUserId();
int getStartupTab();
boolean isServicesEnable();
boolean isNotifyEnable();
int getServicesInterval();
boolean isMobileDisable();
void syncGrades() throws VulcanException, IOException, ParseException;
void syncSubjects() throws VulcanException, IOException, ParseException;

View File

@ -2,32 +2,62 @@ package io.github.wulkanowy.data.db.shared;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import javax.inject.Inject;
import javax.inject.Singleton;
import io.github.wulkanowy.di.annotations.ApplicationContext;
import io.github.wulkanowy.di.annotations.SharedPreferencesInfo;
import io.github.wulkanowy.ui.main.settings.SettingsFragment;
@Singleton
public class SharedPref implements SharedPrefContract {
private static final String SHARED_KEY_USER_ID = "USER_ID";
private final SharedPreferences sharedPreferences;
private final SharedPreferences appSharedPref;
private final SharedPreferences settingsSharedPref;
@Inject
SharedPref(@ApplicationContext Context context, @SharedPreferencesInfo String sharedName) {
sharedPreferences = context.getSharedPreferences(sharedName, Context.MODE_PRIVATE);
appSharedPref = context.getSharedPreferences(sharedName, Context.MODE_PRIVATE);
settingsSharedPref = PreferenceManager.getDefaultSharedPreferences(context);
}
@Override
public long getCurrentUserId() {
return sharedPreferences.getLong(SHARED_KEY_USER_ID, 0);
return appSharedPref.getLong(SHARED_KEY_USER_ID, 0);
}
@Override
public void setCurrentUserId(long userId) {
sharedPreferences.edit().putLong(SHARED_KEY_USER_ID, userId).apply();
appSharedPref.edit().putLong(SHARED_KEY_USER_ID, userId).apply();
}
@Override
public int getStartupTab() {
return Integer.parseInt(settingsSharedPref.getString(SettingsFragment.SHARED_KEY_START_TAB, "2"));
}
@Override
public int getServicesInterval() {
return Integer.parseInt(settingsSharedPref.getString(SettingsFragment.SHARED_KEY_SERVICES_INTERVAL, "60"));
}
@Override
public boolean isServicesEnable() {
return settingsSharedPref.getBoolean(SettingsFragment.SHARED_KEY_SERVICES_ENABLE, true);
}
@Override
public boolean isNotifyEnable() {
return settingsSharedPref.getBoolean(SettingsFragment.SHARED_KEY_NOTIFY_ENABLE, true);
}
@Override
public boolean isMobileDisable() {
return settingsSharedPref.getBoolean(SettingsFragment.SHARED_KEY_SERVICES_MOBILE_DISABLED, false);
}
}

View File

@ -5,4 +5,14 @@ public interface SharedPrefContract {
long getCurrentUserId();
void setCurrentUserId(long userId);
int getStartupTab();
int getServicesInterval();
boolean isMobileDisable();
boolean isServicesEnable();
boolean isNotifyEnable();
}

View File

@ -14,6 +14,7 @@ import com.firebase.jobdispatcher.RetryStrategy;
import com.firebase.jobdispatcher.SimpleJobService;
import com.firebase.jobdispatcher.Trigger;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
@ -27,32 +28,34 @@ import io.github.wulkanowy.utils.LogUtils;
public class SyncJob extends SimpleJobService {
private static final int DEFAULT_INTERVAL_START = 60 * 50;
private static final int DEFAULT_INTERVAL_END = DEFAULT_INTERVAL_START + (60 * 40);
public static final String EXTRA_INTENT_KEY = "cardId";
private List<Grade> gradeList;
public static final String JOB_TAG = "SyncJob";
private List<Grade> gradeList = new ArrayList<>();
@Inject
RepositoryContract repository;
public static void start(Context context) {
public static void start(Context context, int interval, boolean useOnlyWifi) {
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
dispatcher.mustSchedule(dispatcher.newJobBuilder()
.setLifetime(Lifetime.FOREVER)
.setService(SyncJob.class)
.setTag("SyncJob")
.setTag(JOB_TAG)
.setRecurring(true)
.setTrigger(Trigger.executionWindow(DEFAULT_INTERVAL_START, DEFAULT_INTERVAL_END))
.setConstraints(Constraint.ON_ANY_NETWORK)
.setTrigger(Trigger.executionWindow(interval * 60, (interval + 10) * 60))
.setConstraints(useOnlyWifi ? Constraint.ON_UNMETERED_NETWORK : Constraint.ON_ANY_NETWORK)
.setReplaceCurrent(false)
.setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
.build());
}
public static void stop(Context context) {
new FirebaseJobDispatcher(new GooglePlayDriver(context)).cancel(JOB_TAG);
}
@Override
public void onCreate() {
super.onCreate();
@ -67,7 +70,7 @@ public class SyncJob extends SimpleJobService {
gradeList = repository.getNewGrades();
if (!gradeList.isEmpty()) {
if (!gradeList.isEmpty() && repository.isNotifyEnable()) {
showNotification();
}
return JobService.RESULT_SUCCESS;

View File

@ -21,13 +21,12 @@ import io.github.wulkanowy.ui.base.BaseActivity;
import io.github.wulkanowy.ui.main.attendance.AttendanceFragment;
import io.github.wulkanowy.ui.main.dashboard.DashboardFragment;
import io.github.wulkanowy.ui.main.grades.GradesFragment;
import io.github.wulkanowy.ui.main.settings.SettingsFragment;
import io.github.wulkanowy.ui.main.timetable.TimetableFragment;
public class MainActivity extends BaseActivity implements MainContract.View,
AHBottomNavigation.OnTabSelectedListener, OnFragmentIsReadyListener {
private int initTabPosition = 0;
@BindView(R.id.main_activity_nav)
AHBottomNavigation bottomNavigation;
@ -52,15 +51,10 @@ public class MainActivity extends BaseActivity implements MainContract.View,
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initTabPosition = getIntent().getIntExtra(SyncJob.EXTRA_INTENT_KEY, initTabPosition);
getActivityComponent().inject(this);
setButterKnife(ButterKnife.bind(this));
presenter.onStart(this);
initiationViewPager();
initiationBottomNav();
presenter.onStart(this, getIntent().getIntExtra(SyncJob.EXTRA_INTENT_KEY, -1));
}
@Override
@ -102,48 +96,44 @@ public class MainActivity extends BaseActivity implements MainContract.View,
presenter.onFragmentIsReady();
}
private void initiationBottomNav() {
bottomNavigation.addItem(new AHBottomNavigationItem(
getString(R.string.grades_text),
getResources().getDrawable(R.drawable.ic_menu_grade_26dp)
));
bottomNavigation.addItem(new AHBottomNavigationItem(
getString(R.string.attendance_text),
getResources().getDrawable(R.drawable.ic_menu_attendance_24dp)
));
bottomNavigation.addItem(new AHBottomNavigationItem(
getString(R.string.dashboard_text),
getResources().getDrawable(R.drawable.ic_menu_dashboard_24dp)
));
bottomNavigation.addItem(new AHBottomNavigationItem(
getString(R.string.lessonplan_text),
getResources().getDrawable(R.drawable.ic_menu_timetable_24dp)
));
bottomNavigation.addItem(new AHBottomNavigationItem(
getString(R.string.settings_text),
getResources().getDrawable(R.drawable.ic_menu_other_24dp)
));
@Override
public void initiationBottomNav(int tabPosition) {
bottomNavigation.addItem(new AHBottomNavigationItem(getString(R.string.grades_text),
R.drawable.ic_menu_grade_26dp));
bottomNavigation.addItem(new AHBottomNavigationItem(getString(R.string.attendance_text),
R.drawable.ic_menu_attendance_24dp));
bottomNavigation.addItem(new AHBottomNavigationItem(getString(R.string.dashboard_text),
R.drawable.ic_menu_dashboard_24dp));
bottomNavigation.addItem(new AHBottomNavigationItem(getString(R.string.timetable_text),
R.drawable.ic_menu_timetable_24dp));
bottomNavigation.addItem(new AHBottomNavigationItem(getString(R.string.settings_text),
R.drawable.ic_menu_other_24dp));
bottomNavigation.setAccentColor(getResources().getColor(R.color.colorPrimary));
bottomNavigation.setInactiveColor(Color.BLACK);
bottomNavigation.setBackgroundColor(getResources().getColor(R.color.colorBackgroundBottomNav));
bottomNavigation.setTitleState(AHBottomNavigation.TitleState.ALWAYS_SHOW);
bottomNavigation.setOnTabSelectedListener(this);
bottomNavigation.setCurrentItem(initTabPosition);
bottomNavigation.setCurrentItem(tabPosition);
bottomNavigation.setBehaviorTranslationEnabled(false);
}
private void initiationViewPager() {
@Override
public void initiationViewPager(int tabPosition) {
pagerAdapter.addFragment(new GradesFragment());
pagerAdapter.addFragment(new AttendanceFragment());
pagerAdapter.addFragment(new DashboardFragment());
pagerAdapter.addFragment(new TimetableFragment());
pagerAdapter.addFragment(new DashboardFragment());
pagerAdapter.addFragment(new SettingsFragment());
viewPager.setPagingEnabled(false);
viewPager.setAdapter(pagerAdapter);
viewPager.setOffscreenPageLimit(4);
viewPager.setCurrentItem(initTabPosition, false);
viewPager.setCurrentItem(tabPosition, false);
}
@Override

View File

@ -14,11 +14,17 @@ public interface MainContract {
void showActionBar();
void hideActionBar();
void initiationViewPager(int tabPosition);
void initiationBottomNav(int tabPosition);
}
@PerActivity
interface Presenter extends BaseContract.Presenter<View> {
void onStart(View view, int tabPositionIntent);
void onTabSelected(int position, boolean wasSelected);
void onFragmentIsReady();

View File

@ -17,10 +17,21 @@ public class MainPresenter extends BasePresenter<MainContract.View>
}
@Override
public void onStart(MainContract.View view) {
public void onStart(MainContract.View view, int tabPositionIntent) {
super.onStart(view);
getView().showProgressBar(true);
getView().hideActionBar();
int tabPosition;
if (tabPositionIntent != -1) {
tabPosition = tabPositionIntent;
} else {
tabPosition = getRepository().getStartupTab();
}
getView().initiationBottomNav(tabPosition);
getView().initiationViewPager(tabPosition);
}
@Override
@ -32,11 +43,11 @@ public class MainPresenter extends BasePresenter<MainContract.View>
@Override
public void onFragmentIsReady() {
if (fragmentCount < 5) {
if (fragmentCount < 4) {
fragmentCount++;
}
if (fragmentCount == 5) {
if (fragmentCount == 4) {
getView().showActionBar();
getView().showProgressBar(false);
}

View File

@ -0,0 +1,70 @@
package io.github.wulkanowy.ui.main.settings;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.preference.PreferenceFragmentCompat;
import io.github.wulkanowy.R;
import io.github.wulkanowy.services.SyncJob;
public class SettingsFragment extends PreferenceFragmentCompat
implements SharedPreferences.OnSharedPreferenceChangeListener {
public static final String SHARED_KEY_START_TAB = "startup_tab";
public static final String SHARED_KEY_SERVICES_ENABLE = "services_enable";
public static final String SHARED_KEY_NOTIFY_ENABLE = "notify_enable";
public static final String SHARED_KEY_SERVICES_INTERVAL = "services_interval";
public static final String SHARED_KEY_SERVICES_MOBILE_DISABLED = "services_disable_mobile";
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(SHARED_KEY_SERVICES_ENABLE) || key.equals(SHARED_KEY_SERVICES_INTERVAL)
|| key.equals(SHARED_KEY_SERVICES_MOBILE_DISABLED)) {
launchServices(sharedPreferences.getBoolean(SHARED_KEY_SERVICES_ENABLE, true),
sharedPreferences);
}
}
private void launchServices(boolean start, SharedPreferences sharedPref) {
if (start) {
int newInterval = Integer.parseInt(sharedPref.getString(SHARED_KEY_SERVICES_INTERVAL, "60"));
boolean useOnlyWifi = sharedPref.getBoolean(SHARED_KEY_SERVICES_MOBILE_DISABLED, false);
SyncJob.stop(getContext());
SyncJob.start(getContext(), newInterval, useOnlyWifi);
} else {
SyncJob.stop(getContext());
}
}
@Override
public void setMenuVisibility(boolean menuVisible) {
super.setMenuVisibility(menuVisible);
if (menuVisible) {
getActivity().setTitle(R.string.settings_text);
}
}
@Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
}

View File

@ -80,7 +80,7 @@ public class TimetableFragment extends BaseFragment implements TimetableContract
@Override
public void setActivityTitle() {
setTitle(getString(R.string.lessonplan_text));
setTitle(getString(R.string.timetable_text));
}
@Override

View File

@ -44,7 +44,7 @@ public class SplashActivity extends BaseActivity implements SplashContract.View
}
@Override
public void startSyncService() {
SyncJob.start(getApplicationContext());
public void startSyncService(int interval, boolean useOnlyWifi) {
SyncJob.start(getApplicationContext(), interval, useOnlyWifi);
}
}

View File

@ -12,7 +12,7 @@ public interface SplashContract {
void openMainActivity();
void startSyncService();
void startSyncService(int interval, boolean useOnlyWifi);
}
@PerActivity

View File

@ -18,7 +18,10 @@ public class SplashPresenter extends BasePresenter<SplashContract.View>
@Override
public void onStart(@NonNull SplashContract.View activity) {
super.onStart(activity);
getView().startSyncService();
if (getRepository().isServicesEnable()) {
getView().startSyncService(getRepository().getServicesInterval(),
getRepository().isMobileDisable());
}
if (getRepository().getCurrentUserId() == 0) {
getView().openLoginActivity();

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="services_interval_entries">
<item>10 minut</item>
<item>30 minut</item>
<item>1 godzinę</item>
<item>2 godziny</item>
<item>6 godzin</item>
<item>12 godzin</item>
<item>24 godzin</item>
</string-array>
</resources>

View File

@ -33,7 +33,7 @@
<string name="dashboard_text">Dashboard</string>
<string name="grades_text">Oceny</string>
<string name="attendance_text">Frekwencja</string>
<string name="lessonplan_text">Plan lekcji</string>
<string name="timetable_text">Plan lekcji</string>
<string name="settings_text">Ustawienia</string>
<string name="activity_under_construction">Ta część aplikacji jest w budowie</string>
<string name="fragment_no_grades">Brak ocen</string>
@ -113,4 +113,13 @@
<item quantity="few">%1$d nieobecności</item>
<item quantity="many">%1$d nieobecności</item>
</plurals>
<string name="pref_view">Widok</string>
<string name="pref_tab_list">Domyślny widok</string>
<string name="pref_notify">Powiadomienia</string>
<string name="pref_notify_switch">Pokazuj powiadomienia</string>
<string name="pref_services">Usługi</string>
<string name="pref_services_switch">Włącz odświeżanie danych w tle</string>
<string name="pref_services_interval">Interwał między odświeżaniem danych</string>
<string name="pref_services_mobile_data">Synchronizacja tylko przez WiFi</string>
</resources>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="startup_tab_entries" translatable="false">
<item>@string/grades_text</item>
<item>@string/attendance_text</item>
<item>@string/dashboard_text</item>
<item>@string/timetable_text</item>
</string-array>
<string-array name="startup_tab_value" translatable="false">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
<string-array name="services_interval_entries">
<item>10 minutes</item>
<item>30 minutes</item>
<item>1 hour</item>
<item>2 hours</item>
<item>6 hours</item>
<item>12 hours</item>
<item>24 hours</item>
</string-array>
<string-array name="services_interval_value" translatable="false">
<item>10</item>
<item>30</item>
<item>60</item>
<item>120</item>
<item>360</item>
<item>720</item>
<item>1440</item>
</string-array>
</resources>

View File

@ -33,7 +33,7 @@
<string name="dashboard_text">Dashboard</string>
<string name="grades_text">Grades</string>
<string name="attendance_text">Attendance</string>
<string name="lessonplan_text">Timetable</string>
<string name="timetable_text">Timetable</string>
<string name="settings_text">Settings</string>
<string name="activity_under_construction">This section of app is under construction.</string>
<string name="fragment_no_grades">No grades</string>
@ -109,4 +109,13 @@
<item quantity="many">%1$d absences</item>
<item quantity="other">%1$d absences</item>
</plurals>
<string name="pref_tab_list">Default view after startup</string>
<string name="pref_view">View</string>
<string name="pref_notify">Notifications</string>
<string name="pref_notify_switch">Show the notifications</string>
<string name="pref_services">Services</string>
<string name="pref_services_switch">Enable background data refreshing</string>
<string name="pref_services_interval">Interval between data refreshing</string>
<string name="pref_services_mobile_data">Synchronization via WiFi only</string>
</resources>

View File

@ -13,6 +13,7 @@
<item name="titleTextColor">@android:color/primary_text_dark</item>
<item name="subtitleTextColor">@android:color/primary_text_dark</item>
<item name="android:colorBackground">@android:color/white</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
</style>
<style name="WulkanowyTheme.SplashTheme" parent="WulkanowyTheme">

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="@string/pref_view">
<ListPreference
android:defaultValue="2"
android:entries="@array/startup_tab_entries"
android:entryValues="@array/startup_tab_value"
android:key="startup_tab"
android:summary="%s"
android:title="@string/pref_tab_list" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_services">
<SwitchPreference
android:defaultValue="true"
android:key="services_enable"
android:title="@string/pref_services_switch" />
<ListPreference
android:defaultValue="60"
android:dependency="services_enable"
android:entries="@array/services_interval_entries"
android:entryValues="@array/services_interval_value"
android:key="services_interval"
android:summary="%s"
android:title="@string/pref_services_interval" />
<SwitchPreference
android:defaultValue="false"
android:key="services_disable_mobile"
android:title="@string/pref_services_mobile_data"
android:dependency="services_enable" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_notify">
<SwitchPreference
android:defaultValue="true"
android:dependency="services_enable"
android:key="notify_enable"
android:title="@string/pref_notify_switch" />
</PreferenceCategory>
</PreferenceScreen>