diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bcd8cfe..85a0697 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -80,6 +80,13 @@ android:name="android.content.SyncAdapter" android:resource="@xml/syncadapter_kvv" /> + + + + + diff --git a/app/src/main/java/de/sebse/fuplanner/MainActivity.java b/app/src/main/java/de/sebse/fuplanner/MainActivity.java index 13890ff..e355068 100644 --- a/app/src/main/java/de/sebse/fuplanner/MainActivity.java +++ b/app/src/main/java/de/sebse/fuplanner/MainActivity.java @@ -2,9 +2,13 @@ package de.sebse.fuplanner; import android.accounts.Account; import android.accounts.AccountManager; +import android.content.ComponentName; import android.content.ContentResolver; +import android.content.Context; import android.content.Intent; +import android.content.ServiceConnection; import android.os.Bundle; +import android.os.IBinder; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -16,6 +20,7 @@ import com.google.android.material.navigation.NavigationView; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; @@ -80,12 +85,40 @@ public class MainActivity extends AppCompatActivity private static final int DOUBLE_CLICK_TO_EXIT_MILLIS = 2000; private FragmentManager mFragmentManager; - private KVV mKVV; private NewsManager mNewsManager; private CanteenBrowser mCanteenBrowser; private final Logger log = new Logger(this); private NavigationView mNavigationView; + // KVV service + private ArrayList mCallbacks = new ArrayList<>(); + private KVV mKVV; + boolean mBound = false; + /** Defines callbacks for service binding, passed to bindService() */ + private ServiceConnection mConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName className, + IBinder service) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + KVV.LocalBinder binder = (KVV.LocalBinder) service; + mKVV = binder.getService(); + mKVV.addListener("mainactivity", MainActivity.this); + for (KVVCallback callback : mCallbacks) { + callback.get(mKVV); + } + mBound = true; + + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + mKVV.removeListener("mainactivity"); + mBound = false; + } + }; + + + private int mFragmentPage = FRAGMENT_NONE; @NotNull private String mFragmentData = ""; @@ -146,12 +179,14 @@ public class MainActivity extends AppCompatActivity changeFragment(FRAGMENT_STARTUP); int targetPage = desiredPage; String targetData = desiredData; - getKVV().account().restoreOnlineLogin(restoreResult -> { - updateNavigation(); - if (restoreResult != Login.RESTORE_STATUS_INVALID_PASSWORD) - changeFragment(targetPage, targetData); - else - changeFragment(getDefaultFragmentAfterLogout()); + getKVV(kvv -> { + kvv.account().restoreOnlineLogin(restoreResult -> { + updateNavigation(); + if (restoreResult != Login.RESTORE_STATUS_INVALID_PASSWORD) + changeFragment(targetPage, targetData); + else + changeFragment(getDefaultFragmentAfterLogout()); + }); }); } @@ -168,6 +203,21 @@ public class MainActivity extends AppCompatActivity }, log::e);*/ } + @Override + protected void onStart() { + super.onStart(); + Intent intent = new Intent(this, KVV.class); + bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + } + + @Override + protected void onStop() { + super.onStop(); + mKVV.removeListener("mainactivity"); + unbindService(mConnection); + mBound = false; + } + @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); @@ -184,24 +234,26 @@ public class MainActivity extends AppCompatActivity protected void onPause() { super.onPause(); isPaused = true; - isLoggedInBeforePause = getKVV().account().isLoggedIn(); + getKVV(kvv -> isLoggedInBeforePause = kvv.account().isLoggedIn()); } @Override protected void onResume() { super.onResume(); if (isPaused) { - getKVV().account().restoreOnlineLogin(restoreResult -> { - updateNavigation(); - if (restoreResult == Login.RESTORE_STATUS_SUCCESS && !isLoggedInBeforePause) { - changeFragment(getDefaultFragmentAfterLogin()); - registerSync(true); - } else if (restoreResult == Login.RESTORE_STATUS_INVALID_PASSWORD && isLoggedInBeforePause) { - getKVV().account().logout(false); - changeFragment(getDefaultFragmentAfterLogout()); - } + getKVV(kvv -> { + kvv.account().restoreOnlineLogin(restoreResult -> { + updateNavigation(); + if (restoreResult == Login.RESTORE_STATUS_SUCCESS && !isLoggedInBeforePause) { + changeFragment(getDefaultFragmentAfterLogin()); + registerSync(true); + } else if (restoreResult == Login.RESTORE_STATUS_INVALID_PASSWORD && isLoggedInBeforePause) { + kvv.account().logout(false); + changeFragment(getDefaultFragmentAfterLogout()); + } + }); + kvv.modules().list().reloadIfOutdated(); }); - getKVV().modules().list().reloadIfOutdated(); } isPaused = false; } @@ -217,27 +269,29 @@ public class MainActivity extends AppCompatActivity if (drawer.isDrawerOpen(GravityCompat.START) && !isDrawerFixed) { drawer.closeDrawer(GravityCompat.START); } else { - if (mFragmentPage == FRAGMENT_MODULES_DETAILS) { - ModDetailFragment fragment = (ModDetailFragment) mFragmentManager.findFragmentByTag(String.valueOf(FRAGMENT_MODULES_DETAILS)); - if (fragment != null && fragment.isVisible() && Regex.has("\\.[1-9][0-9]*", fragment.getData())) { - fragment.gotoFragmentPart(0, -1); + getKVV(kvv -> { + if (mFragmentPage == FRAGMENT_MODULES_DETAILS) { + ModDetailFragment fragment = (ModDetailFragment) mFragmentManager.findFragmentByTag(String.valueOf(FRAGMENT_MODULES_DETAILS)); + if (fragment != null && fragment.isVisible() && Regex.has("\\.[1-9][0-9]*", fragment.getData())) { + fragment.gotoFragmentPart(0, -1); + } else { + changeFragment(FRAGMENT_MODULES); + } + } else if (mFragmentPage == FRAGMENT_CANTEENS_DETAILS) { + DaySwitcherFragment fragment = (DaySwitcherFragment) mFragmentManager.findFragmentByTag(String.valueOf(FRAGMENT_CANTEENS_DETAILS)); + if (fragment != null && fragment.isVisible() && Regex.has("\\.[1-9][0-9]*", fragment.getData())) { + fragment.gotoFragmentPart(0); + } else { + changeFragment(FRAGMENT_CANTEENS); + } + } else if (kvv.account().isLoggedIn() && mFragmentPage != getDefaultFragmentAfterLogin()) { + changeFragment(getDefaultFragmentAfterLogin()); } else { - changeFragment(FRAGMENT_MODULES); + mDoubleBackToExitPressedOnce = System.currentTimeMillis(); + showToast(R.string.back_to_exit); + //getTokenForAccountCreateIfNeeded(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV); } - } else if (mFragmentPage == FRAGMENT_CANTEENS_DETAILS) { - DaySwitcherFragment fragment = (DaySwitcherFragment) mFragmentManager.findFragmentByTag(String.valueOf(FRAGMENT_CANTEENS_DETAILS)); - if (fragment != null && fragment.isVisible() && Regex.has("\\.[1-9][0-9]*", fragment.getData())) { - fragment.gotoFragmentPart(0); - } else { - changeFragment(FRAGMENT_CANTEENS); - } - } else if (getKVV().account().isLoggedIn() && mFragmentPage != getDefaultFragmentAfterLogin()) { - changeFragment(getDefaultFragmentAfterLogin()); - } else { - mDoubleBackToExitPressedOnce = System.currentTimeMillis(); - showToast(R.string.back_to_exit); - //getTokenForAccountCreateIfNeeded(AccountGeneral.ACCOUNT_TYPE, AccountGeneral.AUTHTOKEN_TYPE_KVV); - } + }); } } @@ -304,8 +358,10 @@ public class MainActivity extends AppCompatActivity startActivity(sendIntent); break; case R.id.nav_logout: - getKVV().account().logout(true); - getKVV().modules().list().delete(); + getKVV(kvv -> { + kvv.account().logout(true); + kvv.modules().list().delete(); + }); break; } @@ -357,11 +413,12 @@ public class MainActivity extends AppCompatActivity return this.mNewsManager; } - public KVV getKVV() { + public void getKVV(KVVCallback callback) { if (this.mKVV == null) { - this.mKVV = new KVV(this, this); + mCallbacks.add(callback); + } else { + callback.get(this.mKVV); } - return this.mKVV; } public CanteenBrowser getCanteenBrowser() { @@ -484,18 +541,21 @@ public class MainActivity extends AppCompatActivity moduleId = moduleId.substring(0, dotPos); switch (mFragmentPage) { case FRAGMENT_MODULES_DETAILS: - getKVV().modules().list().find(moduleId, success -> { - int size = mNavigationView.getMenu().size(); - //noinspection ConstantConditions - String title = success == null ? null : success.title; - for (int k = 0; k < size; k++) { - MenuItem menuItem = mNavigationView.getMenu().getItem(k); - if (menuItem.getTitle().equals(title)) { - menuItem.setChecked(true); - break; + String finalModuleId = moduleId; + getKVV(kvv -> { + kvv.modules().list().find(finalModuleId, success -> { + int size = mNavigationView.getMenu().size(); + //noinspection ConstantConditions + String title = success == null ? null : success.title; + for (int k = 0; k < size; k++) { + MenuItem menuItem = mNavigationView.getMenu().getItem(k); + if (menuItem.getTitle().equals(title)) { + menuItem.setChecked(true); + break; + } } - } - }, log::e); + }, log::e); + }); return; case FRAGMENT_MODULES: item = mNavigationView.getMenu().findItem(R.id.nav_modules); @@ -561,21 +621,23 @@ public class MainActivity extends AppCompatActivity int MAX_COUNT = isLoggedIn ? 3 : 2; final int[] count = {0}; if (isLoggedIn) { - getKVV().modules().list().recv(success -> { - int i = 0; - for (Iterator it = success.latestSemesterIterator(); it.hasNext(); ) { - Modules.Module module = it.next(); - MenuItem menuItem = mNavigationView.getMenu().add(Menu.NONE, Menu.NONE, 101 + i, module.title); - menuItem.setOnMenuItemClickListener(item -> { - onModulesFragmentInteraction(module.getID()); - return false; - }); - i++; - } - if (++count[0] == MAX_COUNT) done.run(); - }, error -> { - if (++count[0] == MAX_COUNT) done.run(); - log.e(error); + getKVV(kvv -> { + kvv.modules().list().recv(success -> { + int i = 0; + for (Iterator it = success.latestSemesterIterator(); it.hasNext(); ) { + Modules.Module module = it.next(); + MenuItem menuItem = mNavigationView.getMenu().add(Menu.NONE, Menu.NONE, 101 + i, module.title); + menuItem.setOnMenuItemClickListener(item -> { + onModulesFragmentInteraction(module.getID()); + return false; + }); + i++; + } + if (++count[0] == MAX_COUNT) done.run(); + }, error -> { + if (++count[0] == MAX_COUNT) done.run(); + log.e(error); + }); }); } getCanteenBrowser().getCanteens(success -> { @@ -616,16 +678,18 @@ public class MainActivity extends AppCompatActivity private void updateNavigation() { mQueue.add(() -> { - boolean isLoggedIn = getKVV().account().isLoggedIn(); - setNavigationHeader(isLoggedIn); - mNavigationView.getMenu().clear(); - if (isLoggedIn) - mNavigationView.inflateMenu(R.menu.activity_main_drawer_login); - else - mNavigationView.inflateMenu(R.menu.activity_main_drawer); - afterAnyMenuInflate(isLoggedIn, () -> { - setNavigationSelection(); - mQueue.next(); + getKVV(kvv -> { + boolean isLoggedIn = kvv.account().isLoggedIn(); + setNavigationHeader(isLoggedIn); + mNavigationView.getMenu().clear(); + if (isLoggedIn) + mNavigationView.inflateMenu(R.menu.activity_main_drawer_login); + else + mNavigationView.inflateMenu(R.menu.activity_main_drawer); + afterAnyMenuInflate(isLoggedIn, () -> { + setNavigationSelection(); + mQueue.next(); + }); }); }); } @@ -722,4 +786,8 @@ public class MainActivity extends AppCompatActivity public CustomAccountManager getAccountManager() { return mAccountManager; } + + public interface KVVCallback { + void get(KVV kvv); + } } diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/ModulesFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/ModulesFragment.java index c1e11c8..dd3bd49 100644 --- a/app/src/main/java/de/sebse/fuplanner/fragments/ModulesFragment.java +++ b/app/src/main/java/de/sebse/fuplanner/fragments/ModulesFragment.java @@ -66,15 +66,15 @@ public class ModulesFragment extends Fragment { private void refresh(boolean forceRefresh) { if (mMainActivityListener != null) { - mMainActivityListener.getKVV().modules().list().recv(success -> { - adapter.setModules(success); - //if (mMainActivityListener != null) - // mMainActivityListener.refreshNavigation(); - swipeLayout.setRefreshing(false); - }, error -> { - log.e(error.toString()); - swipeLayout.setRefreshing(false); - }, forceRefresh); + mMainActivityListener.getKVV(kvv -> { + kvv.modules().list().recv(success -> { + adapter.setModules(success); + swipeLayout.setRefreshing(false); + }, error -> { + log.e(error.toString()); + swipeLayout.setRefreshing(false); + }, forceRefresh); + }); } } diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/ScheduleFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/ScheduleFragment.java index 82cb195..83666c0 100644 --- a/app/src/main/java/de/sebse/fuplanner/fragments/ScheduleFragment.java +++ b/app/src/main/java/de/sebse/fuplanner/fragments/ScheduleFragment.java @@ -64,23 +64,25 @@ public class ScheduleFragment extends Fragment implements public void invalidate(boolean forceRefresh) { if (mListener == null) return; - mListener.getKVV().modules().list().recv(modules -> { - mModules = modules; - final int[] i = {0}; - Iterator iter = mModules.latestSemesterIterator(); - while (iter.hasNext()) { - Modules.Module module = iter.next(); - mListener.getKVV().modules().events().recv(module, success1 -> { - i[0]++; - if (i[0] >= mModules.size()) { - if (mWeekView != null) { - mWeekView.invalidate(); - mWeekView.notifyDatasetChanged(); + mListener.getKVV(kvv -> { + kvv.modules().list().recv(modules -> { + mModules = modules; + final int[] i = {0}; + Iterator iter = mModules.latestSemesterIterator(); + while (iter.hasNext()) { + Modules.Module module = iter.next(); + kvv.modules().events().recv(module, success1 -> { + i[0]++; + if (i[0] >= mModules.size()) { + if (mWeekView != null) { + mWeekView.invalidate(); + mWeekView.notifyDatasetChanged(); + } } - } - }, log::e, forceRefresh); - } - }, log::e, forceRefresh); + }, log::e, forceRefresh); + } + }, log::e, forceRefresh); + }); } @Override @@ -187,20 +189,22 @@ public class ScheduleFragment extends Fragment implements AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getContext()); if (mListener == null) return; - mListener.getKVV().modules().list().find(moduleId, module -> { - String moduleName = module.title; - alertDialogBuilder - .setTitle(event.getName()) - .setMessage( - getResources().getString(R.string.module_name, moduleName) + "\n" + - getResources().getString(R.string.location_name, event.getLocation()) + "\n" + - getResources().getString(R.string.date_scale, UtilsDate.getModifiedTime(getContext(), event.getStartTime().getTimeInMillis()), UtilsDate.getModifiedTime(getContext(), event.getEndTime().getTimeInMillis()+1)) - ) - .setCancelable(true) - .setNeutralButton(R.string.close, (dialog, id) -> dialog.cancel()); + mListener.getKVV(kvv -> { + kvv.modules().list().find(moduleId, module -> { + String moduleName = module.title; + alertDialogBuilder + .setTitle(event.getName()) + .setMessage( + getResources().getString(R.string.module_name, moduleName) + "\n" + + getResources().getString(R.string.location_name, event.getLocation()) + "\n" + + getResources().getString(R.string.date_scale, UtilsDate.getModifiedTime(getContext(), event.getStartTime().getTimeInMillis()), UtilsDate.getModifiedTime(getContext(), event.getEndTime().getTimeInMillis()+1)) + ) + .setCancelable(true) + .setNeutralButton(R.string.close, (dialog, id) -> dialog.cancel()); - AlertDialog alertDialog = alertDialogBuilder.create(); - alertDialog.show(); - }, log::e); + AlertDialog alertDialog = alertDialogBuilder.create(); + alertDialog.show(); + }, log::e); + }); } } diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAnnounceFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAnnounceFragment.java index fcbd7cf..b88cb60 100644 --- a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAnnounceFragment.java +++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAnnounceFragment.java @@ -82,27 +82,31 @@ public class ModDetailAnnounceFragment extends Fragment implements Download.OnDo } private void refresh(boolean forceRefresh) { - if (mListener == null) - return; - mListener.getKVV().modules().details().recv(mItemPos, pair -> { - adapter.setModule(pair.first); - if (pair.second) - swipeLayout.setRefreshing(false); - }, error -> { - swipeLayout.setRefreshing(false); - log.e(error); - }, forceRefresh); + if (mListener != null) { + mListener.getKVV(kvv -> { + kvv.modules().details().recv(mItemPos, pair -> { + adapter.setModule(pair.first); + if (pair.second) + swipeLayout.setRefreshing(false); + }, error -> { + swipeLayout.setRefreshing(false); + log.e(error); + }, forceRefresh); + }); + } } @Override public void request(String title, String url) { if (mListener == null) return; - mListener.getKVV().modules().list().find(mItemPos, (Modules.Module module) -> { - String folderName = "FU-"+module.title.replaceAll("[:*<>|/\"\\\\]", "-"); - folderName += "/Announcement"; - getDownload().openDownloadDialog(title, url, folderName); - }, log::e); + mListener.getKVV(kvv -> { + kvv.modules().list().find(mItemPos, (Modules.Module module) -> { + String folderName = "FU-"+module.title.replaceAll("[:*<>|/\"\\\\]", "-"); + folderName += "/Announcement"; + getDownload().openDownloadDialog(title, url, folderName); + }, log::e); + }); } @Override diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAssignmentFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAssignmentFragment.java index 19b4af6..d4ebfb4 100644 --- a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAssignmentFragment.java +++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAssignmentFragment.java @@ -82,27 +82,31 @@ public class ModDetailAssignmentFragment extends Fragment implements Download.On } private void refresh(boolean forceRefresh) { - if (mListener == null) - return; - mListener.getKVV().modules().details().recv(mItemPos, pair -> { - adapter.setModule(pair.first); - if (pair.second) - swipeLayout.setRefreshing(false); - }, error -> { - swipeLayout.setRefreshing(false); - log.e(error); - }, forceRefresh); + if (mListener != null) { + mListener.getKVV(kvv -> { + kvv.modules().details().recv(mItemPos, pair -> { + adapter.setModule(pair.first); + if (pair.second) + swipeLayout.setRefreshing(false); + }, error -> { + swipeLayout.setRefreshing(false); + log.e(error); + }, forceRefresh); + }); + } } @Override public void request(String title, String url) { if (mListener == null) return; - mListener.getKVV().modules().list().find(mItemPos, (Modules.Module module) -> { - String folderName = "FU-"+module.title.replaceAll("[:*<>|/\"\\\\]", "-"); - folderName += "/Assignment"; - getDownload().openDownloadDialog(title, url, folderName); - }, log::e); + mListener.getKVV(kvv -> { + kvv.modules().list().find(mItemPos, (Modules.Module module) -> { + String folderName = "FU-"+module.title.replaceAll("[:*<>|/\"\\\\]", "-"); + folderName += "/Announcement"; + getDownload().openDownloadDialog(title, url, folderName); + }, log::e); + }); } @Override diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailEventFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailEventFragment.java index 5d9de4a..f2abeb3 100644 --- a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailEventFragment.java +++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailEventFragment.java @@ -81,16 +81,18 @@ public class ModDetailEventFragment extends Fragment { } private void refresh(boolean forceRefresh) { - if (mListener == null) - return; - mListener.getKVV().modules().details().recv(mItemPos, pair -> { - adapter.setModule(pair.first); - if (pair.second) - swipeLayout.setRefreshing(false); - }, error -> { - swipeLayout.setRefreshing(false); - log.e(error); - }, forceRefresh); + if (mListener != null) { + mListener.getKVV(kvv -> { + kvv.modules().details().recv(mItemPos, pair -> { + adapter.setModule(pair.first); + if (pair.second) + swipeLayout.setRefreshing(false); + }, error -> { + swipeLayout.setRefreshing(false); + log.e(error); + }, forceRefresh); + }); + } } @Override diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailFragment.java index 7bc80fa..2344df7 100644 --- a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailFragment.java +++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailFragment.java @@ -72,11 +72,13 @@ public class ModDetailFragment extends Fragment implements ModDetailListener { } if (mListener != null) { mListener.onTitleTextChange(R.string.courses); - mListener.getKVV().modules().list().recv(success -> { - Modules.Module module = success.get(mItemPos); - if (mListener != null && module != null) - mListener.onTitleTextChange(module.title); - }, log::e); + mListener.getKVV(kvv -> { + kvv.modules().list().recv(success -> { + Modules.Module module = success.get(mItemPos); + if (mListener != null && module != null) + mListener.onTitleTextChange(module.title); + }, log::e); + }); } } diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailGradebookFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailGradebookFragment.java index 43db94e..4cf0830 100644 --- a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailGradebookFragment.java +++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailGradebookFragment.java @@ -81,16 +81,18 @@ public class ModDetailGradebookFragment extends Fragment { } private void refresh(boolean forceRefresh) { - if (mListener == null) - return; - mListener.getKVV().modules().details().recv(mItemPos, pair -> { - adapter.setModule(pair.first); - if (pair.second) - swipeLayout.setRefreshing(false); - }, error -> { - swipeLayout.setRefreshing(false); - log.e(error); - }, forceRefresh); + if (mListener != null) { + mListener.getKVV(kvv -> { + kvv.modules().details().recv(mItemPos, pair -> { + adapter.setModule(pair.first); + if (pair.second) + swipeLayout.setRefreshing(false); + }, error -> { + swipeLayout.setRefreshing(false); + log.e(error); + }, forceRefresh); + }); + } } @Override diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailOverviewFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailOverviewFragment.java index 8519488..23ab709 100644 --- a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailOverviewFragment.java +++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailOverviewFragment.java @@ -86,14 +86,16 @@ public class ModDetailOverviewFragment extends Fragment { private void refresh(boolean forceRefresh) { if (mListener != null) { - mListener.getKVV().modules().details().recv(mItemPos, pair -> { - adapter.setModule(pair.first); - if (pair.second) + mListener.getKVV(kvv -> { + kvv.modules().details().recv(mItemPos, pair -> { + adapter.setModule(pair.first); + if (pair.second) + swipeLayout.setRefreshing(false); + }, error -> { swipeLayout.setRefreshing(false); - }, error -> { - swipeLayout.setRefreshing(false); - log.e(error); - }, forceRefresh); + log.e(error); + }, forceRefresh); + }); } } diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailResourceFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailResourceFragment.java index f589e2e..c85d993 100644 --- a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailResourceFragment.java +++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailResourceFragment.java @@ -90,11 +90,13 @@ public class ModDetailResourceFragment extends Fragment implements Download.OnDo // Update and toggle the node. onToggle(!node.isExpand(), holder); } else if (node.getContent() instanceof Resource.File && ModDetailResourceFragment.this.mListener != null) { // if leaf is file - ModDetailResourceFragment.this.mListener.getKVV().modules().resources().recv(mItemPos, (Modules.Module module) -> { - String folderName = "FU-"+module.title.replaceAll("[:*<>|/\"\\\\]", "-"); - Resource.File file = (Resource.File) node.getContent(); - getDownload().openDownloadDialog(file, folderName); - }, log::e); + ModDetailResourceFragment.this.mListener.getKVV(kvv -> { + kvv.modules().resources().recv(mItemPos, (Modules.Module module) -> { + String folderName = "FU-"+module.title.replaceAll("[:*<>|/\"\\\\]", "-"); + Resource.File file = (Resource.File) node.getContent(); + getDownload().openDownloadDialog(file, folderName); + }, log::e); + }); } return false; } @@ -123,11 +125,13 @@ public class ModDetailResourceFragment extends Fragment implements Download.OnDo public void request(String title, String url) { if (mListener == null) return; - mListener.getKVV().modules().list().find(mItemPos, (Modules.Module module) -> { - String folderName = "FU-"+module.title.replaceAll("[:*<>|/\"\\\\]", "-"); - folderName += "/Announcement"; - getDownload().openDownloadDialog(title, url, folderName); - }, log::e); + mListener.getKVV(kvv -> { + kvv.modules().list().find(mItemPos, (Modules.Module module) -> { + String folderName = "FU-"+module.title.replaceAll("[:*<>|/\"\\\\]", "-"); + folderName += "/Announcement"; + getDownload().openDownloadDialog(title, url, folderName); + }, log::e); + }); } @Override @@ -150,16 +154,18 @@ public class ModDetailResourceFragment extends Fragment implements Download.OnDo } private void refresh(boolean forceRefresh) { - if (mListener == null) - return; - mListener.getKVV().modules().details().recv(mItemPos, pair -> { - adapter.setModule(pair.first); - if (pair.second) - swipeLayout.setRefreshing(false); - }, error -> { - swipeLayout.setRefreshing(false); - log.e(error); - }, forceRefresh); + if (mListener != null) { + mListener.getKVV(kvv -> { + kvv.modules().details().recv(mItemPos, pair -> { + adapter.setModule(pair.first); + if (pair.second) + swipeLayout.setRefreshing(false); + }, error -> { + swipeLayout.setRefreshing(false); + log.e(error); + }, forceRefresh); + }); + } } private Download getDownload() { diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/KVV.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/KVV.java index 3a0770b..a435e3a 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/KVV.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/KVV.java @@ -1,31 +1,98 @@ package de.sebse.fuplanner.services.kvv; +import android.accounts.AccountManager; +import android.app.Service; import android.content.Context; +import android.content.Intent; +import android.os.Binder; +import android.os.IBinder; + +import com.android.volley.NetworkResponse; import org.jetbrains.annotations.NotNull; +import java.lang.reflect.Array; +import java.util.ArrayList; import java.util.HashMap; -public class KVV { - private final HashMap addons = new HashMap<>(); - private final KVVListener mListener; - private final Context mContext; +import de.sebse.fuplanner.services.kvv.types.LoginTokenKVV; +import de.sebse.fuplanner.tools.CustomAccountManager; - public KVV(KVVListener listener, Context context) { - this.mListener = listener; - this.mContext = context; - } +public class KVV extends Service { + private final HashMap addons = new HashMap<>(); + private final HashMap mListeners = new HashMap<>(); + private final KVVListener mListener = new KVVListener() { + CustomAccountManager accountManager = null; + @Override + public CustomAccountManager getAccountManager() { + if (accountManager == null) + accountManager = new CustomAccountManager(AccountManager.get(KVV.this.getApplicationContext()), () -> null); + return accountManager; + } + + @Override + public void onKVVNetworkResponse(NetworkResponse error) { + for (KVVListener listener : mListeners.values()) + listener.onKVVNetworkResponse(error); + } + + @Override + public void onLogin(LoginTokenKVV token, boolean isOnlyRefresh) { + for (KVVListener listener : mListeners.values()) + listener.onLogin(token, isOnlyRefresh); + } + + @Override + public void onLogout() { + for (KVVListener listener : mListeners.values()) + listener.onLogout(); + } + + @Override + public void onModuleListChange() { + for (KVVListener listener : mListeners.values()) + listener.onModuleListChange(); + } + }; + // Binder given to clients + private final IBinder mBinder = new LocalBinder(); @NotNull public Login account() { - return (Login) addAndGet("account", () -> new Login(mListener, mContext)); + return (Login) addAndGet("account", () -> new Login(mListener, getApplicationContext())); } @NotNull public Modules modules() { - return (Modules) addAndGet("module", () -> new Modules(account(), mListener, mContext)); + return (Modules) addAndGet("module", () -> new Modules(account(), mListener, getApplicationContext())); } + public void addListener(String key, KVVListener listener) { + mListeners.put(key, listener); + } + + public void removeListener(String key) { + mListeners.remove(key); + } + + @Override + public IBinder onBind(Intent intent) { + return mBinder; + } + + + /** + * Class used for the client Binder. Because we know this service always + * runs in the same process as its clients, we don't need to deal with IPC. + */ + public class LocalBinder extends Binder { + public KVV getService() { + // Return this instance of LocalService so clients can call public methods + return KVV.this; + } + } + + 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 2abb147..29c2376 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 @@ -3,10 +3,14 @@ package de.sebse.fuplanner.services.kvv.sync; import android.accounts.Account; import android.accounts.AccountManager; import android.content.AbstractThreadedSyncAdapter; +import android.content.ComponentName; import android.content.ContentProviderClient; import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; import android.content.SyncResult; import android.os.Bundle; +import android.os.IBinder; import java.util.ArrayList; import java.util.Iterator; @@ -36,6 +40,26 @@ public class KVVSyncAdapter extends AbstractThreadedSyncAdapter { private Logger log = new Logger(this); private NewAsyncQueue mQueue = new NewAsyncQueue(); + + boolean mBound = false; + boolean mWaitForBound = false; + private ServiceConnection mConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName className, IBinder service) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + KVV.LocalBinder binder = (KVV.LocalBinder) service; + mKVV = binder.getService(); + if (mWaitForBound) mQueue.next(); + mBound = true; + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + mBound = false; + } + }; + + /** * Set up the sync adapter */ @@ -57,15 +81,13 @@ public class KVVSyncAdapter extends AbstractThreadedSyncAdapter { } private void init(Context context) { - mKVV = new KVV(new KVVListener() { - CustomAccountManager accountManager = null; - @Override - public CustomAccountManager getAccountManager() { - if (accountManager == null) - accountManager = new CustomAccountManager(AccountManager.get(context), () -> null); - return accountManager; - } - }, context); + // Bind to LocalService + Intent intent = new Intent(getContext(), KVV.class); + getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + if (!mBound) { + mWaitForBound = true; + mQueue.add(() -> {}); + } mQueue.add(() -> { mKVV.account().restoreOnlineLogin(bool -> { mQueue.next(); diff --git a/app/src/main/java/de/sebse/fuplanner/services/kvv/ui/Download.java b/app/src/main/java/de/sebse/fuplanner/services/kvv/ui/Download.java index 47b8898..27a86ca 100644 --- a/app/src/main/java/de/sebse/fuplanner/services/kvv/ui/Download.java +++ b/app/src/main/java/de/sebse/fuplanner/services/kvv/ui/Download.java @@ -104,20 +104,22 @@ public class Download { showDownloadError(); return; } - activity.getKVV().modules().resources().file(file.getTitle(), file.getUrl(), folderName, success -> { - Context context = contextInterface.get(); - if (success.equals("") || context== null) { - showDownloadError(); - } else { - if (Regex.has("^http", success)){ - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(success)); - context.startActivity(intent); + activity.getKVV(kvv -> { + kvv.modules().resources().file(file.getTitle(), file.getUrl(), folderName, success -> { + Context context = contextInterface.get(); + if (success.equals("") || context== null) { + showDownloadError(); + } else { + if (Regex.has("^http", success)){ + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(success)); + context.startActivity(intent); + } + else { + fileOpen(new File(success)); + } } - else { - fileOpen(new File(success)); - } - } - }, log::e, downloadNew); + }, log::e, downloadNew); + }); } private void showDownloadError() { diff --git a/app/src/main/java/de/sebse/fuplanner/tools/MainActivityListener.java b/app/src/main/java/de/sebse/fuplanner/tools/MainActivityListener.java index eb4b80e..f26c797 100644 --- a/app/src/main/java/de/sebse/fuplanner/tools/MainActivityListener.java +++ b/app/src/main/java/de/sebse/fuplanner/tools/MainActivityListener.java @@ -2,8 +2,10 @@ package de.sebse.fuplanner.tools; import androidx.annotation.StringRes; +import de.sebse.fuplanner.MainActivity; import de.sebse.fuplanner.services.canteen.CanteenBrowser; import de.sebse.fuplanner.services.kvv.KVV; +import de.sebse.fuplanner.services.kvv.KVVListener; import de.sebse.fuplanner.services.news.NewsManager; public interface MainActivityListener { @@ -15,7 +17,7 @@ public interface MainActivityListener { void showToast(@StringRes int msgStringRes); - KVV getKVV(); + void getKVV(MainActivity.KVVCallback kvv); CanteenBrowser getCanteenBrowser(); diff --git a/app/src/main/res/xml/service_kvv.xml b/app/src/main/res/xml/service_kvv.xml new file mode 100644 index 0000000..1dbe851 --- /dev/null +++ b/app/src/main/res/xml/service_kvv.xml @@ -0,0 +1,8 @@ + +