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 @@ -9,6 +9,9 @@ import android.util.TypedValue; import android.view.View; +import java.io.PrintWriter; +import java.io.StringWriter; + public abstract class utils { private static final double EarthRadius = 6371e3; public static Double measuredistanceBetween(double lat1,double long1,double lat2,double long2){ @@ -103,4 +106,25 @@ Intent browserIntent1 = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); context.startActivity(browserIntent1); } + /** + * Print the first i lines of the the trace of an exception + * https://stackoverflow.com/questions/21706722/fetch-only-first-n-lines-of-a-stack-trace + */ + public static String traceCaller(Exception ex, int i) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + StringBuilder sb = new StringBuilder(); + ex.printStackTrace(pw); + String ss = sw.toString(); + String[] splitted = ss.split("\n"); + sb.append("\n"); + if(splitted.length > 2 + i) { + for(int x = 2; x < i+2; x++) { + sb.append(splitted[x].trim()); + sb.append("\n"); + } + return sb.toString(); + } + return "Trace too Short."; + } } 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 @@ -78,6 +78,8 @@ protected FragmentListenerMain listenerMain; private HashSet shownStops = null; + //the asynctask used to get the stops from the database + private AsyncStopFetcher stopFetcher = null; private MapView map = null; @@ -119,7 +121,7 @@ if(result.get(Manifest.permission.ACCESS_COARSE_LOCATION) && result.get(Manifest.permission.ACCESS_FINE_LOCATION)){ map.getOverlays().remove(mLocationOverlay); - startLocationOverlay(true); + startLocationOverlay(true, map); if(getContext()==null || getContext().getSystemService(Context.LOCATION_SERVICE)==null) return; LocationManager locationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE); @@ -151,7 +153,7 @@ return fragment; } - public static MapFragment getInstance(Stop stop){ + public static MapFragment getInstance(@NonNull Stop stop){ return getInstance(stop.getLatitude(), stop.getLongitude(), stop.getStopDisplayName(), stop.ID); } @@ -251,6 +253,10 @@ public void onPause() { super.onPause(); saveMapState(); + //cancel asynctask + Log.w(DEBUG_TAG, "On pause called"); + if (stopFetcher!= null) + stopFetcher.cancel(true); } /** @@ -298,7 +304,7 @@ */ public void setLocationFollowing(Boolean value){ followingLocation = value; - if(mLocationOverlay==null || getContext() == null) + if(mLocationOverlay==null || getContext() == null || map ==null) //nothing else to do return; if (value){ @@ -321,11 +327,11 @@ } /** - * Start the location overlay. Enable only when + * Build the location overlay. Enable only when * a) we know we have the permission * b) the location map is set */ - private void startLocationOverlay(boolean enableLocation){ + private void startLocationOverlay(boolean enableLocation, MapView map){ if(getActivity()== null) throw new IllegalStateException("Cannot enable LocationOverlay now"); // Location Overlay // from OpenBikeSharing (THANK GOD) @@ -333,11 +339,14 @@ GpsMyLocationProvider imlp = new GpsMyLocationProvider(getActivity().getBaseContext()); imlp.setLocationUpdateMinDistance(5); imlp.setLocationUpdateMinTime(2000); - this.mLocationOverlay = new LocationOverlay(imlp,map, locationCallbacks); - if (enableLocation) mLocationOverlay.enableMyLocation(); - mLocationOverlay.setOptionsMenuEnabled(true); - map.getOverlays().add(this.mLocationOverlay); + final LocationOverlay overlay = new LocationOverlay(imlp,map, locationCallbacks); + if (enableLocation) overlay.enableMyLocation(); + overlay.setOptionsMenuEnabled(true); + + //map.getOverlays().add(this.mLocationOverlay); + this.mLocationOverlay = overlay; + map.getOverlays().add(mLocationOverlay); } public void startMap(Bundle incoming, Bundle savedInstanceState) { @@ -350,6 +359,8 @@ }else{ Log.d(DEBUG_TAG, "Starting map from scratch"); } + //clear previous overlays + map.getOverlays().clear(); //parse incoming bundle @@ -364,18 +375,30 @@ ID = incoming.getString(BUNDLE_ID); } + + //ask for location permission + if(!Permissions.locationPermissionGranted(activity)){ + if(shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)){ + //TODO: show dialog for permission rationale + Toast.makeText(activity, R.string.enable_position_message_map, Toast.LENGTH_SHORT).show(); + } + positionRequestLauncher.launch(Permissions.LOCATION_PERMISSIONS); + + } + shownStops = new HashSet<>(); // move the map on the marker position or on a default view point: Turin, Piazza Castello // and set the start zoom IMapController mapController = map.getController(); GeoPoint startPoint = null; - + startLocationOverlay(Permissions.locationPermissionGranted(activity), + map); // set the center point if (marker != null) { startPoint = marker; mapController.setZoom(POSITION_FOUND_ZOOM); setLocationFollowing(false); - } else if (savedInstanceState != null) { + } 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), savedInstanceState.getDouble(MAP_CENTER_LON_KEY))); @@ -397,13 +420,6 @@ found = true; setLocationFollowing(true); } - } else if(!Permissions.locationPermissionGranted(activity)){ - if(shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)){ - //TODO: show dialog for permission rationale - Toast.makeText(activity, R.string.enable_position_message_map, Toast.LENGTH_SHORT).show(); - } - positionRequestLauncher.launch(Permissions.LOCATION_PERMISSIONS); - } if(!found){ startPoint = new GeoPoint(DEFAULT_CENTER_LAT, DEFAULT_CENTER_LON); @@ -411,7 +427,6 @@ setLocationFollowing(false); } } - startLocationOverlay(Permissions.locationPermissionGranted(activity)); // set the minimum zoom level map.setMinZoomLevel(15.0); @@ -420,7 +435,9 @@ mapController.setCenter(startPoint); } + //add stops overlay + //map.getOverlays().add(mLocationOverlay); map.getOverlays().add(this.stopsFolderOverlay); Log.d(DEBUG_TAG, "Requesting stops load"); @@ -445,8 +462,10 @@ double latTo = bb.getLatNorth(); double lngFrom = bb.getLonWest(); double lngTo = bb.getLonEast(); - - new AsyncStopFetcher(this).execute( + if (stopFetcher!= null && stopFetcher.getStatus()!= AsyncTask.Status.FINISHED) + stopFetcher.cancel(true); + stopFetcher = new AsyncStopFetcher(this); + stopFetcher.execute( new AsyncStopFetcher.BoundingBoxLimit(lngFrom,lngTo,latFrom, latTo)); } @@ -455,6 +474,11 @@ * @param stops the list of stops that must be included */ protected void showStopsMarkers(List stops){ + if (getContext() == null){ + //we are not attached + return; + } + boolean good = true; for (Stop stop : stops) { if (shownStops.contains(stop.ID)){ @@ -464,12 +488,22 @@ continue; shownStops.add(stop.ID); + if(!map.isShown()){ + if(good) + Log.d(DEBUG_TAG, "Need to show stop but map is not shown, probably detached already"); + good = false; + continue; + } else if(map.getRepository() == null){ + Log.e(DEBUG_TAG, "Map view repository is null"); + } GeoPoint marker = new GeoPoint(stop.getLatitude(), stop.getLongitude()); + Marker stopMarker = makeMarker(marker, stop.getStopDefaultName(), stop.ID, false); stopsFolderOverlay.add(stopMarker); if (!map.getOverlays().contains(stopsFolderOverlay)) { Log.w(DEBUG_TAG, "Map doesn't have folder overlay"); } + good=true; } //Log.d(DEBUG_TAG,"We have " +stopsFolderOverlay.getItems().size()+" stops in the folderOverlay"); //force redraw of markers @@ -479,7 +513,7 @@ public Marker makeMarker(GeoPoint geoPoint, String stopName, String ID, boolean isStartMarker) { // add a marker - Marker marker = new Marker(map); + final Marker marker = new Marker(map); // set custom info window as info window CustomInfoWindow popup = new CustomInfoWindow(map, ID, stopName, responder);