package de.tum.in.tumcampusapp.services; import android.app.IntentService; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.support.v4.content.LocalBroadcastManager; import org.json.JSONException; import java.io.IOException; import java.util.List; import de.tum.in.tumcampusapp.R; import de.tum.in.tumcampusapp.auxiliary.Const; import de.tum.in.tumcampusapp.auxiliary.NetUtils; import de.tum.in.tumcampusapp.auxiliary.Utils; import de.tum.in.tumcampusapp.managers.CacheManager; import de.tum.in.tumcampusapp.managers.CafeteriaManager; import de.tum.in.tumcampusapp.managers.CafeteriaMenuManager; import de.tum.in.tumcampusapp.managers.CardManager; import de.tum.in.tumcampusapp.managers.KinoManager; import de.tum.in.tumcampusapp.managers.NewsManager; import de.tum.in.tumcampusapp.managers.OpenHoursManager; import de.tum.in.tumcampusapp.managers.SurveyManager; import de.tum.in.tumcampusapp.managers.SyncManager; import de.tum.in.tumcampusapp.models.cafeteria.Location; import de.tum.in.tumcampusapp.trace.G; import de.tum.in.tumcampusapp.trace.Util; /** * Service used to download files from external pages */ public class DownloadService extends IntentService { /** * Download broadcast identifier */ public final static String BROADCAST_NAME = "de.tum.in.newtumcampus.intent.action.BROADCAST_DOWNLOAD"; private static final String DOWNLOAD_SERVICE = "DownloadService"; private static final String LAST_UPDATE = "last_update"; private static final String CSV_LOCATIONS = "locations.csv"; private LocalBroadcastManager broadcastManager; /** * default init (run intent in new thread) */ public DownloadService() { super(DOWNLOAD_SERVICE); } /** * Gets the time when BackgroundService was called last time * * @param c Context * @return time when BackgroundService was executed last time */ public static long lastUpdate(Context c) { SharedPreferences prefs = c.getSharedPreferences(Const.INTERNAL_PREFS, 0); return prefs.getLong(LAST_UPDATE, 0); } /** * Download the data for a specific intent * note, that only one concurrent download() is possible with a static synchronized method! */ private static synchronized void download(Intent intent, DownloadService service) { //Set the app version if not set PackageInfo pi = Util.getPackageInfo(service); if (pi != null) { G.appVersion = pi.versionName; // Version G.appPackage = pi.packageName; // Package name G.appVersionCode = pi.versionCode; //Version code e.g.: 45 } String action = intent.getStringExtra(Const.ACTION_EXTRA); // No action: leave service if (action == null) { return; } boolean successful = true; boolean force = intent.getBooleanExtra(Const.FORCE_DOWNLOAD, false); boolean launch = intent.getBooleanExtra(Const.APP_LAUNCHES, false); // Check if device has a internet connection boolean backgroundServicePermitted = Utils.isBackgroundServicePermitted(service); if (NetUtils.isConnected(service) && (launch || backgroundServicePermitted)) { Utils.logv("Handle action <" + action + ">"); switch (action) { case Const.NEWS: successful = service.downloadNews(force); break; case Const.FACULTIES: successful = service.downloadFacultiesAndSurveyData(); break; case Const.CAFETERIAS: successful = service.downloadCafeterias(force); break; case Const.KINO: successful = service.downLoadKino(force); break; case Const.DOWNLOAD_ALL_FROM_EXTERNAL: default: successful = service.downloadAll(force); boolean isSetup = Utils.getInternalSettingBool(service, Const.EVERYTHING_SETUP, false); if (isSetup) { break; } CacheManager cm = new CacheManager(service); cm.syncCalendar(); if (successful) { Utils.setInternalSetting(service, Const.EVERYTHING_SETUP, true); } break; } } // Update the last run time saved in shared prefs if (action.equals(Const.DOWNLOAD_ALL_FROM_EXTERNAL)) { try { service.importLocationsDefaults(); } catch (IOException e) { Utils.log(e); successful = false; } if (successful) { SharedPreferences prefs = service.getSharedPreferences(Const.INTERNAL_PREFS, 0); prefs.edit().putLong(LAST_UPDATE, System.currentTimeMillis()).apply(); } CardManager.update(service); successful = true; } // After done the job, create an broadcast intent and send it. The receivers will be informed that the download service has finished. Utils.logv("Downloadservice was " + (successful ? "" : "not ") + "successful"); if (successful) { service.broadcastDownloadCompleted(); } else { service.broadcastError(service.getResources().getString(R.string.exception_unknown)); } // Do all other import stuff that is not relevant for creating the viewing the start page if (action.equals(Const.DOWNLOAD_ALL_FROM_EXTERNAL)) { service.startService(new Intent(service, FillCacheService.class)); } } @Override public void onCreate() { super.onCreate(); Utils.log("DownloadService service has started"); broadcastManager = LocalBroadcastManager.getInstance(this); // Init sync table new SyncManager(this); } @Override public void onDestroy() { super.onDestroy(); Utils.log("DownloadService service has stopped"); } @Override protected void onHandleIntent(final Intent intent) { new Thread(new Runnable() { @Override public void run() { download(intent, DownloadService.this); } }).start(); } private void broadcastDownloadCompleted() { sendServiceBroadcast(Const.COMPLETED, null); } private void broadcastError(String message) { sendServiceBroadcast(Const.ERROR, message); } private void sendServiceBroadcast(String actionExtra, String message) { Intent intentSend = new Intent(BROADCAST_NAME) .putExtra(Const.ACTION_EXTRA, actionExtra); if (message != null) { intentSend.putExtra(Const.MESSAGE, message); } if (broadcastManager != null) { broadcastManager.sendBroadcast(intentSend); } } /** * Download all external data and check, if the download was successful * * @param force True to force download over normal sync period * @return if all downloads were successful */ private boolean downloadAll(boolean force) { final boolean cafe = downloadCafeterias(force); final boolean kino = downLoadKino(force); final boolean news = downloadNews(force); final boolean faculties = downloadFacultiesAndSurveyData(); return cafe && kino && news && faculties; } private boolean downloadCafeterias(boolean force) { try { CafeteriaManager cm = new CafeteriaManager(this); CafeteriaMenuManager cmm = new CafeteriaMenuManager(this); cm.downloadFromExternal(force); cmm.downloadFromExternal(this, force); return true; } catch (JSONException e) { Utils.log(e); return false; } } private boolean downLoadKino(boolean force) { try { KinoManager km = new KinoManager(this); km.downloadFromExternal(force); return true; } catch (JSONException e) { Utils.log(e); return false; } } private boolean downloadNews(boolean force) { try { NewsManager nm = new NewsManager(this); nm.downloadFromExternal(force); return true; } catch (JSONException e) { Utils.log(e); return false; } } private boolean downloadFacultiesAndSurveyData() { SurveyManager sm = new SurveyManager(this); sm.downloadFacultiesFromExternal(); // Downloads the facultyData from the server in local db sm.downLoadOpenQuestions(); // Downloads openQuestions relevant for the survey card sm.downLoadOwnQuestions(); // Downloads ownQuestions relevant for displaying responses in surveyActivity return true; } /** * Import default location and opening hours from assets */ private void importLocationsDefaults() throws IOException { OpenHoursManager lm = new OpenHoursManager(this); if (lm.empty()) { List<String[]> rows = Utils.readCsv(getAssets().open(CSV_LOCATIONS)); for (String[] row : rows) { lm.replaceIntoDb(new Location(Integer.parseInt(row[0]), row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8])); } } } }