Changeset View
Changeset View
Standalone View
Standalone View
src/it/reyboz/bustorino/fragments/NearbyStopsFragment.java
| Show All 38 Lines | |||||
| 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.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.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; | ||||
| ▲ Show 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | public class NearbyStopsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { | ||||
| @Override | @Override | ||||
| public void onAttach(Context context) { | public void onAttach(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.toString() | 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(); | ||||
| Show All 25 Lines | public void onResume() { | ||||
| if(arrivalsStopAdapter!=null){ | if(arrivalsStopAdapter!=null){ | ||||
| gridRecyclerView.setAdapter(arrivalsStopAdapter); | gridRecyclerView.setAdapter(arrivalsStopAdapter); | ||||
| circlingProgressBar.setVisibility(View.GONE); | circlingProgressBar.setVisibility(View.GONE); | ||||
| } | } | ||||
| } | } | ||||
| mListener.enableRefreshLayout(false); | mListener.enableRefreshLayout(false); | ||||
| Log.d(DEBUG_TAG,"OnResume called"); | 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 | //Re-read preferences | ||||
| SharedPreferences shpr = PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext()); | SharedPreferences shpr = PreferenceManager.getDefaultSharedPreferences(getContext().getApplicationContext()); | ||||
| //For some reason, they are all saved as strings | //For some reason, they are all saved as strings | ||||
| MAX_DISTANCE = shpr.getInt(getString(R.string.pref_key_radius_recents),600); | 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); | |||||
| } | } | ||||
| @Override | @Override | ||||
| public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { | ||||
| super.onViewCreated(view, savedInstanceState); | super.onViewCreated(view, savedInstanceState); | ||||
| gridRecyclerView.setVisibility(View.INVISIBLE); | gridRecyclerView.setVisibility(View.INVISIBLE); | ||||
| gridRecyclerView.addOnScrollListener(scrollListener); | gridRecyclerView.addOnScrollListener(scrollListener); | ||||
| Show All 22 Lines | public Loader<Cursor> onCreateLoader(int id, Bundle args) { | ||||
| return cl; | return cl; | ||||
| } | } | ||||
| @Override | @Override | ||||
| public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) { | public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor data) { | ||||
| if (0 > MAX_DISTANCE) throw new AssertionError(); | if (0 > MAX_DISTANCE) throw new AssertionError(); | ||||
| //Cursor might be null | //Cursor might be null | ||||
| Log.d(DEBUG_TAG, "Num stops found: "+data.getCount()+", Current distance: "+distance); | |||||
| if(data==null){ | if(data==null){ | ||||
| Log.e(DEBUG_TAG,"Null cursor, something really wrong happened"); | Log.e(DEBUG_TAG,"Null cursor, something really wrong happened"); | ||||
| return; | return; | ||||
| } | } | ||||
| if(!isDBUpdating() && (data.getCount()<MIN_NUM_STOPS || distance<=MAX_DISTANCE)){ | if(!isDBUpdating() && (data.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!"); | |||||
| return; | return; | ||||
| } | } | ||||
| Log.d("LoadFromCursor","Number of nearby stops: "+data.getCount()); | Log.d("LoadFromCursor","Number of nearby stops: "+data.getCount()); | ||||
| //////// | //////// | ||||
| ArrayList<Stop> stopList = createStopListFromCursor(data); | |||||
| if(data.getCount()>0) { | if(data.getCount()>0) { | ||||
| ArrayList<Stop> 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 | //quick trial to hopefully always get the stops in the correct order | ||||
| Collections.sort(stopList,new StopSorterByDistance(lastReceivedLocation)); | Collections.sort(stopList,new StopSorterByDistance(lastReceivedLocation)); | ||||
| switch (fragment_type){ | switch (fragment_type){ | ||||
| case TYPE_STOPS: | case TYPE_STOPS: | ||||
| showStopsInRecycler(stopList); | showStopsInRecycler(stopList); | ||||
| break; | break; | ||||
| case TYPE_ARRIVALS: | case TYPE_ARRIVALS: | ||||
| arrivalsManager = new ArrivalsManager(stopList); | arrivalsManager = new ArrivalsManager(stopList); | ||||
| 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 { | } else { | ||||
| setNoStopsLayout(); | setNoStopsLayout(); | ||||
| } | } | ||||
| } | } | ||||
| @Override | @Override | ||||
| public void onLoaderReset(Loader<Cursor> loader) { | public void onLoaderReset(@NonNull Loader<Cursor> loader) { | ||||
| } | } | ||||
| /** | /** | ||||
| * To enable targeting from the Button | * To enable targeting from the Button | ||||
| */ | */ | ||||
| public void switchFragmentType(View v){ | public void switchFragmentType(View v){ | ||||
| switchFragmentType(); | switchFragmentType(); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | private void showArrivalsInRecycler(List<Palina> palinas){ | ||||
| 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 | ||||
| routesPairList.add(new Pair<>(p,r)); | 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){ | if(firstLocForArrivals){ | ||||
| arrivalsStopAdapter = new ArrivalsStopAdapter(routesPairList,mListener,getContext(),lastReceivedLocation); | arrivalsStopAdapter = new ArrivalsStopAdapter(routesPairList,mListener,getContext(),lastReceivedLocation); | ||||
| gridRecyclerView.setAdapter(arrivalsStopAdapter); | gridRecyclerView.setAdapter(arrivalsStopAdapter); | ||||
| firstLocForArrivals = false; | firstLocForArrivals = false; | ||||
| } else { | } else { | ||||
| arrivalsStopAdapter.setRoutesPairListAndPosition(routesPairList,lastReceivedLocation); | arrivalsStopAdapter.setRoutesPairListAndPosition(routesPairList,lastReceivedLocation); | ||||
| } | } | ||||
| Show All 22 Lines | public class NearbyStopsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { | ||||
| } | } | ||||
| class ArrivalsManager implements FiveTAPIVolleyRequest.ResponseListener, Response.ErrorListener{ | class ArrivalsManager implements FiveTAPIVolleyRequest.ResponseListener, Response.ErrorListener{ | ||||
| final HashMap<String,Palina> mStops; | final HashMap<String,Palina> mStops; | ||||
| 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}; | private final QueryType[] types = {QueryType.ARRIVALS,QueryType.DETAILS}; | ||||
| final NetworkVolleyManager volleyManager; | final NetworkVolleyManager volleyManager; | ||||
| private final int MAX_ARRIVAL_STOPS =35; | |||||
| 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<>(); | mStops = new HashMap<>(); | ||||
| volleyManager = NetworkVolleyManager.getInstance(getContext()); | volleyManager = NetworkVolleyManager.getInstance(getContext()); | ||||
| int MAX_ARRIVAL_STOPS = 35; | |||||
| 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)); | mStops.put(s.ID,new Palina(s)); | ||||
| for(QueryType t: types) { | for(QueryType t: types) { | ||||
| final FiveTAPIVolleyRequest req = FiveTAPIVolleyRequest.getNewRequest(t, s.ID, this, this); | final FiveTAPIVolleyRequest req = FiveTAPIVolleyRequest.getNewRequest(t, s.ID, this, this); | ||||
| if (req != null) { | if (req != null) { | ||||
| req.setTag(REQUEST_TAG); | req.setTag(REQUEST_TAG); | ||||
| volleyManager.addToRequestQueue(req); | volleyManager.addToRequestQueue(req); | ||||
| activeRequestCount++; | activeRequestCount++; | ||||
| ▲ Show 20 Lines • Show All 106 Lines • ▼ Show 20 Lines | class FragmentLocationListener implements AppLocationManager.LocationRequester{ | ||||
| Log.d("BusTO:NearPositListen","can start loader "+ canStartDBQuery); | Log.d("BusTO:NearPositListen","can start loader "+ canStartDBQuery); | ||||
| } | } | ||||
| @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); | ||||
| break; | break; | ||||
| case AppLocationManager.LOCATION_UNAVAILABLE: | case AppLocationManager.LOCATION_UNAVAILABLE: | ||||
| messageTextView.setText(R.string.enableGpsText); | messageTextView.setText(R.string.enableGpsText); | ||||
| messageTextView.setVisibility(View.VISIBLE); | messageTextView.setVisibility(View.VISIBLE); | ||||
| break; | break; | ||||
| default: | default: | ||||
| Log.e(DEBUG_TAG,"Location status not recognized"); | Log.e(DEBUG_TAG,"Location status not recognized"); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 66 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