diff --git a/res/layout/activity_about.xml b/res/layout/activity_about.xml --- a/res/layout/activity_about.xml +++ b/res/layout/activity_about.xml @@ -35,12 +35,12 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/versionTextView" android:textAppearance="@style/TextAppearance.AppCompat.Medium" - android:gravity="center_vertical" + android:gravity="center_horizontal|center_vertical" android:layout_margin="10dp" android:layout_marginLeft="20dp" android:layout_marginStart="20dp" - /> + android:textColor="@color/black"/> \ No newline at end of file diff --git a/res/layout/fragment_arrivals.xml b/res/layout/fragment_arrivals.xml --- a/res/layout/fragment_arrivals.xml +++ b/res/layout/fragment_arrivals.xml @@ -86,7 +86,7 @@ android:layout_height="wrap_content" android:layout_marginStart="15dp" android:layout_marginLeft="15dp" - android:text="Source of arrivals" + android:text="" android:textAppearance="?android:attr/textAppearanceMedium" android:textSize="19sp" diff --git a/res/layout/stop_card.xml b/res/layout/stop_card.xml --- a/res/layout/stop_card.xml +++ b/res/layout/stop_card.xml @@ -38,9 +38,10 @@ android:gravity="center_vertical" android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:layout_below="@id/stop_nameText" - android:textIsSelectable="true" android:layout_marginTop="6dp" - android:layout_margin="8dp" - android:textColor="@color/orange_500" android:layout_marginLeft="10dp"/> + android:textIsSelectable="true" android:layout_marginTop="8dp" + android:textColor="@color/orange_500" android:layout_marginLeft="12dp" + android:layout_marginStart="12dp" android:layout_marginRight="8dp" android:layout_marginEnd="8dp" + android:layout_marginBottom="8dp"/> Fabio Mazza attuale rockstar developer anziano.
- Andrea Ugo attuale rockstar developer in formazione.
- Silviu Chiriac designer del logo 2021.
+ - Marco M formidabile tester e cacciatore di bug.
- Ludovico Pavesi ex rockstar developer anziano asd.
- Valerio Bozzolan attuale manutentore.
- Marco Gagino apprezzato ex collaboratore, ideatore icona e grafica.
@@ -94,18 +95,22 @@ Nessuna fermata nei dintorni Preferenze Aggiornamento del database… - Numero di fermate + Numero minimo di fermate + Il numero di fermate da ricercare non è valido + Valore errato, inserisci un numero Impostazioni + Distanza massima di ricerca (m) + Funzionalità sperimentali Impostazioni + Generali Fermate recenti Impostazioni generali Gestione del database Comincia aggiornamento manuale del database + Consenti l\'accesso alla posizione per mostrarla sulla mappa Abilitare il GPS - Raggio di ricerca - Funzionalità sperimentali arriva alle alla fermata Mostra arrivi diff --git a/res/values/colors.xml b/res/values/colors.xml --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -15,5 +15,6 @@ #DE0908 #2060DD #FFFFFF + #000000 \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -72,6 +72,7 @@ - Fabio Mazza current senior rockstar developer.
- Andrea Ugo current junior rockstar developer.
- Silviu Chiriac designer of the 2021 logo.
+ - Marco M rockstar tester and bug hunter.
- Ludovico Pavesi previous senior rockstar developer asd.
- Valerio Bozzolan maintainer and infrastructure sponsor.
- Marco Gagino contributor and icon creator.
@@ -91,6 +92,7 @@

Get involved! :)

]]> + Cannot add to favorites (storage full or corrupted database?)! View on a map Cannot find any application to show it in @@ -99,19 +101,22 @@ ListFragment - BusTO it.reyboz.bustorino.preferences db_is_updating - + Nearby stops Nearby connections App version + The number of stops to show in the recents is invalid + Invalid value, put a valid number Finding the position… No stops nearby - Number of stops + Minimum number of stops Preferences Settings Settings + General Experimental features - Search radius + Maximum distance (meters) Recent stops General settings Database management diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -2,30 +2,44 @@ + android:title="@string/general_settings"> + + diff --git a/src/it/reyboz/bustorino/ActivityPrincipal.java b/src/it/reyboz/bustorino/ActivityPrincipal.java --- a/src/it/reyboz/bustorino/ActivityPrincipal.java +++ b/src/it/reyboz/bustorino/ActivityPrincipal.java @@ -265,7 +265,7 @@ return true; } //selectDrawerItem(menuItem); - Log.d(DEBUG_TAG, "pressed item "+menuItem.toString()); + Log.d(DEBUG_TAG, "pressed item "+menuItem); return true; @@ -354,6 +354,10 @@ mDrawer.closeDrawer(GravityCompat.START); else if(shownFrag != null && shownFrag.isVisible() && shownFrag.getChildFragmentManager().getBackStackEntryCount() > 0){ //if we have been asked to show a stop from another fragment, we should go back even in the main + if(shownFrag instanceof MainScreenFragment){ + //we have to stop the arrivals reload + ((MainScreenFragment) shownFrag).cancelReloadArrivalsIfNeeded(); + } shownFrag.getChildFragmentManager().popBackStackImmediate(); if(showingMainFragmentFromOther && getSupportFragmentManager().getBackStackEntryCount() > 0){ getSupportFragmentManager().popBackStack(); @@ -406,7 +410,7 @@ private MainScreenFragment showMainFragment(){ FragmentManager fraMan = getSupportFragmentManager(); Fragment fragment = fraMan.findFragmentByTag(MainScreenFragment.FRAGMENT_TAG); - MainScreenFragment mainScreenFragment = null; + final MainScreenFragment mainScreenFragment; if (fragment==null | !(fragment instanceof MainScreenFragment)){ mainScreenFragment = createAndShowMainFragment(); } diff --git a/src/it/reyboz/bustorino/backend/FiveTAPIFetcher.java b/src/it/reyboz/bustorino/backend/FiveTAPIFetcher.java --- a/src/it/reyboz/bustorino/backend/FiveTAPIFetcher.java +++ b/src/it/reyboz/bustorino/backend/FiveTAPIFetcher.java @@ -130,7 +130,8 @@ public List parseDirectionsFromResponse(String response) throws IllegalArgumentException,JSONException{ - if(response == null || response.length()==0) throw new IllegalArgumentException("Response string is null or void"); + if(response == null || response.equals("null") || response.length()==0) + throw new IllegalArgumentException("Response string is null or void"); ArrayList routes = new ArrayList<>(10); JSONArray lines =new JSONArray(response); for(int i=0; i routesCopy = new ArrayList<>(routes); + //for + if(routes.size()<=1|| startidx >= routes.size()) //we have finished + return; + Route routeCheck = routes.get(startidx); + boolean found = false; + for(int i=startidx+1; i0){ + if(this.passaggi!=null && other.passaggi!=null && other.passaggi.size()>0){ this.passaggi.addAll(other.passaggi); } diff --git a/src/it/reyboz/bustorino/data/StopsDB.java b/src/it/reyboz/bustorino/data/StopsDB.java deleted file mode 100644 --- a/src/it/reyboz/bustorino/data/StopsDB.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - BusTO ("backend" components) - Copyright (C) 2016 Ludovico Pavesi - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - */ - -package it.reyboz.bustorino.data; - -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteException; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.readystatesoftware.sqliteasset.SQLiteAssetHelper; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - -import it.reyboz.bustorino.backend.Route; -import it.reyboz.bustorino.backend.Stop; -import it.reyboz.bustorino.backend.StopsDBInterface; - - -public class StopsDB extends SQLiteAssetHelper implements StopsDBInterface { - private static String QUERY_TABLE_stops = "stops"; - private static String QUERY_WHERE_ID = "ID = ?"; - private static String QUERY_WHERE_LAT_AND_LNG_IN_RANGE = "lat >= ? AND lat <= ? AND lon >= ? AND lon <= ?"; - private static String[] QUERY_COLUMN_name = {"name"}; - private static final String[] QUERY_COLUMN_location = {"location"}; - private static final String[] QUERY_COLUMN_route = {"route"}; - private static final String[] QUERY_COLUMN_everything = {"name", "location", "type", "lat", "lon"}; - private static final String[] QUERY_COLUMN_everything_and_ID = {"ID", "name", "location", "type", "lat", "lon"}; - - private static String DB_NAME = "stops.sqlite"; - private static int DB_VERSION = 1; - private SQLiteDatabase db; - private AtomicInteger openCounter = new AtomicInteger(); - - public StopsDB(Context context) { - super(context, DB_NAME, null, DB_VERSION); - // WARNING: do not remove the following line, do not save anything in this database, it will be overwritten on every update! - setForcedUpgrade(); - - // remove old database (BusTo version 1.8.5 and below) - File filename = new File(context.getFilesDir(), "busto.sqlite"); - if(filename.exists()) { - //noinspection ResultOfMethodCallIgnored - filename.delete(); - } - } - - /** - * Through the magic of an atomic counter, the database gets opened and closed without race - * conditions between threads (HOPEFULLY). - * - * @return database or null if cannot be opened - */ - @Nullable - public synchronized SQLiteDatabase openIfNeeded() { - openCounter.incrementAndGet(); - this.db = getReadableDatabase(); - return this.db; - } - - /** - * Through the magic of an atomic counter, the database gets really closed only when no thread - * is using it anymore (HOPEFULLY). - */ - public synchronized void closeIfNeeded() { - // is anybody still using the database or can we close it? - if(openCounter.decrementAndGet() <= 0) { - super.close(); - this.db = null; - } - } - - public List getRoutesByStop(@NonNull String stopID) { - String[] uselessArray = {stopID}; - int count; - Cursor result; - - if(this.db == null) { - return null; - } - - try { - result = this.db.query("routemap", QUERY_COLUMN_route, "stop = ?", uselessArray, null, null, null); - } catch(SQLiteException e) { - return null; - } - - count = result.getCount(); - if(count == 0) { - return null; - } - - List routes = new ArrayList<>(count); - - while(result.moveToNext()) { - routes.add(result.getString(0)); - } - - result.close(); - - return routes; - } - - public String getLocationFromID(@NonNull String stopID) { - String[] uselessArray = {stopID}; - int count; - String name; - Cursor result; - - if(this.db == null) { - return null; - } - - try { - result = this.db.query(QUERY_TABLE_stops, QUERY_COLUMN_location, QUERY_WHERE_ID, uselessArray, null, null, null); - } catch(SQLiteException e) { - return null; - } - - count = result.getCount(); - if(count == 0) { - return null; - } - - result.moveToNext(); - name = result.getString(0); - - result.close(); - - return name; - } - - public Stop getAllFromID(@NonNull String stopID) { - Cursor result; - int count; - Stop s; - - if(this.db == null) { - return null; - } - - try { - result = this.db.query(QUERY_TABLE_stops, QUERY_COLUMN_everything, QUERY_WHERE_ID, new String[] {stopID}, null, null, null); - int colName = result.getColumnIndex("name"); - int colLocation = result.getColumnIndex("location"); - int colType = result.getColumnIndex("type"); - int colLat = result.getColumnIndex("lat"); - int colLon = result.getColumnIndex("lon"); - - count = result.getCount(); - if(count == 0) { - return null; - } - - result.moveToNext(); - - Route.Type type = routeTypeFromSymbol(result.getString(colType)); - - String locationWhichSometimesIsAnEmptyString = result.getString(colLocation); - if(locationWhichSometimesIsAnEmptyString.length() <= 0) { - locationWhichSometimesIsAnEmptyString = null; - } - - s = new Stop(stopID, result.getString(colName), null, locationWhichSometimesIsAnEmptyString, type, getRoutesByStop(stopID), result.getDouble(colLat), result.getDouble(colLon)); - } catch(SQLiteException e) { - return null; - } - - result.close(); - - return s; - } - - /** - * Query some bus stops inside a map view - * - * You can obtain the coordinates from OSMDroid using something like this: - * BoundingBoxE6 bb = mMapView.getBoundingBox(); - * double latFrom = bb.getLatSouthE6() / 1E6; - * double latTo = bb.getLatNorthE6() / 1E6; - * double lngFrom = bb.getLonWestE6() / 1E6; - * double lngTo = bb.getLonEastE6() / 1E6; - */ - public Stop[] queryAllInsideMapView(double minLat, double maxLat, double minLng, double maxLng) { - Stop[] stops = new Stop[0]; - - Cursor result; - int count; - - // coordinates must be strings in the where condition - String minLatRaw = String.valueOf(minLat); - String maxLatRaw = String.valueOf(maxLat); - String minLngRaw = String.valueOf(minLng); - String maxLngRaw = String.valueOf(maxLng); - - String stopID; - Route.Type type; - - if(this.db == null) { - return stops; - } - - try { - result = this.db.query(QUERY_TABLE_stops, QUERY_COLUMN_everything_and_ID, QUERY_WHERE_LAT_AND_LNG_IN_RANGE, new String[] {minLatRaw, maxLatRaw, minLngRaw, maxLngRaw}, null, null, null); - - int colID = result.getColumnIndex("ID"); - int colName = result.getColumnIndex("name"); - int colLocation = result.getColumnIndex("location"); - int colType = result.getColumnIndex("type"); - int colLat = result.getColumnIndex("lat"); - int colLon = result.getColumnIndex("lon"); - - count = result.getCount(); - stops = new Stop[count]; - - int i = 0; - while(result.moveToNext()) { - - stopID = result.getString(colID); - type = routeTypeFromSymbol(result.getString(colType)); - - String locationWhichSometimesIsAnEmptyString = result.getString(colLocation); - if (locationWhichSometimesIsAnEmptyString.length() <= 0) { - locationWhichSometimesIsAnEmptyString = null; - } - - stops[i++] = new Stop(stopID, result.getString(colName), null, - locationWhichSometimesIsAnEmptyString, type, getRoutesByStop(stopID), - result.getDouble(colLat), result.getDouble(colLon)); - } - - } catch(SQLiteException e) { - // TODO: put a warning in the log - return stops; - } - - result.close(); - - return stops; - } - - /** - * Get a Route Type from its char symbol - * - * @param route The route symbol (e.g. "B") - * @return The related Route.Type (e.g. Route.Type.Bus) - */ - public static Route.Type routeTypeFromSymbol(String route) { - switch (route) { - case "M": - return Route.Type.METRO; - case "T": - return Route.Type.RAILWAY; - } - - // default with case "B" - return Route.Type.BUS; - } -} diff --git a/src/it/reyboz/bustorino/fragments/MainScreenFragment.java b/src/it/reyboz/bustorino/fragments/MainScreenFragment.java --- a/src/it/reyboz/bustorino/fragments/MainScreenFragment.java +++ b/src/it/reyboz/bustorino/fragments/MainScreenFragment.java @@ -96,6 +96,7 @@ Handler mainHandler; private final Runnable refreshStop = new Runnable() { public void run() { + if(getContext() == null) return; if (fragMan.findFragmentById(R.id.resultFrame) instanceof ArrivalsFragment) { ArrivalsFragment fragment = (ArrivalsFragment) fragMan.findFragmentById(R.id.resultFrame); if (fragment == null){ @@ -131,8 +132,8 @@ if(status == AppLocationManager.LOCATION_GPS_AVAILABLE && !isNearbyFragmentShown()){ //request Stops pendingNearbyStopsRequest = false; - - mainHandler.post(new NearbyStopsRequester(getContext(), cr)); + if (getContext()!= null) + mainHandler.post(new NearbyStopsRequester(getContext(), cr)); } } @@ -149,7 +150,7 @@ @Override public void onLocationProviderAvailable() { //Log.w(DEBUG_TAG, "pendingNearbyStopRequest: "+pendingNearbyStopsRequest); - if(!isNearbyFragmentShown()){ + if(!isNearbyFragmentShown() && getContext()!=null){ pendingNearbyStopsRequest = false; mainHandler.post(new NearbyStopsRequester(getContext(), cr)); } @@ -317,6 +318,18 @@ */ } + /** + * Cancel the reload of the arrival times + * because we are going to pop the fragment + */ + public void cancelReloadArrivalsIfNeeded(){ + if(getContext()==null) return; //we are not attached + + //Fragment fr = getChildFragmentManager().findFragmentById(R.id.resultFrame); + fragmentHelper.stopLastRequestIfNeeded(); + toggleSpinner(false); + } + @Override public void onAttach(@NonNull Context context) { @@ -326,7 +339,7 @@ if (context instanceof CommonFragmentListener) { mListener = (CommonFragmentListener) context; } else { - throw new RuntimeException(context.toString() + throw new RuntimeException(context + " must implement CommonFragmentListener"); } if (setupOnAttached) { @@ -407,6 +420,7 @@ fragmentHelper.stopLastRequestIfNeeded(); } + /* GUI METHODS */ @@ -437,11 +451,11 @@ } else { // searchMode == SEARCH_BY_NAME String query = busStopSearchByNameEditText.getText().toString(); //new asyncWgetBusStopSuggestions(query, stopsDB, StopsFindersByNameRecursionHelper); - new AsyncDataDownload(fragmentHelper, stopsFinderByNames, getContext()).execute(query); + if(getContext()!=null) + new AsyncDataDownload(fragmentHelper, stopsFinderByNames, getContext()).execute(query); } } - public void onToggleKeyboardLayout(View v) { if (searchMode == SEARCH_BY_NAME) { diff --git a/src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java b/src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java --- a/src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java +++ b/src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java @@ -44,6 +44,7 @@ import android.widget.ProgressBar; import android.widget.TextView; import com.android.volley.*; +import it.reyboz.bustorino.BuildConfig; import it.reyboz.bustorino.R; import it.reyboz.bustorino.adapters.ArrivalsStopAdapter; import it.reyboz.bustorino.backend.*; @@ -225,7 +226,7 @@ if (context instanceof FragmentListenerMain) { mListener = (FragmentListenerMain) context; } else { - throw new RuntimeException(context.toString() + throw new RuntimeException(context + " must implement OnFragmentInteractionListener"); } Log.d(DEBUG_TAG, "OnAttach called"); @@ -267,12 +268,31 @@ mListener.enableRefreshLayout(false); Log.d(DEBUG_TAG,"OnResume called"); - + if(getContext()==null){ + Log.e(DEBUG_TAG, "NULL CONTEXT, everything is going to crash now"); + MIN_NUM_STOPS = 5; + MAX_DISTANCE = 600; + return; + } //Re-read preferences SharedPreferences shpr = PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext()); //For some reason, they are all saved as strings MAX_DISTANCE = shpr.getInt(getString(R.string.pref_key_radius_recents),600); - MIN_NUM_STOPS = Integer.parseInt(shpr.getString(getString(R.string.pref_key_num_recents),"10")); + boolean isMinStopInt = true; + try{ + MIN_NUM_STOPS = shpr.getInt(getString(R.string.pref_key_num_recents), 5); + } catch (ClassCastException ex){ + isMinStopInt = false; + } + if(!isMinStopInt) + try { + MIN_NUM_STOPS = Integer.parseInt(shpr.getString(getString(R.string.pref_key_num_recents), "5")); + } catch (NumberFormatException ex){ + MIN_NUM_STOPS = 5; + } + if(BuildConfig.DEBUG) + Log.d(DEBUG_TAG, "Max distance for stops: "+MAX_DISTANCE+ + ", Min number of stops: "+MIN_NUM_STOPS); } @@ -311,21 +331,30 @@ public void onLoadFinished(@NonNull Loader loader, Cursor data) { if (0 > MAX_DISTANCE) throw new AssertionError(); //Cursor might be null + Log.d(DEBUG_TAG, "Num stops found: "+data.getCount()+", Current distance: "+distance); if(data==null){ Log.e(DEBUG_TAG,"Null cursor, something really wrong happened"); return; } - if(!isDBUpdating() && (data.getCount() stopList = createStopListFromCursor(data); + if(data.getCount()>0) { + ArrayList stopList = createStopListFromCursor(data); + double minDistance = Double.POSITIVE_INFINITY; + for(Stop s: stopList){ + minDistance = Math.min(minDistance, s.getDistanceFromLocation(lastReceivedLocation)); + } + + //quick trial to hopefully always get the stops in the correct order Collections.sort(stopList,new StopSorterByDistance(lastReceivedLocation)); switch (fragment_type){ @@ -350,7 +379,7 @@ } @Override - public void onLoaderReset(Loader loader) { + public void onLoaderReset(@NonNull Loader loader) { } /** @@ -427,6 +456,10 @@ routesPairList.add(new Pair<>(p,r)); } } + if (getContext()==null){ + Log.e(DEBUG_TAG, "Trying to show arrivals in Recycler but we're not attached"); + return; + } if(firstLocForArrivals){ arrivalsStopAdapter = new ArrivalsStopAdapter(routesPairList,mListener,getContext(),lastReceivedLocation); gridRecyclerView.setAdapter(arrivalsStopAdapter); @@ -465,13 +498,13 @@ final static String REQUEST_TAG = "NearbyArrivals"; private final QueryType[] types = {QueryType.ARRIVALS,QueryType.DETAILS}; final NetworkVolleyManager volleyManager; - private final int MAX_ARRIVAL_STOPS =35; int activeRequestCount = 0,reqErrorCount = 0, reqSuccessCount=0; ArrivalsManager(List stops){ mStops = new HashMap<>(); volleyManager = NetworkVolleyManager.getInstance(getContext()); + int MAX_ARRIVAL_STOPS = 35; for(Stop s: stops.subList(0,Math.min(stops.size(), MAX_ARRIVAL_STOPS))){ mStops.put(s.ID,new Palina(s)); for(QueryType t: types) { @@ -594,6 +627,7 @@ switch(status){ case AppLocationManager.LOCATION_GPS_AVAILABLE: messageTextView.setVisibility(View.GONE); + break; case AppLocationManager.LOCATION_UNAVAILABLE: messageTextView.setText(R.string.enableGpsText); diff --git a/src/it/reyboz/bustorino/fragments/SettingsFragment.java b/src/it/reyboz/bustorino/fragments/SettingsFragment.java --- a/src/it/reyboz/bustorino/fragments/SettingsFragment.java +++ b/src/it/reyboz/bustorino/fragments/SettingsFragment.java @@ -3,34 +3,125 @@ import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; +import android.os.Handler; import android.util.Log; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.preference.*; import it.reyboz.bustorino.R; +import java.lang.ref.WeakReference; + public class SettingsFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = SettingsFragment.class.getName(); - SharedPreferences preferences; + private static final String DIALOG_FRAGMENT_TAG = + "androidx.preference.PreferenceFragment.DIALOG"; + //private static final + Handler mHandler; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + mHandler = new Handler(); + return super.onCreateView(inflater, container, savedInstanceState); + + } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + //getPreferenceManager().setSharedPreferencesName(getString(R.string.mainSharedPreferences)); + convertStringPrefToIntIfNeeded(getString(R.string.pref_key_num_recents), getContext()); + + getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); setPreferencesFromResource(R.xml.preferences,rootKey); - Context con = getContext(); - if (con == null){ - Log.w("SETTINGS FRAGMENT", "context is null"); - preferences = null; - } - else - preferences = getContext().getSharedPreferences(getString(R.string.mainSharedPreferences), Context.MODE_PRIVATE); + /*EditTextPreference editPref = findPreference(getString(R.string.pref_key_num_recents)); + editPref.setOnBindEditTextListener(editText -> { + editText.setInputType(InputType.TYPE_CLASS_NUMBER); + editText.setSelection(0,editText.getText().length()); + }); + */ + + } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { Preference pref = findPreference(key); - //non so a cosa serva tutto questo + Log.d(TAG,"Preference key "+key+" changed"); + //sometimes this happens + if(getContext()==null) return; + /* + THIS CODE STAYS COMMENTED FOR FUTURE REFERENCES + if (key.equals(getString(R.string.pref_key_num_recents))){ + //check that is it an int + + String value = sharedPreferences.getString(key,""); + boolean valid = value.length() != 0; + try{ + Integer intValue = Integer.parseInt(value); + } catch (NumberFormatException ex){ + valid = false; + } + if (!valid){ + Toast.makeText(getContext(), R.string.invalid_number, Toast.LENGTH_SHORT).show(); + if(pref instanceof EditTextPreference){ + EditTextPreference prefEdit = (EditTextPreference) pref; + //Intent intent = prefEdit.getIntent(); + Log.d(TAG, "opening preference, dialog showing "+ + (getParentFragmentManager().findFragmentByTag(DIALOG_FRAGMENT_TAG)!=null) ); + //getPreferenceManager().showDialog(pref); + //onDisplayPreferenceDialog(prefEdit); + mHandler.postDelayed(new DelayedDisplay(prefEdit), 500); + } + + } + } + */ Log.d("BusTO Settings", "changed "+key+"\n "+sharedPreferences.getAll()); } + + private void convertStringPrefToIntIfNeeded(String preferenceKey, Context con){ + if (con == null) return; + SharedPreferences defaultSharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); + try{ + + Integer val = defaultSharedPref.getInt(preferenceKey, 0); + } catch (NumberFormatException | ClassCastException ex){ + //convert the preference + //final String preferenceNumRecents = getString(R.string.pref_key_num_recents); + Log.d("Preference - BusTO", "Converting to integer the string preference "+preferenceKey); + String currentValue = defaultSharedPref.getString(preferenceKey, "10"); + int newValue; + try{ + newValue = Integer.parseInt(currentValue); + } catch (NumberFormatException e){ + newValue = 10; + } + final SharedPreferences.Editor editor = defaultSharedPref.edit(); + editor.remove(preferenceKey); + editor.putInt(preferenceKey, newValue); + editor.apply(); + } + } + + class DelayedDisplay implements Runnable{ + private final WeakReference preferenceWeakReference; + + public DelayedDisplay(DialogPreference preference) { + this.preferenceWeakReference = new WeakReference<>(preference); + } + + @Override + public void run() { + if(preferenceWeakReference.get()==null) + return; + + getPreferenceManager().showDialog(preferenceWeakReference.get()); + } + } } diff --git a/src/it/reyboz/bustorino/middleware/AsyncDataDownload.java b/src/it/reyboz/bustorino/middleware/AsyncDataDownload.java --- a/src/it/reyboz/bustorino/middleware/AsyncDataDownload.java +++ b/src/it/reyboz/bustorino/middleware/AsyncDataDownload.java @@ -116,8 +116,12 @@ return null; } //Skip the FiveTAPIFetcher for the Metro Stops because it shows incomprehensible arrival times - if(f instanceof FiveTAPIFetcher && Integer.parseInt(stopID)>= 8200) - continue; + try { + if (f instanceof FiveTAPIFetcher && Integer.parseInt(stopID) >= 8200) + continue; + } catch (NumberFormatException ex){ + Log.e(DEBUG_TAG, "The stop number is not a valid integer, expect failures"); + } p= f.ReadArrivalTimesAll(stopID,res); publishProgress(res.get()); //if (res.get()!= Fetcher.Result.OK) @@ -149,7 +153,10 @@ } } } - + p.mergeDuplicateRoutes(0); + if(p.queryAllRoutes().size() == 0) + //skip the rest and go to the next fetcher + continue; result = p; //TODO: find a way to avoid overloading the user with toasts break;