Changeset View
Changeset View
Standalone View
Standalone View
src/it/reyboz/bustorino/fragments/ArrivalsFragment.java
Show All 12 Lines | BusTO - Fragments components | ||||
GNU General Public License for more details. | GNU General Public License for more details. | ||||
You should have received a copy of the GNU General Public License | You should have received a copy of the GNU General Public License | ||||
along with this program. If not, see <http://www.gnu.org/licenses/>. | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
*/ | */ | ||||
package it.reyboz.bustorino.fragments; | package it.reyboz.bustorino.fragments; | ||||
import android.content.Context; | |||||
import android.database.Cursor; | import android.database.Cursor; | ||||
import android.net.Uri; | import android.net.Uri; | ||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||
import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||
import androidx.loader.app.LoaderManager; | import androidx.loader.app.LoaderManager; | ||||
import androidx.loader.content.CursorLoader; | import androidx.loader.content.CursorLoader; | ||||
import androidx.loader.content.Loader; | import androidx.loader.content.Loader; | ||||
import android.util.Log; | import android.util.Log; | ||||
import android.view.LayoutInflater; | import android.view.LayoutInflater; | ||||
import android.view.View; | import android.view.View; | ||||
import android.view.ViewGroup; | import android.view.ViewGroup; | ||||
import android.widget.ImageButton; | import android.widget.ImageButton; | ||||
import android.widget.ListAdapter; | import android.widget.ListAdapter; | ||||
import android.widget.ListView; | |||||
import android.widget.TextView; | import android.widget.TextView; | ||||
import android.widget.Toast; | import android.widget.Toast; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Arrays; | |||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.List; | import java.util.List; | ||||
import it.reyboz.bustorino.R; | import it.reyboz.bustorino.R; | ||||
import it.reyboz.bustorino.adapters.PalinaAdapter; | import it.reyboz.bustorino.adapters.PalinaAdapter; | ||||
import it.reyboz.bustorino.backend.ArrivalsFetcher; | import it.reyboz.bustorino.backend.ArrivalsFetcher; | ||||
import it.reyboz.bustorino.backend.DBStatusManager; | import it.reyboz.bustorino.backend.DBStatusManager; | ||||
import it.reyboz.bustorino.backend.Fetcher; | import it.reyboz.bustorino.backend.Fetcher; | ||||
import it.reyboz.bustorino.backend.FiveTAPIFetcher; | |||||
import it.reyboz.bustorino.backend.FiveTNormalizer; | import it.reyboz.bustorino.backend.FiveTNormalizer; | ||||
import it.reyboz.bustorino.backend.FiveTScraperFetcher; | |||||
import it.reyboz.bustorino.backend.GTTJSONFetcher; | |||||
import it.reyboz.bustorino.backend.Palina; | import it.reyboz.bustorino.backend.Palina; | ||||
import it.reyboz.bustorino.backend.Passaggio; | import it.reyboz.bustorino.backend.Passaggio; | ||||
import it.reyboz.bustorino.backend.Route; | import it.reyboz.bustorino.backend.Route; | ||||
import it.reyboz.bustorino.backend.Stop; | import it.reyboz.bustorino.backend.Stop; | ||||
import it.reyboz.bustorino.backend.utils; | import it.reyboz.bustorino.backend.utils; | ||||
import it.reyboz.bustorino.data.AppDataProvider; | import it.reyboz.bustorino.data.AppDataProvider; | ||||
import it.reyboz.bustorino.data.NextGenDB; | import it.reyboz.bustorino.data.NextGenDB; | ||||
import it.reyboz.bustorino.data.UserDB; | import it.reyboz.bustorino.data.UserDB; | ||||
import it.reyboz.bustorino.middleware.AsyncStopFavoriteAction; | import it.reyboz.bustorino.middleware.AsyncStopFavoriteAction; | ||||
public class ArrivalsFragment extends ResultListFragment implements LoaderManager.LoaderCallbacks<Cursor> { | public class ArrivalsFragment extends ResultListFragment implements LoaderManager.LoaderCallbacks<Cursor> { | ||||
private final static String KEY_STOP_ID = "stopid"; | private final static String KEY_STOP_ID = "stopid"; | ||||
private final static String KEY_STOP_NAME = "stopname"; | private final static String KEY_STOP_NAME = "stopname"; | ||||
private final static String DEBUG_TAG_ALL = "BUSTOArrivalsFragment"; | private final static String DEBUG_TAG_ALL = "BUSTOArrivalsFragment"; | ||||
private String DEBUG_TAG = DEBUG_TAG_ALL; | private String DEBUG_TAG = DEBUG_TAG_ALL; | ||||
private final static int loaderFavId = 2; | private final static int loaderFavId = 2; | ||||
private final static int loaderStopId = 1; | private final static int loaderStopId = 1; | ||||
static final String STOP_TITLE = "messageExtra"; | static final String STOP_TITLE = "messageExtra"; | ||||
private final static String SOURCES_TEXT="sources_textview_message"; | |||||
private @Nullable String stopID,stopName; | private @Nullable String stopID,stopName; | ||||
private DBStatusManager prefs; | private DBStatusManager prefs; | ||||
private DBStatusManager.OnDBUpdateStatusChangeListener listener; | private DBStatusManager.OnDBUpdateStatusChangeListener listener; | ||||
private boolean justCreated = false; | private boolean justCreated = false; | ||||
private Palina lastUpdatedPalina = null; | private Palina lastUpdatedPalina = null; | ||||
private boolean needUpdateOnAttach = false; | private boolean needUpdateOnAttach = false; | ||||
private boolean fetchersChangeRequestPending = false; | private boolean fetchersChangeRequestPending = false; | ||||
private boolean stopIsInFavorites = false; | private boolean stopIsInFavorites = false; | ||||
//Views | //Views | ||||
protected ImageButton addToFavorites; | protected ImageButton addToFavorites; | ||||
protected TextView timesSourceTextView; | protected TextView timesSourceTextView; | ||||
private List<ArrivalsFetcher> fetchers = new ArrayList<>(Arrays.asList(utils.getDefaultArrivalsFetchers())); | private List<ArrivalsFetcher> fetchers = null; //new ArrayList<>(Arrays.asList(utils.getDefaultArrivalsFetchers())); | ||||
private boolean reloadOnResume = true; | private boolean reloadOnResume = true; | ||||
public static ArrivalsFragment newInstance(String stopID){ | public static ArrivalsFragment newInstance(String stopID){ | ||||
return newInstance(stopID, null); | return newInstance(stopID, null); | ||||
} | } | ||||
public static ArrivalsFragment newInstance(@NonNull String stopID, @Nullable String stopName){ | public static ArrivalsFragment newInstance(@NonNull String stopID, @Nullable String stopName){ | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | public View onCreateView(LayoutInflater inflater, ViewGroup container, | ||||
String probablemessage = getArguments().getString(MESSAGE_TEXT_VIEW); | String probablemessage = getArguments().getString(MESSAGE_TEXT_VIEW); | ||||
if (probablemessage != null) { | if (probablemessage != null) { | ||||
//Log.d("BusTO fragment " + this.getTag(), "We have a possible message here in the savedInstaceState: " + probablemessage); | //Log.d("BusTO fragment " + this.getTag(), "We have a possible message here in the savedInstaceState: " + probablemessage); | ||||
messageTextView.setText(probablemessage); | messageTextView.setText(probablemessage); | ||||
messageTextView.setVisibility(View.VISIBLE); | messageTextView.setVisibility(View.VISIBLE); | ||||
} | } | ||||
/*String sourcesTextViewData = getArguments().getString(SOURCES_TEXT); | |||||
if (sourcesTextViewData!=null){ | |||||
timesSourceTextView.setText(sourcesTextViewData); | |||||
}*/ | |||||
//need to do this when we recreate the fragment but we haven't updated the arrival times | |||||
if (lastUpdatedPalina!=null) | |||||
showArrivalsSources(lastUpdatedPalina); | |||||
return root; | return root; | ||||
} | } | ||||
@Override | @Override | ||||
public void onResume() { | public void onResume() { | ||||
super.onResume(); | super.onResume(); | ||||
LoaderManager loaderManager = getLoaderManager(); | LoaderManager loaderManager = getLoaderManager(); | ||||
Log.d(DEBUG_TAG, "OnResume, justCreated "+justCreated); | Log.d(DEBUG_TAG, "OnResume, justCreated "+justCreated); | ||||
/*if(needUpdateOnAttach){ | /*if(needUpdateOnAttach){ | ||||
updateFragmentData(null); | updateFragmentData(null); | ||||
needUpdateOnAttach=false; | needUpdateOnAttach=false; | ||||
}*/ | }*/ | ||||
if(stopID!=null){ | if(stopID!=null){ | ||||
//refresh the arrivals | //refresh the arrivals | ||||
if(!justCreated){ | if(!justCreated){ | ||||
fetchers = utils.getDefaultArrivalsFetchers(getContext()); | |||||
adjustFetchersToSource(); | |||||
if (reloadOnResume) | if (reloadOnResume) | ||||
mListener.requestArrivalsForStopID(stopID); | mListener.requestArrivalsForStopID(stopID); | ||||
} | } | ||||
else justCreated = false; | else justCreated = false; | ||||
//start the loader | //start the loader | ||||
if(prefs.isDBUpdating(true)){ | if(prefs.isDBUpdating(true)){ | ||||
prefs.registerListener(); | prefs.registerListener(); | ||||
} else { | } else { | ||||
Log.d(DEBUG_TAG, "Restarting loader for stop"); | Log.d(DEBUG_TAG, "Restarting loader for stop"); | ||||
loaderManager.restartLoader(loaderFavId, getArguments(), this); | loaderManager.restartLoader(loaderFavId, getArguments(), this); | ||||
} | } | ||||
updateMessage(); | updateMessage(); | ||||
} | } | ||||
} | } | ||||
@Override | @Override | ||||
public void onStart() { | public void onStart() { | ||||
super.onStart(); | super.onStart(); | ||||
if (needUpdateOnAttach){ | if (needUpdateOnAttach){ | ||||
updateFragmentData(null); | updateFragmentData(null); | ||||
needUpdateOnAttach = false; | needUpdateOnAttach = false; | ||||
} | } | ||||
} | } | ||||
@Override | @Override | ||||
public void onPause() { | public void onPause() { | ||||
if(listener!=null) | if(listener!=null) | ||||
prefs.unregisterListener(); | prefs.unregisterListener(); | ||||
super.onPause(); | super.onPause(); | ||||
LoaderManager loaderManager = getLoaderManager(); | LoaderManager loaderManager = getLoaderManager(); | ||||
Log.d(DEBUG_TAG, "onPause, have running loaders: "+loaderManager.hasRunningLoaders()); | Log.d(DEBUG_TAG, "onPause, have running loaders: "+loaderManager.hasRunningLoaders()); | ||||
loaderManager.destroyLoader(loaderFavId); | loaderManager.destroyLoader(loaderFavId); | ||||
} | } | ||||
@Override | |||||
public void onAttach(@NonNull Context context) { | |||||
super.onAttach(context); | |||||
//get fetchers | |||||
fetchers = utils.getDefaultArrivalsFetchers(context); | |||||
} | |||||
@Nullable | @Nullable | ||||
public String getStopID() { | public String getStopID() { | ||||
return stopID; | return stopID; | ||||
} | } | ||||
public boolean reloadsOnResume() { | public boolean reloadsOnResume() { | ||||
return reloadOnResume; | return reloadOnResume; | ||||
} | } | ||||
Show All 11 Lines | public class ArrivalsFragment extends ResultListFragment implements LoaderManager.LoaderCallbacks<Cursor> { | ||||
} | } | ||||
public ArrivalsFetcher[] getCurrentFetchersAsArray(){ | public ArrivalsFetcher[] getCurrentFetchersAsArray(){ | ||||
ArrivalsFetcher[] arr = new ArrivalsFetcher[fetchers.size()]; | ArrivalsFetcher[] arr = new ArrivalsFetcher[fetchers.size()]; | ||||
fetchers.toArray(arr); | fetchers.toArray(arr); | ||||
return arr; | return arr; | ||||
} | } | ||||
private void rotateFetchers(){ | private void rotateFetchers(){ | ||||
Log.d(DEBUG_TAG, "Rotating fetchers, before: "+fetchers); | |||||
Collections.rotate(fetchers, -1); | Collections.rotate(fetchers, -1); | ||||
Log.d(DEBUG_TAG, "Rotating fetchers, afterwards: "+fetchers); | |||||
} | } | ||||
/** | /** | ||||
* Update the UI with the new data | * Update the UI with the new data | ||||
* @param p the full Palina | * @param p the full Palina | ||||
*/ | */ | ||||
public void updateFragmentData(@Nullable Palina p){ | public void updateFragmentData(@Nullable Palina p){ | ||||
Show All 39 Lines | protected void showArrivalsSources(Palina p){ | ||||
break; | break; | ||||
case UNDETERMINED: | case UNDETERMINED: | ||||
//Don't show the view | //Don't show the view | ||||
source_txt = getString(R.string.undetermined_source); | source_txt = getString(R.string.undetermined_source); | ||||
break; | break; | ||||
default: | default: | ||||
throw new IllegalStateException("Unexpected value: " + source); | throw new IllegalStateException("Unexpected value: " + source); | ||||
} | } | ||||
int count = 0; | // | ||||
if (source!= Passaggio.Source.UNDETERMINED) | final boolean updatedFetchers = adjustFetchersToSource(source); | ||||
while (source != fetchers.get(0).getSourceForFetcher() && count < 100){ | if(!updatedFetchers) | ||||
//we need to update the fetcher that is requested | |||||
rotateFetchers(); | |||||
count++; | |||||
} | |||||
if (count>10) | |||||
Log.w(DEBUG_TAG, "Tried to update the source fetcher but it didn't work"); | Log.w(DEBUG_TAG, "Tried to update the source fetcher but it didn't work"); | ||||
final String base_message = getString(R.string.times_source_fmt, source_txt); | final String base_message = getString(R.string.times_source_fmt, source_txt); | ||||
timesSourceTextView.setText(base_message); | timesSourceTextView.setText(base_message); | ||||
if (p.getTotalNumberOfPassages() > 0) { | if (p.getTotalNumberOfPassages() > 0) { | ||||
timesSourceTextView.setVisibility(View.VISIBLE); | timesSourceTextView.setVisibility(View.VISIBLE); | ||||
} else { | } else { | ||||
timesSourceTextView.setVisibility(View.INVISIBLE); | timesSourceTextView.setVisibility(View.INVISIBLE); | ||||
} | } | ||||
fetchersChangeRequestPending = false; | fetchersChangeRequestPending = false; | ||||
} | } | ||||
protected boolean adjustFetchersToSource(Passaggio.Source source){ | |||||
if (source == null) return false; | |||||
int count = 0; | |||||
if (source!= Passaggio.Source.UNDETERMINED) | |||||
while (source != fetchers.get(0).getSourceForFetcher() && count < 200){ | |||||
//we need to update the fetcher that is requested | |||||
rotateFetchers(); | |||||
count++; | |||||
} | |||||
return count < 200; | |||||
} | |||||
protected boolean adjustFetchersToSource(){ | |||||
if (lastUpdatedPalina == null) return false; | |||||
final Passaggio.Source source = lastUpdatedPalina.getPassaggiSourceIfAny(); | |||||
return adjustFetchersToSource(source); | |||||
} | |||||
@Override | @Override | ||||
public void setNewListAdapter(ListAdapter adapter) { | public void setNewListAdapter(ListAdapter adapter) { | ||||
throw new UnsupportedOperationException(); | throw new UnsupportedOperationException(); | ||||
} | } | ||||
/** | /** | ||||
* Update the message in the fragment | * Update the message in the fragment | ||||
* | * | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | public void onLoadFinished(Loader<Cursor> loader, Cursor data) { | ||||
//stop is not inside the favorites and wasn't provided | //stop is not inside the favorites and wasn't provided | ||||
Log.d("ArrivalsFragment"+getTag(),"Stop wasn't in the favorites and has no name, looking in the DB"); | Log.d("ArrivalsFragment"+getTag(),"Stop wasn't in the favorites and has no name, looking in the DB"); | ||||
getLoaderManager().restartLoader(loaderStopId,getArguments(),this); | getLoaderManager().restartLoader(loaderStopId,getArguments(),this); | ||||
} | } | ||||
break; | break; | ||||
case loaderStopId: | case loaderStopId: | ||||
if(data.getCount()>0){ | if(data.getCount()>0){ | ||||
data.moveToFirst(); | data.moveToFirst(); | ||||
stopName = data.getString(data.getColumnIndex( | int index = data.getColumnIndex( | ||||
NextGenDB.Contract.StopsTable.COL_NAME | NextGenDB.Contract.StopsTable.COL_NAME | ||||
)); | ); | ||||
if (index == -1){ | |||||
Log.e(DEBUG_TAG, "Index is -1, column not present. App may explode now..."); | |||||
} | |||||
stopName = data.getString(index); | |||||
updateMessage(); | updateMessage(); | ||||
} else { | } else { | ||||
Log.w("ArrivalsFragment"+getTag(),"Stop is not inside the database... CLOISTER BELL"); | Log.w("ArrivalsFragment"+getTag(),"Stop is not inside the database... CLOISTER BELL"); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | public void updateStarIcon() { | ||||
} | } | ||||
addToFavorites.setVisibility(View.VISIBLE); | addToFavorites.setVisibility(View.VISIBLE); | ||||
} | } | ||||
} | } | ||||
@Override | |||||
public void onDestroyView() { | |||||
getArguments().putString(SOURCES_TEXT, timesSourceTextView.getText().toString()); | |||||
super.onDestroyView(); | |||||
} | |||||
} | } |
Public contents are in Creative Commons Attribution-ShareAlike 4.0 (CC-BY-SA) or GNU Free Documentation License (at your option) unless otherwise noted. · Contact / Register