Periodic sync, reload from memory if outdated
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package de.sebse.fuplanner;
|
||||
|
||||
import android.accounts.AccountManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.Menu;
|
||||
@@ -39,12 +40,13 @@ import de.sebse.fuplanner.fragments.moddetails.ModDetailFragment;
|
||||
import de.sebse.fuplanner.services.canteen.CanteenBrowser;
|
||||
import de.sebse.fuplanner.services.canteen.types.Canteen;
|
||||
import de.sebse.fuplanner.services.canteen.types.CanteenListener;
|
||||
import de.sebse.fuplanner.services.fulogin.AccountGeneral;
|
||||
import de.sebse.fuplanner.services.kvv.KVV;
|
||||
import de.sebse.fuplanner.services.kvv.KVVListener;
|
||||
import de.sebse.fuplanner.services.kvv.sync.KVVContentProvider;
|
||||
import de.sebse.fuplanner.services.kvv.types.LoginToken;
|
||||
import de.sebse.fuplanner.services.kvv.types.Modules;
|
||||
import de.sebse.fuplanner.services.news.NewsManager;
|
||||
import de.sebse.fuplanner.services.fulogin.AccountGeneral;
|
||||
import de.sebse.fuplanner.tools.CustomAccountManager;
|
||||
import de.sebse.fuplanner.tools.MainActivityListener;
|
||||
import de.sebse.fuplanner.tools.NewAsyncQueue;
|
||||
@@ -136,6 +138,12 @@ public class MainActivity extends AppCompatActivity
|
||||
changeFragment(getDefaultFragmentAfterLogout());
|
||||
});
|
||||
}
|
||||
ContentResolver.addPeriodicSync(
|
||||
mAccountManager.getAccountByType(AccountGeneral.ACCOUNT_TYPE),
|
||||
KVVContentProvider.PROVIDER_NAME,
|
||||
Bundle.EMPTY,
|
||||
AccountGeneral.SYNC_INTERVAL);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -158,6 +166,7 @@ public class MainActivity extends AppCompatActivity
|
||||
changeFragment(getDefaultFragmentAfterLogout());
|
||||
}
|
||||
});
|
||||
getKVV().modules().list().reloadIfOutdated();
|
||||
}
|
||||
isPaused = false;
|
||||
}
|
||||
|
||||
@@ -4,4 +4,5 @@ public class AccountGeneral {
|
||||
public static final String ACCOUNT_TYPE = "de.sebse.fuplanner.fuauth";
|
||||
public static final String AUTHTOKEN_TYPE_KVV = "KVV";
|
||||
public static final String AUTHTOKEN_TYPE_BLACKBOARD = "Blackboard";
|
||||
public static final long SYNC_INTERVAL = 6 * 60 * 60; // defined in seconds
|
||||
}
|
||||
|
||||
@@ -46,6 +46,16 @@ public class ModulesList extends HTTPService {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void reloadIfOutdated() {
|
||||
try {
|
||||
if (mModules != null && mModules.isNewerVersionInStorage(getContext())) {
|
||||
restore();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void find(String moduleID, NetworkCallback<Modules.Module> moduleNetworkCallback, NetworkErrorCallback errorCallback) {
|
||||
find(moduleID, moduleNetworkCallback, errorCallback, RETRY_COUNT);
|
||||
}
|
||||
@@ -115,10 +125,10 @@ public class ModulesList extends HTTPService {
|
||||
this.upgrade(success -> {
|
||||
if (this.mModules == null)
|
||||
this.mModules = success;
|
||||
else
|
||||
this.mModules.updateList(success);
|
||||
mListener.onModuleListChange();
|
||||
store();
|
||||
else if(this.mModules.updateList(success)) {
|
||||
mListener.onModuleListChange();
|
||||
store();
|
||||
}
|
||||
callback.onResponse(this.mModules);
|
||||
mQueue.next();
|
||||
}, error -> {
|
||||
|
||||
@@ -11,7 +11,7 @@ import androidx.annotation.Nullable;
|
||||
|
||||
public class KVVContentProvider extends ContentProvider {
|
||||
|
||||
private static final String PROVIDER_NAME = "de.sebse.fuplanner.contentprovider.kvv.modules";
|
||||
public static final String PROVIDER_NAME = "de.sebse.fuplanner.contentprovider.kvv.modules";
|
||||
private static final Uri CONTENT_URI = Uri.parse("content://" + PROVIDER_NAME + "/modules");
|
||||
private static final int MODULE = 1;
|
||||
private static final int MODULE_ID = 2;
|
||||
|
||||
@@ -2,6 +2,8 @@ package de.sebse.fuplanner.services.kvv.types;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.android.gms.common.internal.Objects;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
@@ -25,8 +27,10 @@ import androidx.annotation.Nullable;
|
||||
public class Modules implements Iterable<Modules.Module>, Serializable {
|
||||
private SortedListModule list;
|
||||
private final String mUsername;
|
||||
private transient long mLastTimestamp = 0;
|
||||
//private transient Logger log = new Logger(this);
|
||||
private static final String FILE_NAME = "ModuleListSaving";
|
||||
private static final String FILE_NAME_TIMESTAMP = "ModuleListSavingTimestamp";
|
||||
|
||||
public Modules(String username) {
|
||||
this.mUsername = username;
|
||||
@@ -75,15 +79,38 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
|
||||
Modules modules = (Modules) readObject;
|
||||
is.close();
|
||||
fis.close();
|
||||
|
||||
fis = context.openFileInput(FILE_NAME_TIMESTAMP);
|
||||
is = new ObjectInputStream(fis);
|
||||
modules.mLastTimestamp = is.readLong();
|
||||
is.close();
|
||||
fis.close();
|
||||
|
||||
return modules;
|
||||
}
|
||||
|
||||
public boolean isNewerVersionInStorage(Context context) throws IOException {
|
||||
FileInputStream fis = context.openFileInput(FILE_NAME_TIMESTAMP);
|
||||
ObjectInputStream is = new ObjectInputStream(fis);
|
||||
boolean result = this.mLastTimestamp < is.readLong();
|
||||
is.close();
|
||||
fis.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
public void save(Context context) throws IOException {
|
||||
FileOutputStream fos = context.openFileOutput(FILE_NAME, Context.MODE_PRIVATE);
|
||||
ObjectOutputStream os = new ObjectOutputStream(fos);
|
||||
os.writeObject(this);
|
||||
os.close();
|
||||
fos.close();
|
||||
|
||||
fos = context.openFileOutput(FILE_NAME_TIMESTAMP, Context.MODE_PRIVATE);
|
||||
os = new ObjectOutputStream(fos);
|
||||
this.mLastTimestamp = System.currentTimeMillis();
|
||||
os.writeLong(this.mLastTimestamp);
|
||||
os.close();
|
||||
fos.close();
|
||||
}
|
||||
|
||||
public void delete(Context context) {
|
||||
@@ -94,19 +121,36 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
|
||||
return mUsername;
|
||||
}
|
||||
|
||||
public void updateList(Modules modules) {
|
||||
public boolean updateList(Modules modules) {
|
||||
SortedListModule old = this.list;
|
||||
this.list = modules.list;
|
||||
boolean isChanged = false;
|
||||
for (Module oldModule : old) {
|
||||
Module newModule = this.list.getById(oldModule.getID());
|
||||
if (newModule != null) {
|
||||
if (!isChanged && !hashEquals(oldModule, newModule))
|
||||
isChanged = true;
|
||||
newModule.announcements = oldModule.announcements;
|
||||
newModule.assignments = oldModule.assignments;
|
||||
newModule.events = oldModule.events;
|
||||
newModule.gradebook = oldModule.gradebook;
|
||||
newModule.resources = oldModule.resources;
|
||||
} else {
|
||||
isChanged = true;
|
||||
}
|
||||
}
|
||||
if (this.list.size() != old.size())
|
||||
isChanged = true;
|
||||
return isChanged;
|
||||
}
|
||||
|
||||
private boolean hashEquals(Module o1, Module o2) {
|
||||
if (o1 == null && o2 == null)
|
||||
return true;
|
||||
else if (o1 == null || o2 == null)
|
||||
return false;
|
||||
else
|
||||
return o1.hashCode() == o2.hashCode();
|
||||
}
|
||||
|
||||
public class Module implements Serializable {
|
||||
@@ -166,5 +210,10 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
|
||||
"\ntype: "+type+
|
||||
"\nID: "+ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(semester, lvNumber, title, lecturer, type, description, ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,13 @@ public class CustomAccountManager {
|
||||
return mAccountManager.getAccountsByType(accountType).length != 0;
|
||||
}
|
||||
|
||||
public Account getAccountByType(String accountType) {
|
||||
Account[] accountsByType = mAccountManager.getAccountsByType(accountType);
|
||||
if (accountsByType.length > 0)
|
||||
return accountsByType[0];
|
||||
return null;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ActivityInterface {
|
||||
@Nullable
|
||||
|
||||
Reference in New Issue
Block a user