diff --git a/AndroidManifest.xml b/AndroidManifest.xml
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -85,6 +85,17 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".ActivityMain"/>
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/ic_angery_bus.xml b/res/drawable/ic_angery_bus.xml
new file mode 100644
--- /dev/null
+++ b/res/drawable/ic_angery_bus.xml
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/res/drawable/map.xml b/res/drawable/map.xml
new file mode 100644
--- /dev/null
+++ b/res/drawable/map.xml
@@ -0,0 +1,8 @@
+
+
+
+
diff --git a/res/layout/activity_favorites.xml b/res/layout/activity_favorites.xml
--- a/res/layout/activity_favorites.xml
+++ b/res/layout/activity_favorites.xml
@@ -1,8 +1,16 @@
+ tools:context="it.reyboz.bustorino.ActivityFavorites">
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/map_popup.xml b/res/layout/map_popup.xml
new file mode 100644
--- /dev/null
+++ b/res/layout/map_popup.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/menu/main.xml b/res/menu/main.xml
--- a/res/menu/main.xml
+++ b/res/menu/main.xml
@@ -2,7 +2,12 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="it.reyboz.bustorino.ActivityMain">
-
+
- Fermata aggiunta ai preferiti
Impossibile aggiungere ai preferiti (memoria piena o database corrotto?)!
Preferiti
- Tocca il nome di una fermata per aggiungerla in questa lista
+ Mappa
+ Nessun preferito? Arghh! Schiaccia sulla stella di una fermata per aggiungere a questa lista!
Rimuovi
Rinomina
Rinomina fermata
diff --git a/res/values/strings.xml b/res/values/strings.xml
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -35,7 +35,8 @@
Bus stop removed from your favorites
Favorites
Favorites
- Press on a bus stop name to populate this list
+ Map
+ No favorites? Arghh! Press on a bus stop star to populate this list!
Delete
Rename
Rename the bus stop
diff --git a/res/values/theme.xml b/res/values/theme.xml
--- a/res/values/theme.xml
+++ b/res/values/theme.xml
@@ -13,6 +13,12 @@
- @color/blue_700
+
+
\ No newline at end of file
diff --git a/src/it/reyboz/bustorino/ActivityFavorites.java b/src/it/reyboz/bustorino/ActivityFavorites.java
--- a/src/it/reyboz/bustorino/ActivityFavorites.java
+++ b/src/it/reyboz/bustorino/ActivityFavorites.java
@@ -17,22 +17,17 @@
*/
package it.reyboz.bustorino;
-import android.database.Cursor;
-import android.support.v4.app.LoaderManager;
-import android.support.v4.content.Loader;
-import android.widget.*;
-import it.reyboz.bustorino.backend.Stop;
-import it.reyboz.bustorino.adapters.StopAdapter;
-import it.reyboz.bustorino.middleware.AsyncStopFavoriteAction;
-import it.reyboz.bustorino.middleware.StopsDB;
-import it.reyboz.bustorino.middleware.UserDB;
-
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
-import android.net.Uri;
+import android.content.Intent;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
+import android.os.Bundle;
+import android.support.v4.app.LoaderManager;
import android.support.v4.app.NavUtils;
+import android.support.v4.content.Loader;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.view.ContextMenu;
@@ -41,13 +36,22 @@
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
+import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
-import android.content.Intent;
-import android.database.sqlite.SQLiteDatabase;
-import android.os.Bundle;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
import java.util.List;
+import it.reyboz.bustorino.adapters.StopAdapter;
+import it.reyboz.bustorino.backend.Stop;
+import it.reyboz.bustorino.middleware.AsyncStopFavoriteAction;
+import it.reyboz.bustorino.middleware.StopsDB;
+import it.reyboz.bustorino.middleware.UserDB;
+
public class ActivityFavorites extends AppCompatActivity implements LoaderManager.LoaderCallbacks {
private ListView favoriteListView;
private SQLiteDatabase userDB;
@@ -130,13 +134,17 @@
Toast.makeText(getApplicationContext(),R.string.cannot_show_on_map_no_position,Toast.LENGTH_SHORT).show();
return true;
}
- Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(theGeoUrl));
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- if(intent.resolveActivity(getPackageManager())!=null)
- startActivity(intent);
- else {
- Toast.makeText(getApplicationContext(),R.string.cannot_show_on_map_no_activity,Toast.LENGTH_SHORT).show();
- }
+
+ // start ActivityMap with these extras in intent
+ Intent intent = new Intent(ActivityFavorites.this, ActivityMap.class);
+ Bundle b = new Bundle();
+ b.putDouble("lat", busStop.getLatitude());
+ b.putDouble("lon", busStop.getLongitude());
+ b.putString("name", busStop.getStopDefaultName());
+ b.putString("ID", busStop.ID);
+ intent.putExtras(b);
+
+ startActivity(intent);
return true;
default:
return super.onContextItemSelected(item);
@@ -256,6 +264,8 @@
TextView favoriteTipTextView = (TextView) findViewById(R.id.favoriteTipTextView);
assert favoriteTipTextView != null;
favoriteTipTextView.setVisibility(View.VISIBLE);
+ ImageView angeryBusImageView = (ImageView) findViewById(R.id.angeryBusImageView);
+ angeryBusImageView.setVisibility(View.VISIBLE);
}
/* There's a nice method called notifyDataSetChanged() to avoid building the ListView
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
@@ -385,6 +385,9 @@
case R.id.action_favorites:
startActivity(new Intent(ActivityMain.this, ActivityFavorites.class));
return true;
+ case R.id.action_map:
+ startActivity(new Intent(ActivityMain.this, ActivityMap.class));
+ return true;
case R.id.action_about:
startActivity(new Intent(ActivityMain.this, ActivityAbout.class));
return true;
diff --git a/src/it/reyboz/bustorino/ActivityMap.java b/src/it/reyboz/bustorino/ActivityMap.java
new file mode 100644
--- /dev/null
+++ b/src/it/reyboz/bustorino/ActivityMap.java
@@ -0,0 +1,212 @@
+package it.reyboz.bustorino;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.RequiresApi;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.preference.PreferenceManager;
+
+import org.osmdroid.api.IMapController;
+import org.osmdroid.config.Configuration;
+import org.osmdroid.events.DelayedMapListener;
+import org.osmdroid.events.MapListener;
+import org.osmdroid.events.ScrollEvent;
+import org.osmdroid.events.ZoomEvent;
+import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
+import org.osmdroid.util.BoundingBox;
+import org.osmdroid.util.GeoPoint;
+import org.osmdroid.views.MapView;
+import org.osmdroid.views.overlay.Marker;
+import org.osmdroid.views.overlay.infowindow.InfoWindow;
+
+import it.reyboz.bustorino.backend.Stop;
+import it.reyboz.bustorino.map.CustomInfoWindow;
+import it.reyboz.bustorino.middleware.StopsDB;
+
+public class ActivityMap extends AppCompatActivity {
+
+ private static MapView map = null;
+ public Context ctx;
+
+ @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
+ @Override public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ //handle permissions first, before map is created. not depicted here
+
+ //load/initialize the osmdroid configuration, this can be done
+ ctx = getApplicationContext();
+ Configuration.getInstance().load(ctx, PreferenceManager.getDefaultSharedPreferences(ctx));
+ //setting this before the layout is inflated is a good idea
+ //it 'should' ensure that the map has a writable location for the map cache, even without permissions
+ //if no tiles are displayed, you can try overriding the cache path using Configuration.getInstance().setCachePath
+ //see also StorageUtils
+ //note, the load method also sets the HTTP User Agent to your application's package name, abusing osm's tile servers will get you banned based on this string
+
+ //inflate and create the map
+ setContentView(R.layout.activity_map);
+
+ map = (MapView) findViewById(R.id.map);
+ map.setTileSource(TileSourceFactory.MAPNIK);
+
+ // add ability to zoom with 2 fingers
+ map.setMultiTouchControls(true);
+
+ // take the parameters if it's called from other Activities
+ Bundle b = getIntent().getExtras();
+ GeoPoint marker = null;
+ String name = null;
+ String ID = null;
+ if(b != null) {
+ double lat = b.getDouble("lat");
+ double lon = b.getDouble("lon");
+ marker = new GeoPoint(lat, lon);
+ name = b.getString("name");
+ ID = b.getString("ID");
+ }
+ startMap(marker, name, ID);
+
+ // on drag and zoom reload the markers
+ map.addMapListener(new DelayedMapListener(new MapListener() {
+
+ @Override
+ public boolean onScroll(ScrollEvent paramScrollEvent) {
+ loadMarkers();
+ return true;
+ }
+
+ @Override
+ public boolean onZoom(ZoomEvent event) {
+ loadMarkers();
+ return true;
+ }
+
+ }));
+ }
+
+ public void startMap(GeoPoint marker, String name, String ID) {
+
+ // 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;
+ if (marker != null) {
+ startPoint = marker;
+ mapController.setZoom(20.0);
+ } else {
+ startPoint = new GeoPoint(45.0708, 7.6858);
+ mapController.setZoom(18.0);
+ }
+ // set the minimum zoom level
+ map.setMinZoomLevel(15.5);
+ mapController.setCenter(startPoint);
+
+ loadMarkers();
+ if (marker != null) {
+ // make a marker with the info window open for the searched marker
+ makeMarker(startPoint, name , ID, true);
+ }
+
+ }
+
+ public void makeMarker(GeoPoint geoPoint, String stopName, String ID, boolean isStartMarker) {
+
+ // add a marker
+ Marker marker = new Marker(map);
+
+ // set custom info window as info window
+ CustomInfoWindow popup = new CustomInfoWindow(map, ID, stopName);
+ marker.setInfoWindow(popup);
+
+ // make the marker clickable
+ marker.setOnMarkerClickListener((thisMarker, mapView) -> {
+ if (thisMarker.isInfoWindowOpen()) {
+ // on second click
+
+ // create an intent with these extras
+ Intent intent = new Intent(ActivityMap.this, ActivityMain.class);
+ Bundle b = new Bundle();
+ b.putString("bus-stop-ID", ID);
+ b.putString("bus-stop-display-name", stopName);
+ intent.putExtras(b);
+ intent.setFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
+
+ // start ActivityMain with the previous intent
+ startActivity(intent);
+ } else {
+ // on first click
+
+ // hide all opened info window
+ InfoWindow.closeAllInfoWindowsOn(map);
+ // show this particular info window
+ thisMarker.showInfoWindow();
+ // move the map to its position
+ map.getController().animateTo(thisMarker.getPosition());
+ }
+
+ return true;
+ });
+
+ // set its position
+ marker.setPosition(geoPoint);
+ marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
+ // display the marker
+ map.getOverlays().add(marker);
+ // add to it an icon
+ marker.setIcon(getResources().getDrawable(R.drawable.bus_marker));
+ // add to it a title
+ marker.setTitle(stopName);
+
+ // show popup info window of the searched marker
+ if (isStartMarker) {
+ marker.showInfoWindow();
+ }
+
+ }
+
+ public void loadMarkers() {
+
+ // get rid of the previous markers
+ map.getOverlays().clear();
+
+ // get the top, bottom, left and right screen's coordinate
+ BoundingBox bb = map.getBoundingBox();
+ double latFrom = bb.getLatSouth();
+ double latTo = bb.getLatNorth();
+ double lngFrom = bb.getLonWest();
+ double lngTo = bb.getLonEast();
+
+ // get the stops located in those coordinates
+ StopsDB stopsDB = new StopsDB(ctx);
+ stopsDB.openIfNeeded();
+ Stop[] stops = stopsDB.queryAllInsideMapView(latFrom, latTo, lngFrom, lngTo);
+ stopsDB.closeIfNeeded();
+
+ // add new markers of those stops
+ for (Stop stop : stops) {
+ GeoPoint marker = new GeoPoint(stop.getLatitude(), stop.getLongitude());
+ makeMarker(marker, stop.getStopDefaultName(), stop.ID, false);
+ }
+
+ }
+
+ public void onResume(){
+ super.onResume();
+ //this will refresh the osmdroid configuration on resuming.
+ //if you make changes to the configuration, use
+ //SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ //Configuration.getInstance().load(this, PreferenceManager.getDefaultSharedPreferences(this));
+ map.onResume(); //needed for compass, my location overlays, v6.0.0 and up
+ }
+
+ public void onPause(){
+ super.onPause();
+ //this will refresh the osmdroid configuration on resuming.
+ //if you make changes to the configuration, use
+ //SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ //Configuration.getInstance().save(this, prefs);
+ map.onPause(); //needed for compass, my location overlays, v6.0.0 and up
+ }
+}
\ No newline at end of file
diff --git a/src/it/reyboz/bustorino/map/CustomInfoWindow.java b/src/it/reyboz/bustorino/map/CustomInfoWindow.java
new file mode 100644
--- /dev/null
+++ b/src/it/reyboz/bustorino/map/CustomInfoWindow.java
@@ -0,0 +1,42 @@
+package it.reyboz.bustorino.map;
+
+import android.annotation.SuppressLint;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.MotionEvent;
+import android.view.View;
+
+import org.osmdroid.views.MapView;
+import org.osmdroid.views.overlay.infowindow.BasicInfoWindow;
+
+import it.reyboz.bustorino.ActivityMain;
+import it.reyboz.bustorino.R;
+
+public class CustomInfoWindow extends BasicInfoWindow {
+
+ @SuppressLint("ClickableViewAccessibility")
+ public CustomInfoWindow(MapView mapView, String ID, String stopName) {
+ // get the personalized layout
+ super(R.layout.map_popup, mapView);
+
+ // make clickable
+ mView.setOnTouchListener((View v, MotionEvent e) -> {
+ if (e.getAction() == MotionEvent.ACTION_UP) {
+ // on click
+
+ // create an intent with these extras
+ Intent intent = new Intent(mapView.getContext(), ActivityMain.class);
+ Bundle b = new Bundle();
+ b.putString("bus-stop-ID", ID);
+ b.putString("bus-stop-display-name", stopName);
+ intent.putExtras(b);
+ intent.setFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
+
+ // start ActivityMain with the previous intent
+ mapView.getContext().startActivity(intent);
+ }
+ return true;
+ });
+ }
+
+}