kopia lustrzana https://github.com/SP8EBC/MeteoSystem
updating station summary for favourites separated from updating text view within activity
rodzic
660390391a
commit
0b18117b9c
|
@ -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<WeatherStation> favs;
|
||||
|
||||
private Handler handler = null;
|
||||
/**
|
||||
* This download summary for all stations stored on favourites list and stores results
|
||||
* in 'HashMap<String, Summary> stationSystemNameToSummary'
|
||||
*/
|
||||
private FavouritesStationSummaryUpdater favsSummaryUpdater = null;
|
||||
|
||||
private FavouritesStationDetailsUpdater favsUpdater = null;
|
||||
/**
|
||||
* This map stores summary for all favourites station
|
||||
*/
|
||||
private HashMap<String, Summary> stationSystemNameToSummary = null;
|
||||
|
||||
public File getDirectory() {
|
||||
return directory;
|
||||
|
@ -77,6 +88,10 @@ public class Main extends Application {
|
|||
return confFile;
|
||||
}
|
||||
|
||||
public HashMap<String, Summary> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<String, TextView> 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<String, Summary> 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<String, Summary> _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<Map.Entry<String, TextView>> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
package cc.pogoda.mobile.meteosystem.activity.updater;public class FavouritesStationDetailsValuesUpdater {
|
||||
}
|
|
@ -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<String, Summary> 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<String, Summary> _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<Map.Entry<String, Summary>> _set_of_stations_names = map.entrySet();
|
||||
|
||||
// get an iterator to the set
|
||||
Iterator<Map.Entry<String, Summary>> it = _set_of_stations_names.iterator();
|
||||
|
||||
while (it.hasNext()) {
|
||||
// get currently processed entry
|
||||
Map.Entry<String, Summary> 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<AllS
|
|||
|
||||
AvailableParametersDao paramsDao;
|
||||
|
||||
FavouritesStationDetailsUpdater favsUpdater = null;
|
||||
/**
|
||||
* This updater takes data stored in the hashmap and then updates TextViews on View Holders on
|
||||
* Favourites list
|
||||
*/
|
||||
private FavouritesStationDetailsUpdater favsUpdater = null;
|
||||
|
||||
Handler handler = null;
|
||||
|
||||
/**
|
||||
* This instance of 'Main' singleton class is used to obtain HashMap<String, Summary> stationSystemNameToSummary
|
||||
*/
|
||||
Main main;
|
||||
|
||||
public WeatherStationRecyclerViewAdapter(List<WeatherStation> stations, AppCompatActivity parentActivity, ParceableFavsCallReason.Reason callReason) {
|
||||
this.stations = stations;
|
||||
|
@ -44,8 +56,7 @@ public class WeatherStationRecyclerViewAdapter extends RecyclerView.Adapter<AllS
|
|||
this.reason = callReason;
|
||||
this.summaryDao = new SummaryDao();
|
||||
this.paramsDao = new AvailableParametersDao();
|
||||
|
||||
|
||||
this.main = (Main) parentActivity.getApplication();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -105,4 +116,26 @@ public class WeatherStationRecyclerViewAdapter extends RecyclerView.Adapter<AllS
|
|||
return stations.size();
|
||||
}
|
||||
|
||||
|
||||
public void createAndStartUpdater() {
|
||||
|
||||
// check if there is previous instance of updater
|
||||
if (favsUpdater != null && favsUpdater.isEnabled()) {
|
||||
stopUpdater();
|
||||
}
|
||||
|
||||
handler = new Handler(Looper.getMainLooper());
|
||||
favsUpdater = new FavouritesStationDetailsUpdater(handler, main.getStationSystemNameToSummary());
|
||||
|
||||
handler.postDelayed(favsUpdater, 100);
|
||||
favsUpdater.setEnabled(true);
|
||||
}
|
||||
|
||||
public void stopUpdater() {
|
||||
if (reason.equals(ParceableFavsCallReason.Reason.FAVOURITES)) {
|
||||
handler.removeCallbacks(favsUpdater);
|
||||
favsUpdater.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.tinylog.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
@ -49,6 +50,8 @@ public class ConfigurationFile {
|
|||
} catch (IOException | JSONException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
Logger.error("[ConfigurationFile][restoreFromFile][e = " + e.getLocalizedMessage() +"]");
|
||||
|
||||
AppConfiguration.locale = "default";
|
||||
AppConfiguration.replaceMsWithKnots = false;
|
||||
AppConfiguration.decimationPeriod = 0;
|
||||
|
|
Ładowanie…
Reference in New Issue