Changeset View
Changeset View
Standalone View
Standalone View
src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
Show All 22 Lines | |||||
import android.database.Cursor; | import android.database.Cursor; | ||||
import android.location.Location; | import android.location.Location; | ||||
import android.net.Uri; | import android.net.Uri; | ||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||
import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||
import androidx.fragment.app.Fragment; | import androidx.fragment.app.Fragment; | ||||
import androidx.lifecycle.Observer; | |||||
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 androidx.core.util.Pair; | import androidx.core.util.Pair; | ||||
import androidx.preference.PreferenceManager; | import androidx.preference.PreferenceManager; | ||||
import androidx.appcompat.widget.AppCompatButton; | import androidx.appcompat.widget.AppCompatButton; | ||||
import androidx.recyclerview.widget.GridLayoutManager; | import androidx.recyclerview.widget.GridLayoutManager; | ||||
import androidx.recyclerview.widget.RecyclerView; | import androidx.recyclerview.widget.RecyclerView; | ||||
import androidx.work.WorkInfo; | |||||
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.ProgressBar; | import android.widget.ProgressBar; | ||||
import android.widget.TextView; | import android.widget.TextView; | ||||
import com.android.volley.*; | import com.android.volley.*; | ||||
import it.reyboz.bustorino.BuildConfig; | import it.reyboz.bustorino.BuildConfig; | ||||
import it.reyboz.bustorino.R; | import it.reyboz.bustorino.R; | ||||
import it.reyboz.bustorino.adapters.ArrivalsStopAdapter; | import it.reyboz.bustorino.adapters.ArrivalsStopAdapter; | ||||
import it.reyboz.bustorino.backend.*; | import it.reyboz.bustorino.backend.*; | ||||
import it.reyboz.bustorino.backend.FiveTAPIFetcher.QueryType; | import it.reyboz.bustorino.backend.FiveTAPIFetcher.QueryType; | ||||
import it.reyboz.bustorino.backend.mato.MapiArrivalRequest; | |||||
import it.reyboz.bustorino.data.DatabaseUpdate; | |||||
import it.reyboz.bustorino.middleware.AppLocationManager; | import it.reyboz.bustorino.middleware.AppLocationManager; | ||||
import it.reyboz.bustorino.data.AppDataProvider; | import it.reyboz.bustorino.data.AppDataProvider; | ||||
import it.reyboz.bustorino.data.NextGenDB.Contract.*; | import it.reyboz.bustorino.data.NextGenDB.Contract.*; | ||||
import it.reyboz.bustorino.adapters.SquareStopAdapter; | import it.reyboz.bustorino.adapters.SquareStopAdapter; | ||||
import it.reyboz.bustorino.util.LocationCriteria; | import it.reyboz.bustorino.util.LocationCriteria; | ||||
import it.reyboz.bustorino.util.StopSorterByDistance; | import it.reyboz.bustorino.util.StopSorterByDistance; | ||||
import java.util.*; | import java.util.*; | ||||
Show All 13 Lines | public class NearbyStopsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { | ||||
//data Bundle | //data Bundle | ||||
private final String BUNDLE_LOCATION = "location"; | private final String BUNDLE_LOCATION = "location"; | ||||
private final int LOADER_ID = 0; | private final int LOADER_ID = 0; | ||||
private RecyclerView gridRecyclerView; | private RecyclerView gridRecyclerView; | ||||
private SquareStopAdapter dataAdapter; | private SquareStopAdapter dataAdapter; | ||||
private AutoFitGridLayoutManager gridLayoutManager; | private AutoFitGridLayoutManager gridLayoutManager; | ||||
boolean canStartDBQuery = true; | |||||
private Location lastReceivedLocation = null; | private Location lastReceivedLocation = null; | ||||
private ProgressBar circlingProgressBar,flatProgressBar; | private ProgressBar circlingProgressBar,flatProgressBar; | ||||
private int distance; | private int distance; | ||||
protected SharedPreferences globalSharedPref; | protected SharedPreferences globalSharedPref; | ||||
private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener; | private SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener; | ||||
private TextView messageTextView,titleTextView; | private TextView messageTextView,titleTextView; | ||||
private CommonScrollListener scrollListener; | private CommonScrollListener scrollListener; | ||||
private AppCompatButton switchButton; | private AppCompatButton switchButton; | ||||
private boolean firstLocForStops = true,firstLocForArrivals = true; | private boolean firstLocForStops = true,firstLocForArrivals = true; | ||||
public static final int COLUMN_WIDTH_DP = 250; | public static final int COLUMN_WIDTH_DP = 250; | ||||
private Integer MAX_DISTANCE = -3; | private Integer MAX_DISTANCE = -3; | ||||
private int MIN_NUM_STOPS = -1; | private int MIN_NUM_STOPS = -1; | ||||
private int TIME_INTERVAL_REQUESTS = -1; | private int TIME_INTERVAL_REQUESTS = -1; | ||||
private AppLocationManager locManager; | private AppLocationManager locManager; | ||||
//These are useful for the case of nearby arrivals | //These are useful for the case of nearby arrivals | ||||
private ArrivalsManager arrivalsManager = null; | private ArrivalsManager arrivalsManager = null; | ||||
private ArrivalsStopAdapter arrivalsStopAdapter = null; | private ArrivalsStopAdapter arrivalsStopAdapter = null; | ||||
private boolean dbUpdateRunning = false; | |||||
private ArrayList<Stop> currentNearbyStops = new ArrayList<>(); | |||||
public NearbyStopsFragment() { | public NearbyStopsFragment() { | ||||
// Required empty public constructor | // Required empty public constructor | ||||
} | } | ||||
/** | /** | ||||
* Use this factory method to create a new instance of | * Use this factory method to create a new instance of | ||||
* this fragment using the provided parameters. | * this fragment using the provided parameters. | ||||
* @return A new instance of fragment NearbyStopsFragment. | * @return A new instance of fragment NearbyStopsFragment. | ||||
Show All 13 Lines | public class NearbyStopsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { | ||||
@Override | @Override | ||||
public void onCreate(Bundle savedInstanceState) { | public void onCreate(Bundle savedInstanceState) { | ||||
super.onCreate(savedInstanceState); | super.onCreate(savedInstanceState); | ||||
if (getArguments() != null) { | if (getArguments() != null) { | ||||
setFragmentType(getArguments().getInt(FRAGMENT_TYPE_KEY)); | setFragmentType(getArguments().getInt(FRAGMENT_TYPE_KEY)); | ||||
} | } | ||||
locManager = AppLocationManager.getInstance(getContext()); | locManager = AppLocationManager.getInstance(getContext()); | ||||
fragmentLocationListener = new FragmentLocationListener(this); | fragmentLocationListener = new FragmentLocationListener(this); | ||||
if (getContext()!=null) { | |||||
globalSharedPref = getContext().getSharedPreferences(getString(R.string.mainSharedPreferences),Context.MODE_PRIVATE); | globalSharedPref = getContext().getSharedPreferences(getString(R.string.mainSharedPreferences), Context.MODE_PRIVATE); | ||||
globalSharedPref.registerOnSharedPreferenceChangeListener(preferenceChangeListener); | globalSharedPref.registerOnSharedPreferenceChangeListener(preferenceChangeListener); | ||||
} | |||||
} | } | ||||
@Override | @Override | ||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, | ||||
Bundle savedInstanceState) { | Bundle savedInstanceState) { | ||||
// Inflate the layout for this fragment | // Inflate the layout for this fragment | ||||
if (getContext() == null) throw new RuntimeException(); | if (getContext() == null) throw new RuntimeException(); | ||||
View root = inflater.inflate(R.layout.fragment_nearby_stops, container, false); | View root = inflater.inflate(R.layout.fragment_nearby_stops, container, false); | ||||
gridRecyclerView = root.findViewById(R.id.stopGridRecyclerView); | gridRecyclerView = root.findViewById(R.id.stopGridRecyclerView); | ||||
gridLayoutManager = new AutoFitGridLayoutManager(getContext().getApplicationContext(), Float.valueOf(utils.convertDipToPixels(getContext(),COLUMN_WIDTH_DP)).intValue()); | gridLayoutManager = new AutoFitGridLayoutManager(getContext().getApplicationContext(), Float.valueOf(utils.convertDipToPixels(getContext(),COLUMN_WIDTH_DP)).intValue()); | ||||
gridRecyclerView.setLayoutManager(gridLayoutManager); | gridRecyclerView.setLayoutManager(gridLayoutManager); | ||||
gridRecyclerView.setHasFixedSize(false); | gridRecyclerView.setHasFixedSize(false); | ||||
circlingProgressBar = root.findViewById(R.id.loadingBar); | circlingProgressBar = root.findViewById(R.id.loadingBar); | ||||
flatProgressBar = root.findViewById(R.id.horizontalProgressBar); | flatProgressBar = root.findViewById(R.id.horizontalProgressBar); | ||||
messageTextView = root.findViewById(R.id.messageTextView); | messageTextView = root.findViewById(R.id.messageTextView); | ||||
titleTextView = root.findViewById(R.id.titleTextView); | titleTextView = root.findViewById(R.id.titleTextView); | ||||
switchButton = root.findViewById(R.id.switchButton); | switchButton = root.findViewById(R.id.switchButton); | ||||
preferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() { | scrollListener = new CommonScrollListener(mListener,false); | ||||
switchButton.setOnClickListener(v -> switchFragmentType()); | |||||
Log.d(DEBUG_TAG, "onCreateView"); | |||||
DatabaseUpdate.watchUpdateWorkStatus(getContext(), this, new Observer<List<WorkInfo>>() { | |||||
@Override | @Override | ||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { | public void onChanged(List<WorkInfo> workInfos) { | ||||
Log.d(DEBUG_TAG,"Key "+key+" was changed"); | if(workInfos.isEmpty()) return; | ||||
if(key.equals(getString(R.string.databaseUpdatingPref))){ | |||||
if(!sharedPreferences.getBoolean(getString(R.string.databaseUpdatingPref),true)){ | WorkInfo wi = workInfos.get(0); | ||||
canStartDBQuery = true; | if (wi.getState() == WorkInfo.State.RUNNING && locManager.isRequesterRegistered(fragmentLocationListener)) { | ||||
Log.d(DEBUG_TAG,"The database has finished updating, can start update now"); | locManager.removeLocationRequestFor(fragmentLocationListener); | ||||
} | dbUpdateRunning = true; | ||||
} else if(!locManager.isRequesterRegistered(fragmentLocationListener)){ | |||||
locManager.addLocationRequestFor(fragmentLocationListener); | |||||
dbUpdateRunning = false; | |||||
} | } | ||||
} | } | ||||
}; | |||||
scrollListener = new CommonScrollListener(mListener,false); | |||||
switchButton.setOnClickListener(v -> { | |||||
switchFragmentType(); | |||||
}); | }); | ||||
Log.d(DEBUG_TAG, "onCreateView"); | |||||
return root; | return root; | ||||
} | } | ||||
protected ArrayList<Stop> createStopListFromCursor(Cursor data){ | static ArrayList<Stop> createStopListFromCursor(Cursor data){ | ||||
ArrayList<Stop> stopList = new ArrayList<>(); | ArrayList<Stop> stopList = new ArrayList<>(); | ||||
final int col_id = data.getColumnIndex(StopsTable.COL_ID); | final int col_id = data.getColumnIndex(StopsTable.COL_ID); | ||||
final int latInd = data.getColumnIndex(StopsTable.COL_LAT); | final int latInd = data.getColumnIndex(StopsTable.COL_LAT); | ||||
final int lonInd = data.getColumnIndex(StopsTable.COL_LONG); | final int lonInd = data.getColumnIndex(StopsTable.COL_LONG); | ||||
final int nameindex = data.getColumnIndex(StopsTable.COL_NAME); | final int nameindex = data.getColumnIndex(StopsTable.COL_NAME); | ||||
final int typeIndex = data.getColumnIndex(StopsTable.COL_TYPE); | final int typeIndex = data.getColumnIndex(StopsTable.COL_TYPE); | ||||
final int linesIndex = data.getColumnIndex(StopsTable.COL_LINES_STOPPING); | final int linesIndex = data.getColumnIndex(StopsTable.COL_LINES_STOPPING); | ||||
Show All 30 Lines | private void setFragmentType(int type){ | ||||
case TYPE_STOPS: | case TYPE_STOPS: | ||||
TIME_INTERVAL_REQUESTS = 1000; | TIME_INTERVAL_REQUESTS = 1000; | ||||
} | } | ||||
} | } | ||||
@Override | @Override | ||||
public void onAttach(Context context) { | public void onAttach(@NonNull Context context) { | ||||
super.onAttach(context); | super.onAttach(context); | ||||
/// TODO: RISOLVERE PROBLEMA: il context qui e' l'Activity non il Fragment | /// TODO: RISOLVERE PROBLEMA: il context qui e' l'Activity non il Fragment | ||||
if (context instanceof FragmentListenerMain) { | if (context instanceof FragmentListenerMain) { | ||||
mListener = (FragmentListenerMain) context; | mListener = (FragmentListenerMain) context; | ||||
} else { | } else { | ||||
throw new RuntimeException(context | throw new RuntimeException(context | ||||
+ " must implement OnFragmentInteractionListener"); | + " must implement OnFragmentInteractionListener"); | ||||
} | } | ||||
Log.d(DEBUG_TAG, "OnAttach called"); | Log.d(DEBUG_TAG, "OnAttach called"); | ||||
} | } | ||||
@Override | @Override | ||||
public void onPause() { | public void onPause() { | ||||
super.onPause(); | super.onPause(); | ||||
canStartDBQuery = false; | |||||
gridRecyclerView.setAdapter(null); | gridRecyclerView.setAdapter(null); | ||||
locManager.removeLocationRequestFor(fragmentLocationListener); | locManager.removeLocationRequestFor(fragmentLocationListener); | ||||
Log.d(DEBUG_TAG,"On paused called"); | Log.d(DEBUG_TAG,"On paused called"); | ||||
} | } | ||||
@Override | @Override | ||||
public void onResume() { | public void onResume() { | ||||
super.onResume(); | super.onResume(); | ||||
canStartDBQuery = !globalSharedPref.getBoolean(getString(R.string.databaseUpdatingPref),false); | |||||
try{ | try{ | ||||
if(canStartDBQuery) locManager.addLocationRequestFor(fragmentLocationListener); | if(!dbUpdateRunning && !locManager.isRequesterRegistered(fragmentLocationListener)) | ||||
locManager.addLocationRequestFor(fragmentLocationListener); | |||||
} catch (SecurityException ex){ | } catch (SecurityException ex){ | ||||
//ignored | //ignored | ||||
//try another location provider | //try another location provider | ||||
} | } | ||||
switch(fragment_type){ | switch(fragment_type){ | ||||
case TYPE_STOPS: | case TYPE_STOPS: | ||||
if(dataAdapter!=null){ | if(dataAdapter!=null){ | ||||
gridRecyclerView.setAdapter(dataAdapter); | gridRecyclerView.setAdapter(dataAdapter); | ||||
▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | public void onDetach() { | ||||
mListener = null; | mListener = null; | ||||
if(arrivalsManager!=null) arrivalsManager.cancelAllRequests(); | if(arrivalsManager!=null) arrivalsManager.cancelAllRequests(); | ||||
} | } | ||||
@NonNull | @NonNull | ||||
@Override | @Override | ||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) { | public Loader<Cursor> onCreateLoader(int id, Bundle args) { | ||||
//BUILD URI | //BUILD URI | ||||
if (args!=null) | |||||
lastReceivedLocation = args.getParcelable(BUNDLE_LOCATION); | lastReceivedLocation = args.getParcelable(BUNDLE_LOCATION); | ||||
Uri.Builder builder = new Uri.Builder(); | Uri.Builder builder = new Uri.Builder(); | ||||
builder.scheme("content").authority(AppDataProvider.AUTHORITY) | builder.scheme("content").authority(AppDataProvider.AUTHORITY) | ||||
.appendPath("stops").appendPath("location") | .appendPath("stops").appendPath("location") | ||||
.appendPath(String.valueOf(lastReceivedLocation.getLatitude())) | .appendPath(String.valueOf(lastReceivedLocation.getLatitude())) | ||||
.appendPath(String.valueOf(lastReceivedLocation.getLongitude())) | .appendPath(String.valueOf(lastReceivedLocation.getLongitude())) | ||||
.appendPath(String.valueOf(distance)); //distance | .appendPath(String.valueOf(distance)); //distance | ||||
CursorLoader cl = new CursorLoader(getContext(),builder.build(),PROJECTION,null,null,null); | CursorLoader cl = new CursorLoader(getContext(),builder.build(),PROJECTION,null,null,null); | ||||
cl.setUpdateThrottle(2000); | cl.setUpdateThrottle(2000); | ||||
return cl; | return cl; | ||||
} | } | ||||
@Override | @Override | ||||
public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor cursor) { | public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor cursor) { | ||||
if (0 > MAX_DISTANCE) throw new AssertionError(); | if (0 > MAX_DISTANCE) throw new AssertionError(); | ||||
//Cursor might be null | //Cursor might be null | ||||
if(cursor==null){ | if (cursor == null) { | ||||
Log.e(DEBUG_TAG,"Null cursor, something really wrong happened"); | Log.e(DEBUG_TAG, "Null cursor, something really wrong happened"); | ||||
return; | return; | ||||
} | } | ||||
Log.d(DEBUG_TAG, "Num stops found: "+cursor.getCount()+", Current distance: "+distance); | Log.d(DEBUG_TAG, "Num stops found: " + cursor.getCount() + ", Current distance: " + distance); | ||||
if(!isDBUpdating() && (cursor.getCount()<MIN_NUM_STOPS && distance<=MAX_DISTANCE)){ | if (!dbUpdateRunning && (cursor.getCount() < MIN_NUM_STOPS && distance <= MAX_DISTANCE)) { | ||||
distance = distance*2; | distance = distance * 2; | ||||
Bundle d = new Bundle(); | Bundle d = new Bundle(); | ||||
d.putParcelable(BUNDLE_LOCATION,lastReceivedLocation); | d.putParcelable(BUNDLE_LOCATION, lastReceivedLocation); | ||||
getLoaderManager().restartLoader(LOADER_ID,d,this); | getLoaderManager().restartLoader(LOADER_ID, d, this); | ||||
//Log.d(DEBUG_TAG, "Doubling distance now!"); | //Log.d(DEBUG_TAG, "Doubling distance now!"); | ||||
return; | return; | ||||
} | } | ||||
Log.d("LoadFromCursor","Number of nearby stops: "+cursor.getCount()); | Log.d("LoadFromCursor", "Number of nearby stops: " + cursor.getCount()); | ||||
//////// | //////// | ||||
if(cursor.getCount()>0) | |||||
currentNearbyStops = createStopListFromCursor(cursor); | |||||
showCurrentStops(); | |||||
} | |||||
/** | |||||
* Display the stops, or run new set of requests for arrivals | |||||
*/ | |||||
private void showCurrentStops(){ | |||||
if (currentNearbyStops.isEmpty()) { | |||||
setNoStopsLayout(); | |||||
return; | |||||
} | |||||
if(cursor.getCount()>0) { | |||||
ArrayList<Stop> stopList = createStopListFromCursor(cursor); | |||||
double minDistance = Double.POSITIVE_INFINITY; | double minDistance = Double.POSITIVE_INFINITY; | ||||
for(Stop s: stopList){ | for(Stop s: currentNearbyStops){ | ||||
minDistance = Math.min(minDistance, s.getDistanceFromLocation(lastReceivedLocation)); | minDistance = Math.min(minDistance, s.getDistanceFromLocation(lastReceivedLocation)); | ||||
} | } | ||||
//quick trial to hopefully always get the stops in the correct order | //quick trial to hopefully always get the stops in the correct order | ||||
Collections.sort(stopList,new StopSorterByDistance(lastReceivedLocation)); | Collections.sort(currentNearbyStops,new StopSorterByDistance(lastReceivedLocation)); | ||||
switch (fragment_type){ | switch (fragment_type){ | ||||
case TYPE_STOPS: | case TYPE_STOPS: | ||||
showStopsInRecycler(stopList); | showStopsInRecycler(currentNearbyStops); | ||||
break; | break; | ||||
case TYPE_ARRIVALS: | case TYPE_ARRIVALS: | ||||
arrivalsManager = new ArrivalsManager(stopList); | arrivalsManager = new ArrivalsManager(currentNearbyStops); | ||||
flatProgressBar.setVisibility(View.VISIBLE); | flatProgressBar.setVisibility(View.VISIBLE); | ||||
flatProgressBar.setProgress(0); | flatProgressBar.setProgress(0); | ||||
flatProgressBar.setIndeterminate(false); | flatProgressBar.setIndeterminate(false); | ||||
//for the moment, be satisfied with only one location | //for the moment, be satisfied with only one location | ||||
//AppLocationManager.getInstance(getContext()).removeLocationRequestFor(fragmentLocationListener); | //AppLocationManager.getInstance(getContext()).removeLocationRequestFor(fragmentLocationListener); | ||||
break; | break; | ||||
default: | default: | ||||
} | } | ||||
} else { | |||||
setNoStopsLayout(); | |||||
} | |||||
} | } | ||||
@Override | @Override | ||||
public void onLoaderReset(@NonNull Loader<Cursor> loader) { | public void onLoaderReset(@NonNull Loader<Cursor> loader) { | ||||
} | } | ||||
/** | /** | ||||
* To enable targeting from the Button | * To enable targeting from the Button | ||||
Show All 18 Lines | private void switchFragmentType(){ | ||||
} else if (fragment_type==TYPE_STOPS){ | } else if (fragment_type==TYPE_STOPS){ | ||||
setFragmentType(TYPE_ARRIVALS); | setFragmentType(TYPE_ARRIVALS); | ||||
titleTextView.setText(getString(R.string.nearby_arrivals_message)); | titleTextView.setText(getString(R.string.nearby_arrivals_message)); | ||||
switchButton.setText(getString(R.string.show_stops)); | switchButton.setText(getString(R.string.show_stops)); | ||||
if(arrivalsStopAdapter!=null) | if(arrivalsStopAdapter!=null) | ||||
gridRecyclerView.setAdapter(arrivalsStopAdapter); | gridRecyclerView.setAdapter(arrivalsStopAdapter); | ||||
} | } | ||||
fragmentLocationListener.lastUpdateTime = -1; | fragmentLocationListener.lastUpdateTime = -1; | ||||
locManager.removeLocationRequestFor(fragmentLocationListener); | //locManager.removeLocationRequestFor(fragmentLocationListener); | ||||
locManager.addLocationRequestFor(fragmentLocationListener); | //locManager.addLocationRequestFor(fragmentLocationListener); | ||||
showCurrentStops(); | |||||
} | } | ||||
//useful methods | //useful methods | ||||
protected boolean isDBUpdating(){ | |||||
return globalSharedPref.getBoolean(getString(R.string.databaseUpdatingPref),false); | |||||
} | |||||
/////// GUI METHODS //////// | /////// GUI METHODS //////// | ||||
private void showStopsInRecycler(List<Stop> stops){ | private void showStopsInRecycler(List<Stop> stops){ | ||||
if(firstLocForStops) { | if(firstLocForStops) { | ||||
dataAdapter = new SquareStopAdapter(stops, mListener, lastReceivedLocation); | dataAdapter = new SquareStopAdapter(stops, mListener, lastReceivedLocation); | ||||
gridRecyclerView.setAdapter(dataAdapter); | gridRecyclerView.setAdapter(dataAdapter); | ||||
firstLocForStops = false; | firstLocForStops = false; | ||||
Show All 18 Lines | private void showArrivalsInRecycler(List<Palina> palinas){ | ||||
final ArrayList<Pair<Stop,Route>> routesPairList = new ArrayList<>(10); | final ArrayList<Pair<Stop,Route>> routesPairList = new ArrayList<>(10); | ||||
//int maxNum = Math.min(MAX_STOPS, stopList.size()); | //int maxNum = Math.min(MAX_STOPS, stopList.size()); | ||||
for(Palina p: palinas){ | for(Palina p: palinas){ | ||||
//if there are no routes available, skip stop | //if there are no routes available, skip stop | ||||
if(p.queryAllRoutes().size() == 0) continue; | if(p.queryAllRoutes().size() == 0) continue; | ||||
for(Route r: p.queryAllRoutes()){ | for(Route r: p.queryAllRoutes()){ | ||||
//if there are no routes, should not do anything | //if there are no routes, should not do anything | ||||
if (r.passaggi != null && !r.passaggi.isEmpty()) | |||||
routesPairList.add(new Pair<>(p,r)); | routesPairList.add(new Pair<>(p,r)); | ||||
} | } | ||||
} | } | ||||
if (getContext()==null){ | if (getContext()==null){ | ||||
Log.e(DEBUG_TAG, "Trying to show arrivals in Recycler but we're not attached"); | Log.e(DEBUG_TAG, "Trying to show arrivals in Recycler but we're not attached"); | ||||
return; | return; | ||||
} | } | ||||
if(firstLocForArrivals){ | if(firstLocForArrivals){ | ||||
arrivalsStopAdapter = new ArrivalsStopAdapter(routesPairList,mListener,getContext(),lastReceivedLocation); | arrivalsStopAdapter = new ArrivalsStopAdapter(routesPairList,mListener,getContext(),lastReceivedLocation); | ||||
Show All 22 Lines | public class NearbyStopsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { | ||||
private void showRecyclerHidingLoadMessage(){ | private void showRecyclerHidingLoadMessage(){ | ||||
if (gridRecyclerView.getVisibility() != View.VISIBLE) { | if (gridRecyclerView.getVisibility() != View.VISIBLE) { | ||||
circlingProgressBar.setVisibility(View.GONE); | circlingProgressBar.setVisibility(View.GONE); | ||||
gridRecyclerView.setVisibility(View.VISIBLE); | gridRecyclerView.setVisibility(View.VISIBLE); | ||||
} | } | ||||
messageTextView.setVisibility(View.GONE); | messageTextView.setVisibility(View.GONE); | ||||
} | } | ||||
class ArrivalsManager implements FiveTAPIVolleyRequest.ResponseListener, Response.ErrorListener{ | class ArrivalsManager implements Response.Listener<Palina>, Response.ErrorListener{ | ||||
final HashMap<String,Palina> mStops; | final HashMap<String,Palina> palinasDone = new HashMap<>(); | ||||
final Map<String,List<Route>> routesToAdd = new HashMap<>(); | //final Map<String,List<Route>> routesToAdd = new HashMap<>(); | ||||
final static String REQUEST_TAG = "NearbyArrivals"; | final static String REQUEST_TAG = "NearbyArrivals"; | ||||
private final QueryType[] types = {QueryType.ARRIVALS,QueryType.DETAILS}; | |||||
final NetworkVolleyManager volleyManager; | final NetworkVolleyManager volleyManager; | ||||
int activeRequestCount = 0,reqErrorCount = 0, reqSuccessCount=0; | int activeRequestCount = 0,reqErrorCount = 0, reqSuccessCount=0; | ||||
ArrivalsManager(List<Stop> stops){ | ArrivalsManager(List<Stop> stops){ | ||||
mStops = new HashMap<>(); | |||||
volleyManager = NetworkVolleyManager.getInstance(getContext()); | volleyManager = NetworkVolleyManager.getInstance(getContext()); | ||||
int MAX_ARRIVAL_STOPS = 35; | int MAX_ARRIVAL_STOPS = 35; | ||||
Date currentDate = new Date(); | |||||
int timeRange = 3600; | |||||
int departures = 10; | |||||
int numreq = 0; | |||||
for(Stop s: stops.subList(0,Math.min(stops.size(), MAX_ARRIVAL_STOPS))){ | for(Stop s: stops.subList(0,Math.min(stops.size(), MAX_ARRIVAL_STOPS))){ | ||||
mStops.put(s.ID,new Palina(s)); | |||||
for(QueryType t: types) { | final MapiArrivalRequest req = new MapiArrivalRequest(s.ID, currentDate, timeRange, departures, this, this); | ||||
final FiveTAPIVolleyRequest req = FiveTAPIVolleyRequest.getNewRequest(t, s.ID, this, this); | |||||
if (req != null) { | |||||
req.setTag(REQUEST_TAG); | req.setTag(REQUEST_TAG); | ||||
volleyManager.addToRequestQueue(req); | volleyManager.addToRequestQueue(req); | ||||
activeRequestCount++; | activeRequestCount++; | ||||
numreq++; | |||||
} | } | ||||
} | flatProgressBar.setMax(numreq); | ||||
} | |||||
flatProgressBar.setMax(activeRequestCount); | |||||
} | } | ||||
@Override | @Override | ||||
public void onErrorResponse(VolleyError error) { | public void onErrorResponse(VolleyError error) { | ||||
if(error instanceof ParseError){ | if(error instanceof ParseError){ | ||||
//TODO | //TODO | ||||
Show All 12 Lines | class ArrivalsManager implements Response.Listener<Palina>, Response.ErrorListener{ | ||||
} | } | ||||
//counters | //counters | ||||
activeRequestCount--; | activeRequestCount--; | ||||
reqErrorCount++; | reqErrorCount++; | ||||
flatProgressBar.setProgress(reqErrorCount+reqSuccessCount); | flatProgressBar.setProgress(reqErrorCount+reqSuccessCount); | ||||
} | } | ||||
@Override | @Override | ||||
public void onResponse(Palina result, QueryType type) { | public void onResponse(Palina result) { | ||||
//counter for requests | //counter for requests | ||||
activeRequestCount--; | activeRequestCount--; | ||||
reqSuccessCount++; | reqSuccessCount++; | ||||
//final Palina palinaInMap = palinasDone.get(result.ID); | |||||
final Palina palinaInMap = mStops.get(result.ID); | |||||
//palina cannot be null here | //palina cannot be null here | ||||
//sorry for the brutal crash when it happens | //sorry for the brutal crash when it happens | ||||
if(palinaInMap == null) throw new IllegalStateException("Cannot get the palina from the map"); | //if(palinaInMap == null) throw new IllegalStateException("Cannot get the palina from the map"); | ||||
//necessary to split the Arrivals and Details cases | //add the palina to the successful one | ||||
switch (type){ | //TODO: Avoid redoing everything every time a new Result arrives | ||||
case ARRIVALS: | palinasDone.put(result.ID, result); | ||||
palinaInMap.addInfoFromRoutes(result.queryAllRoutes()); | |||||
final List<Route> possibleRoutes = routesToAdd.get(result.ID); | |||||
if(possibleRoutes!=null) { | |||||
palinaInMap.addInfoFromRoutes(possibleRoutes); | |||||
routesToAdd.remove(result.ID); | |||||
} | |||||
break; | |||||
case DETAILS: | |||||
if(palinaInMap.queryAllRoutes().size()>0){ | |||||
//merge the branches | |||||
palinaInMap.addInfoFromRoutes(result.queryAllRoutes()); | |||||
} else { | |||||
routesToAdd.put(result.ID,result.queryAllRoutes()); | |||||
} | |||||
break; | |||||
default: | |||||
throw new IllegalArgumentException("Wrong QueryType in onResponse"); | |||||
} | |||||
final ArrayList<Palina> outList = new ArrayList<>(); | final ArrayList<Palina> outList = new ArrayList<>(); | ||||
for(Palina p: mStops.values()){ | for(Palina p: palinasDone.values()){ | ||||
final List<Route> routes = p.queryAllRoutes(); | final List<Route> routes = p.queryAllRoutes(); | ||||
if(routes!=null && routes.size()>0) outList.add(p); | if(routes!=null && routes.size()>0) outList.add(p); | ||||
} | } | ||||
showArrivalsInRecycler(outList); | showArrivalsInRecycler(outList); | ||||
flatProgressBar.setProgress(reqErrorCount+reqSuccessCount); | flatProgressBar.setProgress(reqErrorCount+reqSuccessCount); | ||||
if(activeRequestCount==0) { | if(activeRequestCount==0) { | ||||
flatProgressBar.setIndeterminate(true); | flatProgressBar.setIndeterminate(true); | ||||
flatProgressBar.setVisibility(View.GONE); | flatProgressBar.setVisibility(View.GONE); | ||||
Show All 17 Lines | class FragmentLocationListener implements AppLocationManager.LocationRequester{ | ||||
public FragmentLocationListener(LoaderManager.LoaderCallbacks<Cursor> callbacks) { | public FragmentLocationListener(LoaderManager.LoaderCallbacks<Cursor> callbacks) { | ||||
this.callbacks = callbacks; | this.callbacks = callbacks; | ||||
} | } | ||||
@Override | @Override | ||||
public void onLocationChanged(Location location) { | public void onLocationChanged(Location location) { | ||||
//set adapter | //set adapter | ||||
float accuracy = location.getAccuracy(); | float accuracy = location.getAccuracy(); | ||||
if(accuracy<60 && canStartDBQuery) { | if(accuracy<60 && !dbUpdateRunning) { | ||||
distance = 20; | distance = 20; | ||||
final Bundle msgBundle = new Bundle(); | final Bundle msgBundle = new Bundle(); | ||||
msgBundle.putParcelable(BUNDLE_LOCATION,location); | msgBundle.putParcelable(BUNDLE_LOCATION,location); | ||||
getLoaderManager().restartLoader(LOADER_ID,msgBundle,callbacks); | getLoaderManager().restartLoader(LOADER_ID,msgBundle,callbacks); | ||||
} | } | ||||
lastUpdateTime = System.currentTimeMillis(); | lastUpdateTime = System.currentTimeMillis(); | ||||
Log.d("BusTO:NearPositListen","can start loader "+ canStartDBQuery); | Log.d("BusTO:NearPositListen","can start loader "+ !dbUpdateRunning); | ||||
} | } | ||||
@Override | @Override | ||||
public void onLocationStatusChanged(int status) { | public void onLocationStatusChanged(int status) { | ||||
switch(status){ | switch(status){ | ||||
case AppLocationManager.LOCATION_GPS_AVAILABLE: | case AppLocationManager.LOCATION_GPS_AVAILABLE: | ||||
messageTextView.setVisibility(View.GONE); | messageTextView.setVisibility(View.GONE); | ||||
▲ Show 20 Lines • Show All 74 Lines • Show Last 20 Lines |
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