From 234e7ebc1118cf44bcf0426a346b0bcbe42713ae Mon Sep 17 00:00:00 2001 From: Sebastian Seedorf Date: Thu, 24 Oct 2019 10:36:04 +0200 Subject: [PATCH 01/12] Network and Sync Stabilization --- app/app.iml | 4 +- app/build.gradle | 5 +-- .../java/de/sebse/fuplanner/MainActivity.java | 43 ++++++++++++------- .../services/canteen/CanteenBrowser.java | 3 -- .../services/canteen/types/Canteens.java | 8 +++- .../fulogin/FUAuthenticatorActivity.java | 2 +- .../sebse/fuplanner/services/kvv/Login.java | 11 +++-- .../fuplanner/services/kvv/ModulesEvents.java | 1 - .../fuplanner/services/kvv/ModulesList.java | 2 +- .../services/kvv/sync/KVVSyncAdapter.java | 1 + .../services/kvv/types/CacheBBCourse.java | 8 +++- .../services/kvv/types/CacheKVVCourse.java | 8 +++- .../services/kvv/types/CacheLecturer.java | 8 +++- .../services/kvv/types/LoginTokenBB.java | 4 ++ .../services/kvv/types/LoginTokenKVV.java | 4 ++ 15 files changed, 79 insertions(+), 33 deletions(-) diff --git a/app/app.iml b/app/app.iml index 673e0e1..7a740ab 100644 --- a/app/app.iml +++ b/app/app.iml @@ -94,12 +94,12 @@ - + - + diff --git a/app/build.gradle b/app/build.gradle index b563794..f1c5d10 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,7 @@ android { } buildTypes { release { - minifyEnabled true - shrinkResources true + minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } @@ -31,7 +30,7 @@ dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') implementation 'androidx.recyclerview:recyclerview:1.0.0' implementation 'androidx.preference:preference:1.1.0' - implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2' + implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta3' implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'com.android.volley:volley:1.1.1' implementation 'com.github.Cutta:TagView:1.3' diff --git a/app/src/main/java/de/sebse/fuplanner/MainActivity.java b/app/src/main/java/de/sebse/fuplanner/MainActivity.java index 4f39ea8..c13f910 100644 --- a/app/src/main/java/de/sebse/fuplanner/MainActivity.java +++ b/app/src/main/java/de/sebse/fuplanner/MainActivity.java @@ -189,7 +189,7 @@ public class MainActivity extends AppCompatActivity if (!mAccountManager.hasAccounts(AccountGeneral.ACCOUNT_TYPE)) { desiredPage = getDefaultFragmentAfterLogout(); desiredData = ""; - mAccountManager.getTokenByType(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_BLACKBOARD, null, null); + goToLoginScreen(); updateNavigation(); changeFragment(desiredPage, desiredData); } else { @@ -210,16 +210,10 @@ public class MainActivity extends AppCompatActivity if (!mAlreadyCreated) { Intent serviceIntent = new Intent(this, KVV.class); - bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE); + getApplicationContext().bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE); } mAlreadyCreated = true; - if (!Preferences.getBoolean(this, R.string.pref_set_auto_sync_on_startup)) { - registerSync(true); - Preferences.setBoolean(this, R.string.pref_set_auto_sync_on_startup, true); - } else { - registerSync(false); - } CustomNotificationManager.createNotificationChannel(this); /*getKVV(kvv -> { kvv.modules().list().recv(list -> { @@ -229,12 +223,17 @@ public class MainActivity extends AppCompatActivity });*/ } + private void goToLoginScreen() { + Preferences.setBoolean(this, R.string.pref_set_auto_sync_on_startup, false); + mAccountManager.getTokenByType(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_BLACKBOARD, null, null); + } + @Override protected void onStart() { super.onStart(); if (!mAlreadyCreated) { Intent serviceIntent = new Intent(this, KVV.class); - bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE); + getApplicationContext().bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE); } mAlreadyCreated = true; } @@ -245,7 +244,7 @@ public class MainActivity extends AppCompatActivity if (mKVV != null) mKVV.removeListener("mainactivity"); if (mBound) - unbindService(mConnection); + getApplicationContext().unbindService(mConnection); mKVV = null; mBound = false; mAlreadyCreated = false; @@ -279,7 +278,7 @@ public class MainActivity extends AppCompatActivity updateNavigation(); if (restoreResult == Login.RESTORE_STATUS_SUCCESS && !isLoggedInBeforePause) { changeFragment(getDefaultFragmentAfterLogin()); - registerSync(true); + registerSync(); } else if (restoreResult == Login.RESTORE_STATUS_INVALID_PASSWORD && isLoggedInBeforePause) { kvv.account().logout(false); changeFragment(getDefaultFragmentAfterLogout()); @@ -289,6 +288,13 @@ public class MainActivity extends AppCompatActivity }); } isPaused = false; + + if (!Preferences.getBoolean(this, R.string.pref_set_auto_sync_on_startup) && mAccountManager.hasAccounts(AccountGeneral.ACCOUNT_TYPE)) { + registerSync(true); + Preferences.setBoolean(this, R.string.pref_set_auto_sync_on_startup, true); + } else { + registerSync(); + } } @Override @@ -523,16 +529,23 @@ public class MainActivity extends AppCompatActivity changeFragment(newFragment); } - private void registerSync(boolean onLogin) { + private void registerSync() { + registerSync(false); + } + + private void registerSync(boolean isLogin) { Account accountByType = mAccountManager.getAccountByType(AccountGeneral.ACCOUNT_TYPE); if (accountByType != null) { - if (onLogin) + if (isLogin || (ContentResolver.getMasterSyncAutomatically() && ContentResolver.getSyncAutomatically(accountByType, KVVContentProvider.PROVIDER_NAME))) { ContentResolver.setSyncAutomatically(accountByType, KVVContentProvider.PROVIDER_NAME, true); + } ContentResolver.addPeriodicSync( accountByType, KVVContentProvider.PROVIDER_NAME, Bundle.EMPTY, - Long.parseLong(Preferences.getStringArray(this, R.array.pref_sync_frequency))*60*60); + Long.parseLong(Preferences.getStringArray(this, R.array.pref_sync_frequency)) * 60 * 60 + ); + ContentResolver.requestSync(accountByType, KVVContentProvider.PROVIDER_NAME, Bundle.EMPTY); } } @@ -686,7 +699,7 @@ public class MainActivity extends AppCompatActivity if (drawer.isDrawerOpen(GravityCompat.START) && !isDrawerFixed) { drawer.closeDrawer(GravityCompat.START); } - mAccountManager.getTokenByType(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_BLACKBOARD, null, null); + goToLoginScreen(); }); } diff --git a/app/src/main/java/de/sebse/fuplanner/services/canteen/CanteenBrowser.java b/app/src/main/java/de/sebse/fuplanner/services/canteen/CanteenBrowser.java index 7060a5c..2a5cb77 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/canteen/CanteenBrowser.java +++ b/app/src/main/java/de/sebse/fuplanner/services/canteen/CanteenBrowser.java @@ -136,9 +136,7 @@ public class CanteenBrowser extends HTTPService { // "https://openmensa.org/api/v2/canteens?near[lat]=52.449743&near[lng]=13.282245&near[dist]=50" for (double[] root : canteenRoots) { - log.d("invoke", root[0], root[1]); get(String.format("https://openmensa.org/api/v2/canteens?near[lat]=%s&near[lng]=%s&near[dist]=50", root[0], root[1]), null, response -> { - log.d("invoke response", root[0], root[1]); String body = response.getParsed(); if (body == null) { errorCallback.onError(new NetworkError(201401, 403, "No canteen list retrieved!")); @@ -152,7 +150,6 @@ public class CanteenBrowser extends HTTPService { return; } finishedCount.getAndIncrement(); - log.d("invoke increment", root[0], root[1], finishedCount.get(), this.canteenRoots.length); if (finishedCount.get() == this.canteenRoots.length) { callback.onResponse(canteens); diff --git a/app/src/main/java/de/sebse/fuplanner/services/canteen/types/Canteens.java b/app/src/main/java/de/sebse/fuplanner/services/canteen/types/Canteens.java index cded142..8fc58c6 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/canteen/types/Canteens.java +++ b/app/src/main/java/de/sebse/fuplanner/services/canteen/types/Canteens.java @@ -4,6 +4,7 @@ import android.content.Context; import androidx.annotation.NonNull; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; @@ -74,7 +75,12 @@ public class Canteens implements Serializable, Iterable { } public static Canteens load(Context context) throws IOException, ClassNotFoundException { - FileInputStream fis = context.openFileInput(FILE_NAME); + FileInputStream fis; + try { + fis = context.openFileInput(FILE_NAME); + } catch (FileNotFoundException e) { + return null; + } ObjectInputStream is = new ObjectInputStream(fis); Canteens modules = (Canteens) is.readObject(); is.close(); diff --git a/app/src/main/java/de/sebse/fuplanner/services/fulogin/FUAuthenticatorActivity.java b/app/src/main/java/de/sebse/fuplanner/services/fulogin/FUAuthenticatorActivity.java index 8cb2681..f9b4708 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/fulogin/FUAuthenticatorActivity.java +++ b/app/src/main/java/de/sebse/fuplanner/services/fulogin/FUAuthenticatorActivity.java @@ -171,7 +171,7 @@ public class FUAuthenticatorActivity extends AccountAuthenticatorActivity { final Account account = new Account(accountName, intent.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE)); final AccountManager mAccountManager = AccountManager.get(this); - if (getIntent().getBooleanExtra(ARG_IS_ADDING_NEW_ACCOUNT, false)) { + if (mIsAddingNewAccount) { String authtoken = intent.getStringExtra(AccountManager.KEY_AUTHTOKEN); String authtokenType = mAuthTokenType; diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/Login.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/Login.java index 8711582..9985b07 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/Login.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/Login.java @@ -16,12 +16,11 @@ import de.sebse.fuplanner.services.kvv.types.LoginTokenKVV; import de.sebse.fuplanner.tools.CustomAccountManager; import de.sebse.fuplanner.tools.NetworkCallbackCollector; import de.sebse.fuplanner.tools.Preferences; -import de.sebse.fuplanner.tools.network.HTTPService; import de.sebse.fuplanner.tools.network.NetworkCallback; import de.sebse.fuplanner.tools.network.NetworkError; import de.sebse.fuplanner.tools.network.NetworkErrorCallback; -public class Login extends HTTPService { +public class Login { public static final int RESTORE_STATUS_SUCCESS = 1; public static final int RESTORE_STATUS_ERROR = 2; public static final int RESTORE_STATUS_INVALID_PASSWORD = 3; @@ -31,6 +30,7 @@ public class Login extends HTTPService { public static final int RELOGIN = 0; private final KVVListener mListener; + private Context context; @Nullable private LoginTokenKVV mTokenKVV; @Nullable private LoginTokenBB mTokenBB; private boolean mLoginPending = false; @@ -38,8 +38,13 @@ public class Login extends HTTPService { private final NetworkCallbackCollector mRestoreCallbacks = new NetworkCallbackCollector<>(); Login(KVVListener listener, Context context) { - super(context); + super(); this.mListener = listener; + this.context = context; + } + + private Context getContext() { + return this.context; } public void restoreOnlineLogin(IntegerInterface callback) { diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesEvents.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesEvents.java index 132aa6d..8483c2e 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesEvents.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesEvents.java @@ -123,7 +123,6 @@ public class ModulesEvents extends PartModules { //String[] tests = {"462854", "465661", "462126", "463782", "437050", "433843", "471614", "464205"}; //String[] tests = {"461459", "424564", "459494", "429737", "463765", "476477", "464082", "459577", "459743", "464318", "449358", "454327", "461784", "468081", "485919"}; //vvNumber = tests[new Random().nextInt(tests.length)]; - //log.d("LAAAAAAST", vvNumber); //vvNumber = "462126"; super.get(String.format("https://www.fu-berlin.de/vv/de/lv/%s", vvNumber), null, response1 -> { String body = response1.getParsed(); diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesList.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesList.java index 7a6b267..8156944 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesList.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/ModulesList.java @@ -27,7 +27,7 @@ import de.sebse.fuplanner.tools.network.NetworkCallback; import de.sebse.fuplanner.tools.network.NetworkError; import de.sebse.fuplanner.tools.network.NetworkErrorCallback; -import static de.sebse.fuplanner.services.kvv.PartModules.RETRY_COUNT; +import static de.sebse.fuplanner.services.kvv.Part.RETRY_COUNT; public class ModulesList extends HTTPService { private final Login mLogin; diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/sync/KVVSyncAdapter.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/sync/KVVSyncAdapter.java index 2ee94cb..b0da80e 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/sync/KVVSyncAdapter.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/sync/KVVSyncAdapter.java @@ -100,6 +100,7 @@ public class KVVSyncAdapter extends AbstractThreadedSyncAdapter { SyncResult syncResult) { if (!mBound) { Intent intent = new Intent(getContext(), KVV.class); + getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE); mWaitForBound = true; mQueue.add(() -> {}); } diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheBBCourse.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheBBCourse.java index 4a3eeaf..ceadaa0 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheBBCourse.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheBBCourse.java @@ -3,6 +3,7 @@ package de.sebse.fuplanner.services.kvv.types; import android.content.Context; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; @@ -23,7 +24,12 @@ public class CacheBBCourse implements Serializable { private HashMap mBBCourseListRefresh = new HashMap<>(); public static CacheBBCourse load(Context context) throws IOException, ClassNotFoundException { - FileInputStream fis = context.openFileInput(FILE_NAME); + FileInputStream fis; + try { + fis = context.openFileInput(FILE_NAME); + } catch (FileNotFoundException e) { + return null; + } ObjectInputStream is = new ObjectInputStream(fis); Object readObject = is.readObject(); if (!(readObject instanceof CacheBBCourse)) diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheKVVCourse.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheKVVCourse.java index c8b029d..35c6d0a 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheKVVCourse.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheKVVCourse.java @@ -3,6 +3,7 @@ package de.sebse.fuplanner.services.kvv.types; import android.content.Context; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; @@ -20,7 +21,12 @@ public class CacheKVVCourse implements Serializable { private HashMap mKVVCourseListRefresh = new HashMap<>(); public static CacheKVVCourse load(Context context) throws IOException, ClassNotFoundException { - FileInputStream fis = context.openFileInput(FILE_NAME); + FileInputStream fis; + try { + fis = context.openFileInput(FILE_NAME); + } catch (FileNotFoundException e) { + return null; + } ObjectInputStream is = new ObjectInputStream(fis); Object readObject = is.readObject(); if (!(readObject instanceof CacheKVVCourse)) diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheLecturer.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheLecturer.java index c079574..09b2fb5 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheLecturer.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/CacheLecturer.java @@ -3,6 +3,7 @@ package de.sebse.fuplanner.services.kvv.types; import android.content.Context; import java.io.FileInputStream; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; @@ -23,7 +24,12 @@ public class CacheLecturer implements Serializable { private HashMap mLecturersRefresh = new HashMap<>(); public static CacheLecturer load(Context context) throws IOException, ClassNotFoundException { - FileInputStream fis = context.openFileInput(FILE_NAME); + FileInputStream fis; + try { + fis = context.openFileInput(FILE_NAME); + } catch (FileNotFoundException e) { + return null; + } ObjectInputStream is = new ObjectInputStream(fis); Object readObject = is.readObject(); if (!(readObject instanceof CacheLecturer)) diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/LoginTokenBB.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/LoginTokenBB.java index a3d8ebf..200fc05 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/LoginTokenBB.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/LoginTokenBB.java @@ -44,6 +44,10 @@ public class LoginTokenBB { }, errorCallback); } + public static boolean hasAccounts(CustomAccountManager manager) { + return manager.hasAccounts(AccountGeneral.ACCOUNT_TYPE); + } + public void delete(CustomAccountManager manager) { manager.deleteAccount(AccountGeneral.ACCOUNT_TYPE); } diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/LoginTokenKVV.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/LoginTokenKVV.java index e0acf83..190ed3b 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/types/LoginTokenKVV.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/types/LoginTokenKVV.java @@ -42,6 +42,10 @@ public class LoginTokenKVV { }, errorCallback); } + public static boolean hasAccounts(CustomAccountManager manager) { + return manager.hasAccounts(AccountGeneral.ACCOUNT_TYPE); + } + public void delete(CustomAccountManager manager) { manager.deleteAccount(AccountGeneral.ACCOUNT_TYPE); } From c641e24a43406404f094827d1b4cb0a3f6fa455c Mon Sep 17 00:00:00 2001 From: Sebastian Seedorf Date: Thu, 24 Oct 2019 10:41:14 +0200 Subject: [PATCH 02/12] Gradebook NullPointerException Fix --- .../fragments/moddetails/ModDetailGradebookAdapter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailGradebookAdapter.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailGradebookAdapter.java index 19bcb96..96167b9 100644 --- a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailGradebookAdapter.java +++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailGradebookAdapter.java @@ -127,10 +127,10 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter Date: Thu, 24 Oct 2019 10:45:22 +0200 Subject: [PATCH 03/12] Schedule Color Fix --- app/src/main/res/values/colors.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index b4416a0..a166905 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -22,7 +22,7 @@ @color/colorFUBlue @color/colorFUGray - @color/colorFUGrayDark2 + @color/colorFUGrayDark @color/colorFUWhite @color/colorFUGreen @color/colorFURedLight2 From a0fe303d4bc93aeb5e3e27879fce294a3f4a2d4c Mon Sep 17 00:00:00 2001 From: Sebastian Seedorf Date: Thu, 24 Oct 2019 11:23:51 +0200 Subject: [PATCH 04/12] Toolbar Color Fix --- app/src/main/res/layout/app_bar_main.xml | 3 ++- app/src/main/res/values-night/colors.xml | 1 + app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/styles.xml | 10 ++++++++-- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/app_bar_main.xml b/app/src/main/res/layout/app_bar_main.xml index 5e3f758..71bed9f 100644 --- a/app/src/main/res/layout/app_bar_main.xml +++ b/app/src/main/res/layout/app_bar_main.xml @@ -16,7 +16,8 @@ android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="@color/fuToolbarBackground" - app:popupTheme="@style/FUTheme.PopupOverlay" /> + app:popupTheme="@style/FUTheme.PopupOverlay" + android:theme="@style/FUTheme.Toolbar" /> @color/colorFUGrayDark2 @color/colorFUBlack @color/colorFUGreenDark + @color/colorFUWhite @color/colorFURedDark @color/colorFURedDark2 @color/colorFUBlack diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index a166905..3e426d1 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -25,6 +25,7 @@ @color/colorFUGrayDark @color/colorFUWhite @color/colorFUGreen + @color/colorFUGreenDark @color/colorFURedLight2 @color/colorFURedLight @color/colorFUGray diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d4c05f4..53f98cc 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -3,10 +3,16 @@ +