diff --git a/app/src/main/java/cc/pogoda/mobile/meteosystem/Main.java b/app/src/main/java/cc/pogoda/mobile/meteosystem/Main.java index 40edc5b..0fda7bf 100644 --- a/app/src/main/java/cc/pogoda/mobile/meteosystem/Main.java +++ b/app/src/main/java/cc/pogoda/mobile/meteosystem/Main.java @@ -20,11 +20,14 @@ import org.tinylog.Logger; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Locale; import cc.pogoda.mobile.meteosystem.activity.handler.MainActImageButtonFavouritesClickEvent; import cc.pogoda.mobile.meteosystem.activity.updater.FavouritesStationDetailsUpdater; +import cc.pogoda.mobile.meteosystem.activity.updater.FavouritesStationSummaryUpdater; +import cc.pogoda.mobile.meteosystem.activity.view.AllStationsActRecyclerViewHolder; import cc.pogoda.mobile.meteosystem.config.AppConfiguration; import cc.pogoda.mobile.meteosystem.dao.AllStationsDao; import cc.pogoda.mobile.meteosystem.file.ConfigurationFile; @@ -34,6 +37,7 @@ import cc.pogoda.mobile.meteosystem.type.ParceableFavsCallReason; import cc.pogoda.mobile.meteosystem.type.ParceableStationsList; import cc.pogoda.mobile.meteosystem.type.WeatherStation; import cc.pogoda.mobile.meteosystem.type.WeatherStationListEvent; +import cc.pogoda.mobile.meteosystem.type.web.Summary; public class Main extends Application { @@ -61,9 +65,16 @@ public class Main extends Application { private List favs; - private Handler handler = null; + /** + * This download summary for all stations stored on favourites list and stores results + * in 'HashMap stationSystemNameToSummary' + */ + private FavouritesStationSummaryUpdater favsSummaryUpdater = null; - private FavouritesStationDetailsUpdater favsUpdater = null; + /** + * This map stores summary for all favourites station + */ + private HashMap stationSystemNameToSummary = null; public File getDirectory() { return directory; @@ -77,6 +88,10 @@ public class Main extends Application { return confFile; } + public HashMap getStationSystemNameToSummary() { + return stationSystemNameToSummary; + } + @Override public void onCreate() { super.onCreate(); @@ -85,13 +100,7 @@ public class Main extends Application { confFile = new ConfigurationFile(ctx); - StrictMode.VmPolicy.Builder b = new StrictMode.VmPolicy.Builder(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - StrictMode.VmPolicy policy = b.detectAll().detectNonSdkApiUsage().penaltyListener((Runnable r) -> r.run(), (Violation v) -> {v.printStackTrace();}).build(); - StrictMode.setVmPolicy(policy); - } - - directory = getApplicationContext().getDir("meteosystem", Context.MODE_PRIVATE); + directory = getApplicationContext().getDir("files", Context.MODE_PRIVATE); directoryForLogs = new File(directory.getAbsolutePath() + "/logs/"); @@ -99,6 +108,15 @@ public class Main extends Application { Logger.info("Application starting..."); +// StrictMode.VmPolicy.Builder b = new StrictMode.VmPolicy.Builder(); +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { +// StrictMode.VmPolicy policy = b.detectAll().detectNonSdkApiUsage().penaltyListener((Runnable r) -> r.run(), (Violation v) -> { +// v.printStackTrace(); +// Logger.warn("[StrictMode.VmPolicy][penaltyListener][Violation][v.getLocalizedMessage() = " + v.getLocalizedMessage() + "]"); +// }).build(); +// StrictMode.setVmPolicy(policy); +// } + AndroidThreeTen.init(this); EventBus.getDefault().register(this); @@ -107,9 +125,7 @@ public class Main extends Application { confFile.restoreFromFile(); - handler = new Handler(Looper.getMainLooper()); - - favsUpdater = new FavouritesStationDetailsUpdater(handler); + stationSystemNameToSummary = new HashMap<>(); fileNames = new FileNames(ctx); @@ -123,6 +139,10 @@ public class Main extends Application { // recreate list of favorites recreateListOfFavs(); + favsSummaryUpdater = new FavouritesStationSummaryUpdater(stationSystemNameToSummary); + + favsSummaryUpdater.start(100); + if (AppConfiguration.locale != null && !AppConfiguration.locale.equals("default") ) { Logger.debug("[Main][onCreate][AppConfiguration.locale = " + AppConfiguration.locale + "]"); Locale locale = new Locale(AppConfiguration.locale); @@ -180,6 +200,7 @@ public class Main extends Application { // as a list does not make a copy of the object. It (ArrayList) keeps // only a reference to an object + stationSystemNameToSummary.put(fromAllStations.getSystemName(), null); } } @@ -223,7 +244,9 @@ public class Main extends Application { // recreate parceable object and pass it everywhere recreateListOfFavs(); - //Toast.makeText(this, intentServiceResult.getResultValue(), Toast.LENGTH_SHORT).show(); + + favsSummaryUpdater.updateImmediately(); + } public boolean listOfAllStationsReady() { @@ -236,7 +259,7 @@ public class Main extends Application { } public boolean listOfFavsReady() { - if (favs != null && favs.size() > 0) { + if (favs != null/* && favs.size() > 0*/) { return true; } else { @@ -244,25 +267,17 @@ public class Main extends Application { } } - public void createAndStartUpdater() { + public boolean checkIsOnFavsList(String _system_name) { + boolean out = false; - // check if there is previous instance of updater - if (favsUpdater != null && favsUpdater.isEnabled()) { - stopUpdater(); + for (WeatherStation wx : favs) { + if (wx.getSystemName().equals(_system_name)) { + out = true; + break; } - - handler = new Handler(Looper.getMainLooper()); - favsUpdater = new FavouritesStationDetailsUpdater(handler); - - handler.postDelayed(favsUpdater, 300); - favsUpdater.setEnabled(true); - } - - public void stopUpdater() { - if (reason.equals(ParceableFavsCallReason.Reason.FAVOURITES)) { - handler.removeCallbacks(favsUpdater); - favsUpdater.setEnabled(false); } + + return out; } } diff --git a/app/src/main/java/cc/pogoda/mobile/meteosystem/activity/updater/FavouritesStationDetailsUpdater.java b/app/src/main/java/cc/pogoda/mobile/meteosystem/activity/updater/FavouritesStationDetailsUpdater.java index a6c534a..dcd94e7 100644 --- a/app/src/main/java/cc/pogoda/mobile/meteosystem/activity/updater/FavouritesStationDetailsUpdater.java +++ b/app/src/main/java/cc/pogoda/mobile/meteosystem/activity/updater/FavouritesStationDetailsUpdater.java @@ -5,6 +5,8 @@ import android.graphics.Color; import android.os.Handler; import android.widget.TextView; +import org.tinylog.Logger; + import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -17,7 +19,8 @@ import cc.pogoda.mobile.meteosystem.type.web.QualityFactor; import cc.pogoda.mobile.meteosystem.type.web.Summary; /** - * This class is used to update entries on Favourites list + * This class is used to update entries (TextView) on Favourites list using HashMap + * which is updated by {@link FavouritesStationSummaryUpdater} */ public class FavouritesStationDetailsUpdater implements Runnable { @@ -32,27 +35,27 @@ public class FavouritesStationDetailsUpdater implements Runnable { */ private HashMap stationsToUpdate; - /** - * Used to get data from web service - */ - private SummaryDao dao = null; - /** * */ private AvailableParametersDao availableParametersDao = null; + /** + * This map comes from 'Main' class and it is shared with @link{{@link FavouritesStationSummaryUpdater}} + */ + HashMap stationNameSummary = null; + /** * Not sure if this is really required but just to be sure that updater won't be started * after the activity had been torn down. */ private boolean enabled; - public FavouritesStationDetailsUpdater(Handler _handler) { + public FavouritesStationDetailsUpdater(Handler _handler, HashMap _station_system_name_to_summary) { handler = _handler; - dao = new SummaryDao(); stationsToUpdate = new HashMap<>(); availableParametersDao = new AvailableParametersDao(); + stationNameSummary = _station_system_name_to_summary; } public boolean isEnabled() { @@ -71,7 +74,7 @@ public class FavouritesStationDetailsUpdater implements Runnable { @Override public void run() { - if (enabled && stationsToUpdate != null && stationsToUpdate.size() > 0) { + if (stationNameSummary != null && enabled && stationsToUpdate != null && stationsToUpdate.size() > 0) { // get a set of all elements stored in the map Set> entries = stationsToUpdate.entrySet(); @@ -87,7 +90,9 @@ public class FavouritesStationDetailsUpdater implements Runnable { TextView toUpdate = e.getValue(); // query web service for station data - Summary summary = dao.getStationSummary(stationSystemName); + Summary summary = stationNameSummary.get(stationSystemName); + + Logger.debug("[FavouritesStationDetailsUpdater][run][stationSystemName = " + stationSystemName +"][summary.last_timestamp = " + summary.last_timestamp +"]"); // query for available parameters AvailableParametersWeb params = availableParametersDao.getAvaliableParamsByStationName(stationSystemName); @@ -132,7 +137,7 @@ public class FavouritesStationDetailsUpdater implements Runnable { } } - handler.postDelayed(this, 30000); + handler.postDelayed(this, 60000); } } } diff --git a/app/src/main/java/cc/pogoda/mobile/meteosystem/activity/updater/FavouritesStationDetailsValuesUpdater.java b/app/src/main/java/cc/pogoda/mobile/meteosystem/activity/updater/FavouritesStationDetailsValuesUpdater.java deleted file mode 100644 index 984a71f..0000000 --- a/app/src/main/java/cc/pogoda/mobile/meteosystem/activity/updater/FavouritesStationDetailsValuesUpdater.java +++ /dev/null @@ -1,2 +0,0 @@ -package cc.pogoda.mobile.meteosystem.activity.updater;public class FavouritesStationDetailsValuesUpdater { -} diff --git a/app/src/main/java/cc/pogoda/mobile/meteosystem/activity/updater/FavouritesStationSummaryUpdater.java b/app/src/main/java/cc/pogoda/mobile/meteosystem/activity/updater/FavouritesStationSummaryUpdater.java new file mode 100644 index 0000000..68293a6 --- /dev/null +++ b/app/src/main/java/cc/pogoda/mobile/meteosystem/activity/updater/FavouritesStationSummaryUpdater.java @@ -0,0 +1,111 @@ +package cc.pogoda.mobile.meteosystem.activity.updater; + +import android.os.Handler; +import android.telephony.SubscriptionManager; + +import org.tinylog.Logger; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import cc.pogoda.mobile.meteosystem.dao.SummaryDao; +import cc.pogoda.mobile.meteosystem.type.web.Summary; + +/** + * This class is a runnable executed from background Thread by ScheduledExecuter + * which periodically download current Summary for all stations stored on favourites list + */ +public class FavouritesStationSummaryUpdater implements Runnable { + + private HashMap map; + + private SummaryDao summaryDao; + + private ScheduledExecutorService executor; + + private ScheduledFuture scheduledTask; + + private boolean enabled = false; + + /** + * Set to true when a update is forced in case of a removal or adding new entry to the map + */ + private boolean forceUpdate = false; + + public FavouritesStationSummaryUpdater(HashMap _out_map) { + map = _out_map; + summaryDao = new SummaryDao(); + + executor = Executors.newScheduledThreadPool(5); + } + + @Override + public void run() { + // check if map was set so something + if (map != null && map.size() > 0) { + + // get a set of all stations from favourites + Set> _set_of_stations_names = map.entrySet(); + + // get an iterator to the set + Iterator> it = _set_of_stations_names.iterator(); + + while (it.hasNext()) { + // get currently processed entry + Map.Entry entry = it.next(); + + // get station name + String station_name = entry.getKey(); + + Summary summary = summaryDao.getStationSummary(station_name); + + Logger.debug("[FavouritesStationSummaryUpdater][run][station_name = " + station_name +"][summary.last_timestamp = " + summary.last_timestamp +"]"); + + // put the summary back into the map + map.put(station_name, summary); + } + + + } + + if (forceUpdate) { + forceUpdate = false; + + start(66000); + } + } + + public void updateImmediately() { + forceUpdate = true; + stop(); + + Thread t = new Thread(this); + t.start(); + } + + public void start(int _initial_delay) { + + Logger.debug("[FavouritesStationSummaryUpdater][start][_initial_delay = " + _initial_delay +"]"); + + if (enabled) { + stop(); + } + + scheduledTask = executor.scheduleAtFixedRate(this, _initial_delay, 123000, TimeUnit.MILLISECONDS); + enabled = true; + } + + public void stop() { + if (enabled) { + scheduledTask.cancel(true); + enabled = false; + } + } +} diff --git a/app/src/main/java/cc/pogoda/mobile/meteosystem/adapter/WeatherStationRecyclerViewAdapter.java b/app/src/main/java/cc/pogoda/mobile/meteosystem/adapter/WeatherStationRecyclerViewAdapter.java index 90cabbd..a01bd43 100644 --- a/app/src/main/java/cc/pogoda/mobile/meteosystem/adapter/WeatherStationRecyclerViewAdapter.java +++ b/app/src/main/java/cc/pogoda/mobile/meteosystem/adapter/WeatherStationRecyclerViewAdapter.java @@ -2,6 +2,7 @@ package cc.pogoda.mobile.meteosystem.adapter; import android.content.Context; import android.os.Handler; +import android.os.Looper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -14,6 +15,7 @@ import androidx.recyclerview.widget.RecyclerView; import java.util.List; +import cc.pogoda.mobile.meteosystem.Main; import cc.pogoda.mobile.meteosystem.R; import cc.pogoda.mobile.meteosystem.activity.handler.AllStationsActRecyclerViewButtonClickEvent; import cc.pogoda.mobile.meteosystem.activity.updater.FavouritesStationDetailsUpdater; @@ -35,8 +37,18 @@ public class WeatherStationRecyclerViewAdapter extends RecyclerView.Adapter stationSystemNameToSummary + */ + Main main; public WeatherStationRecyclerViewAdapter(List stations, AppCompatActivity parentActivity, ParceableFavsCallReason.Reason callReason) { this.stations = stations; @@ -44,8 +56,7 @@ public class WeatherStationRecyclerViewAdapter extends RecyclerView.Adapter