diff --git a/build.gradle b/build.gradle --- a/build.gradle +++ b/build.gradle @@ -12,9 +12,9 @@ } ext { //libraries versions - fragment_version = "1.3.3" - activity_version = "1.1.0" - appcompat_version = "1.2.0" + fragment_version = "1.3.6" + activity_version = "1.2.4" + appcompat_version = "1.3.1" preference_version = "1.1.1" work_version = "2.5.0" diff --git a/src/it/reyboz/bustorino/ActivityMain.java b/src/it/reyboz/bustorino/ActivityMain.java --- a/src/it/reyboz/bustorino/ActivityMain.java +++ b/src/it/reyboz/bustorino/ActivityMain.java @@ -783,6 +783,13 @@ } } + @Override + public void showMapCenteredOnStop(Stop stop) { + //nothing to do + //TODO: delete this activity altogether + Log.w(DEBUG_TAG,"Asked to show the stop on the map"); + } + private void prepareGUIForBusLines() { swipeRefreshLayout.setEnabled(true); swipeRefreshLayout.setVisibility(View.VISIBLE); 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 @@ -527,6 +527,11 @@ } } + @Override + public void showMapCenteredOnStop(Stop stop) { + createAndShowMapFragment(stop); + } + //Map Fragment stuff void createAndShowMapFragment(@Nullable Stop stop){ FragmentManager fm = getSupportFragmentManager(); diff --git a/src/it/reyboz/bustorino/backend/utils.java b/src/it/reyboz/bustorino/backend/utils.java --- a/src/it/reyboz/bustorino/backend/utils.java +++ b/src/it/reyboz/bustorino/backend/utils.java @@ -29,6 +29,9 @@ return Math.abs(EarthRadius*c); } + public static Double angleRawDifferenceFromMeters(double distanceInMeters){ + return Math.toDegrees(distanceInMeters/EarthRadius); + } /* public static int convertDipToPixels(Context con,float dips) { diff --git a/src/it/reyboz/bustorino/data/AppDataProvider.java b/src/it/reyboz/bustorino/data/AppDataProvider.java --- a/src/it/reyboz/bustorino/data/AppDataProvider.java +++ b/src/it/reyboz/bustorino/data/AppDataProvider.java @@ -220,9 +220,9 @@ Double latitude = Double.parseDouble(parts.get(2)); Double longitude = Double.parseDouble(parts.get(3)); //converting distance to a float to not lose precision - float distance = parts.size()>=5 ? Float.parseFloat(parts.get(4))/1000 : 0.1f; - if(parts.size()>=5) - Log.d("LocationSearch"," given distance to search is "+parts.get(4)+" m"); + float distance = parts.size()>=5 ? Float.parseFloat(parts.get(4))/1000 : 0.02f; + //if(parts.size()>=5) + //Log.d("LocationSearch"," given distance to search is "+parts.get(4)+" m"); Double distasAngle = (distance/6371)*180/Math.PI; //small angles approximation, still valid for about 500 metres String whereClause = StopsTable.COL_LAT+ "< "+(latitude+distasAngle)+" AND " diff --git a/src/it/reyboz/bustorino/data/FavoritesLiveData.java b/src/it/reyboz/bustorino/data/FavoritesLiveData.java --- a/src/it/reyboz/bustorino/data/FavoritesLiveData.java +++ b/src/it/reyboz/bustorino/data/FavoritesLiveData.java @@ -1,35 +1,27 @@ package it.reyboz.bustorino.data; -import android.annotation.SuppressLint; -import android.content.AsyncQueryHandler; + import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; -import android.os.AsyncTask; import android.os.Handler; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.core.content.ContentResolverCompat; -import androidx.core.os.CancellationSignal; -import androidx.core.os.OperationCanceledException; + import androidx.lifecycle.LiveData; -import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.List; -import it.reyboz.bustorino.backend.Route; +import it.reyboz.bustorino.BuildConfig; import it.reyboz.bustorino.backend.Stop; -import it.reyboz.bustorino.data.NextGenDB.Contract.*; - public class FavoritesLiveData extends LiveData> implements CustomAsyncQueryHandler.AsyncQueryListener { private static final String TAG = "FavoritesLiveData"; private final boolean notifyChangesDescendants; @@ -47,7 +39,7 @@ AppDataProvider.FAVORITES).build(); - private final int FAV_TOKEN = 23, STOPS_TOKEN_BASE=90; + private final int FAV_TOKEN = 23, STOPS_TOKEN_BASE=220; @Nullable @@ -95,16 +87,10 @@ @Override protected void onActive() { - Log.d(TAG, "onActive()"); + //Log.d(TAG, "onActive()"); loadData(); } - @Override - protected void onInactive() { - Log.d(TAG, "onInactive()"); - - } - /** * Clear the data for the cursor */ @@ -118,6 +104,8 @@ @Override protected void setValue(List stops) { + //Log.d("BusTO-FavoritesLiveData","Setting the new values for the stops, have "+ + // stops.size()+" stops"); ContentResolver resolver = mContext.getContentResolver(); resolver.registerContentObserver(FAVORITES_URI, notifyChangesDescendants,mObserver); @@ -130,14 +118,20 @@ if (token == FAV_TOKEN) { stopsFromFavorites = UserDB.getFavoritesFromCursor(cursor, UserDB.getFavoritesColumnNamesAsArray); cursor.close(); - - for (int i = 0; i < stopsFromFavorites.size(); i++) { - Stop s = stopsFromFavorites.get(i); - queryHandler.startQuery(STOPS_TOKEN_BASE + i, null, getStopsBuilder().appendPath(s.ID).build(), - NextGenDB.QUERY_COLUMN_stops_all, null, null, null); - } + //reset counters stopNeededCount = stopsFromFavorites.size(); stopsDone = new ArrayList<>(); + if(stopsFromFavorites.size() == 0){ + //we don't need to call the other query + setValue(stopsDone); + } else + for (int i = 0; i < stopsFromFavorites.size(); i++) { + Stop s = stopsFromFavorites.get(i); + queryHandler.startQuery(STOPS_TOKEN_BASE + i, null, + getStopsBuilder().appendPath(s.ID).build(), + NextGenDB.QUERY_COLUMN_stops_all, null, null, null); + } + } else if(token >= STOPS_TOKEN_BASE){ @@ -151,9 +145,11 @@ if (result.size() < 1){ // stop is not in the DB finalStop = stopUpdate; - } else{ + } else { finalStop = result.get(0); - assert (finalStop.ID.equals(stopUpdate.ID)); + if (BuildConfig.DEBUG && !(finalStop.ID.equals(stopUpdate.ID))) { + throw new AssertionError("Assertion failed"); + } finalStop.setStopUserName(stopUpdate.getStopUserName()); } if (stopsDone!=null) diff --git a/src/it/reyboz/bustorino/fragments/CommonFragmentListener.java b/src/it/reyboz/bustorino/fragments/CommonFragmentListener.java --- a/src/it/reyboz/bustorino/fragments/CommonFragmentListener.java +++ b/src/it/reyboz/bustorino/fragments/CommonFragmentListener.java @@ -1,6 +1,8 @@ package it.reyboz.bustorino.fragments; +import android.location.Location; import android.view.View; +import it.reyboz.bustorino.backend.Stop; public interface CommonFragmentListener { @@ -28,4 +30,11 @@ * Method to call when we want to hide the keyboard */ void hideKeyboard(); + + /** + * We want to open the map on the specified stop + * @param stop needs to have location data (latitude, longitude) + */ + void showMapCenteredOnStop(Stop stop); + } diff --git a/src/it/reyboz/bustorino/fragments/FavoritesFragment.java b/src/it/reyboz/bustorino/fragments/FavoritesFragment.java --- a/src/it/reyboz/bustorino/fragments/FavoritesFragment.java +++ b/src/it/reyboz/bustorino/fragments/FavoritesFragment.java @@ -3,9 +3,8 @@ import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; -import android.content.Intent; import android.os.Bundle; -import android.os.Handler; +import android.util.Log; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.MenuInflater; @@ -26,14 +25,10 @@ import java.util.ArrayList; import java.util.List; -import it.reyboz.bustorino.ActivityFavorites; -import it.reyboz.bustorino.ActivityMain; -import it.reyboz.bustorino.ActivityMap; -import it.reyboz.bustorino.R; +import it.reyboz.bustorino.*; import it.reyboz.bustorino.adapters.StopAdapter; import it.reyboz.bustorino.backend.Stop; import it.reyboz.bustorino.data.FavoritesViewModel; -import it.reyboz.bustorino.data.UserDB; import it.reyboz.bustorino.middleware.AsyncStopFavoriteAction; public class FavoritesFragment extends BaseFragment { @@ -155,33 +150,16 @@ showBusStopUsernameInputDialog(busStop); return true; case R.id.action_view_on_map: - final String theGeoUrl = busStop.getGeoURL(); - /* - if(theGeoUrl==null){ - //doesn't have a position - Toast.makeText(getContext(),R.string.cannot_show_on_map_no_position,Toast.LENGTH_SHORT).show(); + if (busStop.getLatitude() == null | busStop.getLongitude() == null | + mListener==null + ) { + Toast.makeText(getContext(), R.string.cannot_show_on_map_no_position, Toast.LENGTH_SHORT).show(); return true; } - // start ActivityMap with these extras in intent - Intent intent = new Intent(getContext(), ActivityMap.class); - Bundle b = new Bundle(); - double lat, lon; - if (busStop.getLatitude()!=null) - lat = busStop.getLatitude(); - else lat = 200; - if (busStop.getLongitude()!=null) - lon = busStop.getLongitude(); - else lon = 200; - b.putDouble("lat", lat); - b.putDouble("lon",lon); - b.putString("name", busStop.getStopDefaultName()); - b.putString("ID", busStop.ID); - intent.putExtras(b); - - startActivity(intent); - TODO: start map on button press - */ + //GeoPoint point = new GeoPoint(busStop.getLatitude(), busStop.getLongitude()); + + mListener.showMapCenteredOnStop(busStop); return true; default: return super.onContextItemSelected(item); @@ -191,7 +169,8 @@ void showStops(List busStops){ // If no data is found show a friendly message - + if(BuildConfig.DEBUG) + Log.d("BusTO - Favorites", "We have "+busStops.size()+" favorites in the list"); if (busStops.size() == 0) { favoriteListView.setVisibility(View.INVISIBLE); // TextView favoriteTipTextView = (TextView) findViewById(R.id.favoriteTipTextView); @@ -213,7 +192,6 @@ * reason. It would probably end up as "slow" as throwing away the old ListView and * redrwaing everything. */ - // Show results favoriteListView.setAdapter(new StopAdapter(getContext(), busStops)); } diff --git a/src/it/reyboz/bustorino/fragments/FragmentHelper.java b/src/it/reyboz/bustorino/fragments/FragmentHelper.java --- a/src/it/reyboz/bustorino/fragments/FragmentHelper.java +++ b/src/it/reyboz/bustorino/fragments/FragmentHelper.java @@ -171,6 +171,8 @@ * @param parameters attach parameters */ protected void attachFragmentToContainer(FragmentManager fm,Fragment fragment, AttachParameters parameters){ + if(shouldHaltAllActivities) //nothing to do + return; FragmentTransaction ft = fm.beginTransaction(); int frameID; if(parameters.attachToSecondaryFrame && secondaryFrameLayout!=NO_FRAME) @@ -185,12 +187,12 @@ if (parameters.addToBackStack) ft.addToBackStack("state_"+parameters.tag); ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_CLOSE); - if(!fm.isDestroyed()) + if(!fm.isDestroyed() && !shouldHaltAllActivities) ft.commit(); //fm.executePendingTransactions(); } - public void setBlockAllActivities(boolean shouldI) { + public synchronized void setBlockAllActivities(boolean shouldI) { this.shouldHaltAllActivities = shouldI; } @@ -198,7 +200,7 @@ if(lastTaskRef == null) return; AsyncDataDownload task = lastTaskRef.get(); if(task!=null){ - task.cancel(true); + task.cancel(false); } } diff --git a/src/it/reyboz/bustorino/fragments/FragmentListenerMain.java b/src/it/reyboz/bustorino/fragments/FragmentListenerMain.java --- a/src/it/reyboz/bustorino/fragments/FragmentListenerMain.java +++ b/src/it/reyboz/bustorino/fragments/FragmentListenerMain.java @@ -17,14 +17,10 @@ */ package it.reyboz.bustorino.fragments; -import it.reyboz.bustorino.backend.Stop; - public interface FragmentListenerMain extends CommonFragmentListener { void toggleSpinner(boolean state); - //TODO: implement void showStopOnMap() - /** * Tell activity that we need to enable/disable the refreshLayout * @param yes or no 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 @@ -42,14 +42,7 @@ import java.util.Map; import it.reyboz.bustorino.R; -import it.reyboz.bustorino.backend.ArrivalsFetcher; -import it.reyboz.bustorino.backend.FiveTAPIFetcher; -import it.reyboz.bustorino.backend.FiveTScraperFetcher; -import it.reyboz.bustorino.backend.FiveTStopsFetcher; -import it.reyboz.bustorino.backend.GTTJSONFetcher; -import it.reyboz.bustorino.backend.GTTStopsFetcher; -import it.reyboz.bustorino.backend.Palina; -import it.reyboz.bustorino.backend.StopsFinderByName; +import it.reyboz.bustorino.backend.*; import it.reyboz.bustorino.middleware.AppLocationManager; import it.reyboz.bustorino.middleware.AsyncDataDownload; import it.reyboz.bustorino.util.LocationCriteria; @@ -307,6 +300,7 @@ Fragment fragment = getChildFragmentManager().findFragmentById(R.id.resultFrame); if (fragment!=null) getChildFragmentManager().putFragment(outState, SAVED_FRAGMENT, fragment); + fragmentHelper.setBlockAllActivities(true); } public void setSuppressArrivalsReload(boolean value){ @@ -400,6 +394,8 @@ pendingStopID = null; } mListener.readyGUIfor(FragmentKind.MAIN_SCREEN_FRAGMENT); + + fragmentHelper.setBlockAllActivities(false); } @Override @@ -407,6 +403,8 @@ //mainHandler = null; locationManager.removeLocationRequestFor(requester); super.onPause(); + fragmentHelper.setBlockAllActivities(true); + fragmentHelper.stopLastRequestIfNeeded(); } /* @@ -594,6 +592,11 @@ } + @Override + public void showMapCenteredOnStop(Stop stop) { + if(mListener!=null) mListener.showMapCenteredOnStop(stop); + } + /** * Main method for stops requests * @param ID the Stop ID diff --git a/src/it/reyboz/bustorino/fragments/MapFragment.java b/src/it/reyboz/bustorino/fragments/MapFragment.java --- a/src/it/reyboz/bustorino/fragments/MapFragment.java +++ b/src/it/reyboz/bustorino/fragments/MapFragment.java @@ -23,6 +23,7 @@ import androidx.core.content.res.ResourcesCompat; import androidx.preference.PreferenceManager; +import it.reyboz.bustorino.backend.utils; import org.osmdroid.api.IGeoPoint; import org.osmdroid.api.IMapController; import org.osmdroid.config.Configuration; @@ -40,10 +41,7 @@ import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider; import java.lang.ref.WeakReference; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.util.*; import it.reyboz.bustorino.R; import it.reyboz.bustorino.backend.Stop; @@ -72,6 +70,7 @@ private static final double DEFAULT_CENTER_LAT = 45.0708; private static final double DEFAULT_CENTER_LON = 7.6858; private static final double POSITION_FOUND_ZOOM = 18.3; + public static final double NO_POSITION_ZOOM = 17.1; private static final String DEBUG_TAG=FRAGMENT_TAG; @@ -395,9 +394,14 @@ map); // set the center point if (marker != null) { - startPoint = marker; + //startPoint = marker; mapController.setZoom(POSITION_FOUND_ZOOM); setLocationFollowing(false); + // put the center a little bit off (animate later) + startPoint = new GeoPoint(marker); + startPoint.setLatitude(marker.getLatitude()+ utils.angleRawDifferenceFromMeters(20)); + startPoint.setLongitude(marker.getLongitude()-utils.angleRawDifferenceFromMeters(20)); + //don't need to do all the rest since we want to show a point } else if (savedInstanceState != null && savedInstanceState.containsKey(MAP_CURRENT_ZOOM_KEY)) { mapController.setZoom(savedInstanceState.getDouble(MAP_CURRENT_ZOOM_KEY)); mapController.setCenter(new GeoPoint(savedInstanceState.getDouble(MAP_CENTER_LAT_KEY), @@ -423,7 +427,7 @@ } if(!found){ startPoint = new GeoPoint(DEFAULT_CENTER_LAT, DEFAULT_CENTER_LON); - mapController.setZoom(17.0); + mapController.setZoom(NO_POSITION_ZOOM); setLocationFollowing(false); } } @@ -431,6 +435,7 @@ // set the minimum zoom level map.setMinZoomLevel(15.0); //add contingency check (shouldn't happen..., but) + if (startPoint != null) { mapController.setCenter(startPoint); } @@ -446,7 +451,8 @@ //requestStopsToShow(); if (marker != null) { // make a marker with the info window open for the searched marker - makeMarker(startPoint, name , ID, true); + Marker stopMarker = makeMarker(marker, name , ID, true); + map.getController().animateTo(marker); } } @@ -523,7 +529,6 @@ marker.setOnMarkerClickListener((thisMarker, mapView) -> { if (thisMarker.isInfoWindowOpen()) { // on second click - //TODO: show the arrivals for the stop Log.w(DEBUG_TAG, "Pressed on the click marker"); } else { // on first click @@ -554,6 +559,7 @@ // show popup info window of the searched marker if (isStartMarker) { marker.showInfoWindow(); + //map.getController().animateTo(marker.getPosition()); } return marker; 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 @@ -271,8 +271,8 @@ //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),1000); - MIN_NUM_STOPS = Integer.parseInt(shpr.getString(getString(R.string.pref_key_num_recents),"12")); + 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")); } diff --git a/src/it/reyboz/bustorino/middleware/AsyncStopFavoriteAction.java b/src/it/reyboz/bustorino/middleware/AsyncStopFavoriteAction.java --- a/src/it/reyboz/bustorino/middleware/AsyncStopFavoriteAction.java +++ b/src/it/reyboz/bustorino/middleware/AsyncStopFavoriteAction.java @@ -22,6 +22,7 @@ import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.os.AsyncTask; +import android.util.Log; import android.widget.Toast; import it.reyboz.bustorino.R; import it.reyboz.bustorino.backend.Stop; @@ -129,6 +130,7 @@ Toast.makeText(this.context, R.string.cant_add_to_favorites, Toast.LENGTH_SHORT).show(); } listener.doStuffWithResult(result); + Log.d("BusTO FavoritesAction", "Action "+action+" completed"); } public interface ResultListener{