diff --git a/.travis.yml b/.travis.yml index 769c1d47..8c732f5b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,4 +37,13 @@ before_script: script: - ./wait_for_emulator - - ./gradlew connectedCheck -PdisablePreDex \ No newline at end of file + - ./gradlew connectedCheck -PdisablePreDex + +# Integration with Gitter (https://gitter.im/CUTR-at-USF/OpenTripPlanner-for-Android) +notifications: + webhooks: + urls: + - https://webhooks.gitter.im/e/92762176661b63005621 + on_success: always # options: [always|never|change] default: always + on_failure: always # options: [always|never|change] default: always + on_start: false # default: false \ No newline at end of file diff --git a/README.md b/README.md index 4d5e91da..d6a35883 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ -OpenTripPlanner for Android [![Build Status](https://travis-ci.org/CUTR-at-USF/OpenTripPlanner-for-Android.svg?branch=master)](https://travis-ci.org/CUTR-at-USF/OpenTripPlanner-for-Android) +OpenTripPlanner for Android [![Build Status](https://travis-ci.org/CUTR-at-USF/OpenTripPlanner-for-Android.svg?branch=master)](https://travis-ci.org/CUTR-at-USF/OpenTripPlanner-for-Android) [![Join the chat at https://gitter.im/CUTR-at-USF/OpenTripPlanner-for-Android](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/CUTR-at-USF/OpenTripPlanner-for-Android?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) =========================== -[![Join the chat at https://gitter.im/CUTR-at-USF/OpenTripPlanner-for-Android](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/CUTR-at-USF/OpenTripPlanner-for-Android?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - An Android app for multi-modal trip planning and navigation using any OpenTripPlanner server. Download the app via the [Google Play store](https://play.google.com/store/apps/details?id=edu.usf.cutr.opentripplanner.android). diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2454e74f..4d8a938c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Mar 06 10:05:36 EST 2015 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip +#Mon Dec 22 22:23:08 CET 2014 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip diff --git a/opentripplanner-android/build.gradle b/opentripplanner-android/build.gradle index 6a193e9b..97edb556 100644 --- a/opentripplanner-android/build.gradle +++ b/opentripplanner-android/build.gradle @@ -19,10 +19,10 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:1.1.0' + classpath 'com.android.tools.build:gradle:1.3.0' } } -apply plugin: 'com.android.application' +apply plugin: 'android' repositories { mavenCentral() @@ -37,14 +37,14 @@ repositories { } android { - compileSdkVersion 21 + compileSdkVersion 23 buildToolsVersion "21.1.2" defaultConfig { versionCode 15 versionName "2.1.2" - minSdkVersion 8 - targetSdkVersion 13 + minSdkVersion 9 + targetSdkVersion 23 } // http://stackoverflow.com/questions/20673625/gradle-0-7-0-duplicate-files-during-packaging-of-apk @@ -111,8 +111,11 @@ tasks.whenTaskAdded { theTask -> } dependencies { - compile 'com.android.support:support-v4:19.1.+' - compile 'com.google.android.gms:play-services:3.2.65' + compile 'com.android.support:support-v4:23.1.1' + // Only include Google Play Services maps and location libraries + compile 'com.google.android.gms:play-services-maps:7.8.0' + compile 'com.google.android.gms:play-services-location:7.8.0' + // Jackson is used for parsing JSON REST API responses compile 'com.fasterxml.jackson.core:jackson-core:2.4.1' compile 'com.fasterxml.jackson.core:jackson-annotations:2.4.1' compile 'com.fasterxml.jackson.core:jackson-databind:2.4.1.1' @@ -120,4 +123,6 @@ dependencies { compile 'edu.usf.cutr.opentripplanner.android:opentripplanner-pojos:1.0.0-SNAPSHOT' // OpenCSV, for parsing the OTP Server Directory Google Doc compile 'net.sf.opencsv:opencsv:2.3' + // Map util (point in bounding box) + compile 'com.google.maps.android:android-maps-utils:0.4' } diff --git a/opentripplanner-android/src/androidTest/java/edu/usf/cutr/opentripplanner/android/test/BoundsTest.java b/opentripplanner-android/src/androidTest/java/edu/usf/cutr/opentripplanner/android/test/BoundsTest.java index 879a7e65..fcd42afe 100644 --- a/opentripplanner-android/src/androidTest/java/edu/usf/cutr/opentripplanner/android/test/BoundsTest.java +++ b/opentripplanner-android/src/androidTest/java/edu/usf/cutr/opentripplanner/android/test/BoundsTest.java @@ -22,8 +22,6 @@ public class BoundsTest extends AndroidTestCase { public static final String TAG = "BoundsTest"; - public static final int ACCEPTABLE_ERROR = 10; // meters - Server serverTampa = new Server(); Server serverPortland = new Server(); @@ -41,6 +39,8 @@ public class BoundsTest extends AndroidTestCase { Server serverChukotkaPeninsulaIDL = new Server(); + Server serverUnitedStates = new Server(); + @Override protected void setUp() throws Exception { // Tampa server @@ -112,6 +112,14 @@ protected void setUp() throws Exception { serverChukotkaPeninsulaIDL.setContactName("Unknown"); serverChukotkaPeninsulaIDL.setContactEmail("Unknown"); + // United States + serverUnitedStates.setRegion("United States"); + serverUnitedStates.setBaseURL("http://us-server.com"); + serverUnitedStates.setBounds("24.5454892,-124.16933,49.273757,-69.965541"); + serverUnitedStates.setLanguage("en_US"); + serverUnitedStates.setContactName("Unknown"); + serverUnitedStates.setContactEmail("Unknown"); + super.setUp(); } @@ -119,96 +127,100 @@ public void testBoundsEvaluation() { // Tampa server LatLng pointInTampa1 = new LatLng(27.9710, -82.4650); Assert.assertTrue( - LocationUtil.checkPointInBoundingBox(pointInTampa1, serverTampa, ACCEPTABLE_ERROR)); + LocationUtil.checkPointInBoundingBox(pointInTampa1, serverTampa)); LatLng pointOutOfTampa1 = new LatLng(45.416, -122.839); Assert.assertFalse(LocationUtil - .checkPointInBoundingBox(pointOutOfTampa1, serverTampa, ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointOutOfTampa1, serverTampa)); // Portland server LatLng pointInPortland1 = new LatLng(45.518, -122.6800); Assert.assertTrue(LocationUtil - .checkPointInBoundingBox(pointInPortland1, serverPortland, ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointInPortland1, serverPortland)); LatLng pointOutOfPortland1 = new LatLng(45.416, -122.939); Assert.assertFalse(LocationUtil - .checkPointInBoundingBox(pointOutOfPortland1, serverPortland, ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointOutOfPortland1, serverPortland)); // Greenville server LatLng pointInGreenville1 = new LatLng(34.84733, -82.39693); Assert.assertTrue(LocationUtil - .checkPointInBoundingBox(pointInGreenville1, serverGreenville, ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointInGreenville1, serverGreenville)); LatLng pointOutOfGreenville1 = new LatLng(45.416, -122.839); Assert.assertFalse(LocationUtil - .checkPointInBoundingBox(pointOutOfGreenville1, serverGreenville, - ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointOutOfGreenville1, serverGreenville)); // Calgary server LatLng pointInCalgary1 = new LatLng(50.7100302, -114.6108674); Assert.assertTrue(LocationUtil - .checkPointInBoundingBox(pointInCalgary1, serverCalgary, ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointInCalgary1, serverCalgary)); LatLng pointOutOfCalgary1 = new LatLng(45.416, -122.839); Assert.assertFalse(LocationUtil - .checkPointInBoundingBox(pointOutOfCalgary1, serverCalgary, ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointOutOfCalgary1, serverCalgary)); // Porto server LatLng pointInPorto1 = new LatLng(41.1554, -8.6078); Assert.assertTrue( - LocationUtil.checkPointInBoundingBox(pointInPorto1, serverPorto, ACCEPTABLE_ERROR)); + LocationUtil.checkPointInBoundingBox(pointInPorto1, serverPorto)); LatLng pointOutOfPorto1 = new LatLng(45.416, -122.839); Assert.assertFalse(LocationUtil - .checkPointInBoundingBox(pointOutOfPorto1, serverPorto, ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointOutOfPorto1, serverPorto)); // Portland big bounds server LatLng pointInPortlandBigBounds1 = new LatLng(45.518, -122.6800); Assert.assertTrue(LocationUtil - .checkPointInBoundingBox(pointInPortlandBigBounds1, serverPortlandBigBounds, - ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointInPortlandBigBounds1, serverPortlandBigBounds)); LatLng pointOutOfPortlandBigBounds1 = new LatLng(27.9710, -82.4650); Assert.assertFalse(LocationUtil - .checkPointInBoundingBox(pointOutOfPortlandBigBounds1, serverPortlandBigBounds, - ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointOutOfPortlandBigBounds1, serverPortlandBigBounds)); // FijiIDL server LatLng pointInFijiIDLPositive = new LatLng(-16.407, -179.8141); Assert.assertTrue(LocationUtil - .checkPointInBoundingBox(pointInFijiIDLPositive, serverFijiIDL, ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointInFijiIDLPositive, serverFijiIDL)); LatLng pointOutOfFijiIDLPositive = new LatLng(-17.6995, 175.6581); Assert.assertFalse(LocationUtil - .checkPointInBoundingBox(pointOutOfFijiIDLPositive, serverFijiIDL, - ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointOutOfFijiIDLPositive, serverFijiIDL)); LatLng pointInFijiIDLNegative = new LatLng(-16.9089, -179.8151); Assert.assertTrue(LocationUtil - .checkPointInBoundingBox(pointInFijiIDLNegative, serverFijiIDL, ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointInFijiIDLNegative, serverFijiIDL)); LatLng pointOutOfFijiIDLNegative = new LatLng(-16.5907, -178.8570); Assert.assertFalse(LocationUtil - .checkPointInBoundingBox(pointOutOfFijiIDLNegative, serverFijiIDL, - ACCEPTABLE_ERROR)); + .checkPointInBoundingBox(pointOutOfFijiIDLNegative, serverFijiIDL)); // ChukotkaPeninsulaIDL server LatLng pointInChukotkaPeninsulaIDLPositive = new LatLng(66.8878, 179.1520); Assert.assertTrue(LocationUtil.checkPointInBoundingBox(pointInChukotkaPeninsulaIDLPositive, - serverChukotkaPeninsulaIDL, ACCEPTABLE_ERROR)); + serverChukotkaPeninsulaIDL)); LatLng pointOutOfChukotkaPeninsulaIDLPositive = new LatLng(-17.6995, 175.6581); Assert.assertFalse(LocationUtil .checkPointInBoundingBox(pointOutOfChukotkaPeninsulaIDLPositive, - serverChukotkaPeninsulaIDL, ACCEPTABLE_ERROR)); + serverChukotkaPeninsulaIDL)); LatLng pointInChukotkaPeninsulaIDLNegative = new LatLng(67.2878, -179.7276); Assert.assertTrue(LocationUtil.checkPointInBoundingBox(pointInChukotkaPeninsulaIDLNegative, - serverChukotkaPeninsulaIDL, ACCEPTABLE_ERROR)); + serverChukotkaPeninsulaIDL)); LatLng pointOutOfChukotkaPeninsulaIDLNegative = new LatLng(67.2878, -178.7276); Assert.assertFalse(LocationUtil .checkPointInBoundingBox(pointOutOfChukotkaPeninsulaIDLNegative, - serverChukotkaPeninsulaIDL, ACCEPTABLE_ERROR)); + serverChukotkaPeninsulaIDL)); + + // USA server + LatLng pointInUsaPositive = new LatLng(28.05866283764341, -82.41802878677845); + Assert.assertTrue(LocationUtil.checkPointInBoundingBox(pointInUsaPositive, + serverUnitedStates)); + + LatLng pointOutOfUsaPositive = new LatLng(67.2878, -178.7276); + Assert.assertFalse(LocationUtil + .checkPointInBoundingBox(pointOutOfUsaPositive, serverUnitedStates)); } } diff --git a/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/OTPApp.java b/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/OTPApp.java index f1359240..f130de10 100644 --- a/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/OTPApp.java +++ b/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/OTPApp.java @@ -105,8 +105,6 @@ public class OTPApp extends Application { public static final double BIKE_PARAMETERS_MAX_VALUE = 1.0; - public static final int CHECK_BOUNDS_ACCEPTABLE_ERROR = 1000; - public static final float COORDINATES_IMPORTANT_DIFFERENCE = 2000f; public static final int ADDRESS_MAX_LINES_TO_SHOW = 5; @@ -181,6 +179,14 @@ public class OTPApp extends Application { public static final int COLOR_ROUTE_LINE = 0x7F0000FF; + public static final int OPTIMIZATION_QUICK = 0; + + public static final int OPTIMIZATION_SAFE = 1; + + public static final int OPTIMIZATION_TRANSFERS = 2; + + public static final int OPTIMIZATION_TRIANGLE = 3; + /** * Preference keys */ diff --git a/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/fragments/MainFragment.java b/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/fragments/MainFragment.java index 4f2e55c1..8fc63fa6 100644 --- a/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/fragments/MainFragment.java +++ b/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/fragments/MainFragment.java @@ -16,6 +16,39 @@ package edu.usf.cutr.opentripplanner.android.fragments; +import com.google.android.gms.common.ConnectionResult; +import com.google.android.gms.common.GooglePlayServicesUtil; +import com.google.android.gms.common.api.GoogleApiClient; +import com.google.android.gms.maps.CameraUpdateFactory; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener; +import com.google.android.gms.maps.GoogleMap.OnMapClickListener; +import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener; +import com.google.android.gms.maps.GoogleMap.OnMarkerDragListener; +import com.google.android.gms.maps.SupportMapFragment; +import com.google.android.gms.maps.UiSettings; +import com.google.android.gms.maps.model.BitmapDescriptorFactory; +import com.google.android.gms.maps.model.CameraPosition; +import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.LatLngBounds; +import com.google.android.gms.maps.model.Marker; +import com.google.android.gms.maps.model.MarkerOptions; +import com.google.android.gms.maps.model.Polyline; +import com.google.android.gms.maps.model.PolylineOptions; +import com.google.android.gms.maps.model.TileOverlay; +import com.google.android.gms.maps.model.TileOverlayOptions; + +import org.opentripplanner.api.model.Itinerary; +import org.opentripplanner.api.model.Leg; +import org.opentripplanner.api.ws.GraphMetadata; +import org.opentripplanner.api.ws.Request; +import org.opentripplanner.index.model.TripTimeShort; +import org.opentripplanner.routing.bike_rental.BikeRentalStation; +import org.opentripplanner.routing.bike_rental.BikeRentalStationList; +import org.opentripplanner.routing.core.OptimizeType; +import org.opentripplanner.routing.core.TraverseMode; +import org.opentripplanner.routing.core.TraverseModeSet; + import android.animation.LayoutTransition; import android.annotation.TargetApi; import android.app.Activity; @@ -64,9 +97,6 @@ import android.view.Gravity; import android.view.KeyEvent; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; @@ -82,10 +112,10 @@ import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; +import android.widget.Button; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.ImageButton; -import android.widget.ListView; import android.widget.RadioButton; import android.widget.RelativeLayout; import android.widget.Spinner; @@ -93,40 +123,6 @@ import android.widget.TextView.OnEditorActionListener; import android.widget.Toast; -import com.google.android.gms.common.ConnectionResult; -import com.google.android.gms.common.GooglePlayServicesClient; -import com.google.android.gms.common.GooglePlayServicesUtil; -import com.google.android.gms.location.LocationClient; -import com.google.android.gms.maps.CameraUpdateFactory; -import com.google.android.gms.maps.GoogleMap; -import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener; -import com.google.android.gms.maps.GoogleMap.OnMapClickListener; -import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener; -import com.google.android.gms.maps.GoogleMap.OnMarkerDragListener; -import com.google.android.gms.maps.SupportMapFragment; -import com.google.android.gms.maps.UiSettings; -import com.google.android.gms.maps.model.BitmapDescriptorFactory; -import com.google.android.gms.maps.model.CameraPosition; -import com.google.android.gms.maps.model.LatLng; -import com.google.android.gms.maps.model.LatLngBounds; -import com.google.android.gms.maps.model.Marker; -import com.google.android.gms.maps.model.MarkerOptions; -import com.google.android.gms.maps.model.Polyline; -import com.google.android.gms.maps.model.PolylineOptions; -import com.google.android.gms.maps.model.TileOverlay; -import com.google.android.gms.maps.model.TileOverlayOptions; - -import org.opentripplanner.api.model.Itinerary; -import org.opentripplanner.api.model.Leg; -import org.opentripplanner.api.ws.GraphMetadata; -import org.opentripplanner.api.ws.Request; -import org.opentripplanner.index.model.TripTimeShort; -import org.opentripplanner.routing.bike_rental.BikeRentalStation; -import org.opentripplanner.routing.bike_rental.BikeRentalStationList; -import org.opentripplanner.routing.core.OptimizeType; -import org.opentripplanner.routing.core.TraverseMode; -import org.opentripplanner.routing.core.TraverseModeSet; - import java.io.UnsupportedEncodingException; import java.lang.ref.WeakReference; import java.net.URLEncoder; @@ -169,16 +165,19 @@ import edu.usf.cutr.opentripplanner.android.tasks.TripRequest; import edu.usf.cutr.opentripplanner.android.util.BikeRentalStationInfo; import edu.usf.cutr.opentripplanner.android.util.ConversionUtils; +import edu.usf.cutr.opentripplanner.android.util.CustomAddress; import edu.usf.cutr.opentripplanner.android.util.CustomInfoWindowAdapter; import edu.usf.cutr.opentripplanner.android.util.DateTimeDialog; import edu.usf.cutr.opentripplanner.android.util.DirectionsGenerator; import edu.usf.cutr.opentripplanner.android.util.LocationUtil; +import edu.usf.cutr.opentripplanner.android.util.PlacesAutoCompleteAdapter; import edu.usf.cutr.opentripplanner.android.util.RangeSeekBar; import edu.usf.cutr.opentripplanner.android.util.RangeSeekBar.OnRangeSeekBarChangeListener; import edu.usf.cutr.opentripplanner.android.util.RightDrawableOnTouchListener; import edu.usf.cutr.opentripplanner.android.util.TripInfo; -import edu.usf.cutr.opentripplanner.android.util.PlacesAutoCompleteAdapter; -import edu.usf.cutr.opentripplanner.android.util.CustomAddress; + +import static com.google.android.gms.location.LocationServices.API; +import static com.google.android.gms.location.LocationServices.FusedLocationApi; /** * Main UI screen of the mOTPApp, showing the map. @@ -191,8 +190,8 @@ public class MainFragment extends Fragment implements TripRequestCompleteListener, MetadataRequestCompleteListener, BikeRentalLoadCompleteListener, RequestTimesForTripsCompleteListener, OTPGeocodingListener, DateCompleteListener, OnRangeSeekBarChangeListener, ServerCheckerCompleteListener, - GooglePlayServicesClient.OnConnectionFailedListener, - GooglePlayServicesClient.ConnectionCallbacks, + GoogleApiClient.OnConnectionFailedListener, + GoogleApiClient.ConnectionCallbacks, GoogleMap.OnCameraChangeListener { private static LocationManager sLocationManager; @@ -201,7 +200,7 @@ public class MainFragment extends Fragment implements private Context mApplicationContext; - private LocationClient mLocationClient; + private GoogleApiClient mGoogleApiClient; private OtpFragment mFragmentListener; @@ -226,7 +225,11 @@ public class MainFragment extends Fragment implements private ViewGroup mNavigationDrawerLeftPane; - private ListView mDdlOptimization; + private RadioButton mBtnModeQuick; + + private RadioButton mBtnModeSafe; + + private RadioButton mBtnModeTransfersOrBike; private CheckBox mBtnModeBus; @@ -254,8 +257,13 @@ public class MainFragment extends Fragment implements private ImageButton mBtnDisplayDirection; - private MenuItem mGPS; + private Button mBtnGPS; + + private Button mBtnSettings; + private Button mBtnServerInfo; + + private Button mBtnFeedback; private GoogleMap mMap; @@ -401,8 +409,6 @@ public void onAttach(Activity activity) { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setHasOptionsMenu(true); - getActivity().getSupportFragmentManager() .addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { public void onBackStackChanged() { @@ -471,8 +477,10 @@ public void onGlobalLayout() { mTbEndLocation = (AutoCompleteTextView) mainView.findViewById(R.id.tbEndLocation); mBtnSwapOriginDestination = (ImageButton) mainView.findViewById(R.id.btnSwapOriginDestination); - mDdlOptimization = (ListView) mainView - .findViewById(R.id.spinOptimization); + + mBtnModeQuick = (RadioButton) mainView.findViewById(R.id.btnModeQuick); + mBtnModeSafe = (RadioButton) mainView.findViewById(R.id.btnModeSafe); + mBtnModeTransfersOrBike = (RadioButton) mainView.findViewById(R.id.btnModeTransfersOrBike); mBtnModeWalk = (RadioButton) mainView.findViewById(R.id.btnModeWalk); mBtnModeBike = (RadioButton) mainView.findViewById(R.id.btnModeBike); @@ -510,6 +518,14 @@ public void onGlobalLayout() { mBtnHandle = (ImageButton) mainView.findViewById(R.id.btnHandle); mDrawerLayout = (DrawerLayout) mainView.findViewById(R.id.drawerLayout); + mBtnGPS = (Button) mainView.findViewById(R.id.btnGPS); + + mBtnSettings = (Button) mainView.findViewById(R.id.btnSettings); + + mBtnServerInfo = (Button) mainView.findViewById(R.id.btnServerInfo); + + mBtnFeedback = (Button) mainView.findViewById(R.id.btnFeedback); + mTbStartLocation.setImeOptions(EditorInfo.IME_ACTION_NEXT); mTbEndLocation.setImeOptions(EditorInfo.IME_ACTION_DONE); mTbEndLocation.setImeActionLabel(getResources().getString(R.string.text_box_virtual_keyboard_done_label), EditorInfo.IME_ACTION_DONE); @@ -553,8 +569,6 @@ public void onActivityCreated(Bundle savedInstanceState) { mIsAlarmTripTimeUpdateActive = false; mAlarmReceiver = new AlarmReceiver(); - mMap = retrieveMap(mMap); - mOTPApp = ((OTPApp) getActivity().getApplication()); mPrefs = PreferenceManager.getDefaultSharedPreferences( @@ -578,21 +592,6 @@ public void onActivityCreated(Bundle savedInstanceState) { setTextBoxLocation(getResources().getString(R.string.text_box_my_location), true); } - ArrayAdapter optimizationAdapter - = new ArrayAdapter( - getActivity(), - android.R.layout.simple_list_item_single_choice, - new OptimizeSpinnerItem[]{ - new OptimizeSpinnerItem( - getResources().getString(R.string.left_panel_optimization_quick), - OptimizeType.QUICK), - new OptimizeSpinnerItem( - getResources().getString(R.string.left_panel_optimization_safe), - OptimizeType.SAFE), - new OptimizeSpinnerItem( - getResources().getString(R.string.left_panel_optimization_fewest_transfers), - OptimizeType.TRANSFERS)}); - Server selectedServer = mOTPApp.getSelectedServer(); if (selectedServer != null) { if (!mMapFailed) { @@ -605,6 +604,9 @@ public void onActivityCreated(Bundle savedInstanceState) { restoreState(savedInstanceState); + mMap = retrieveMap(mMap); + + if (!mMapFailed) { updateSelectedServer(false); } @@ -694,8 +696,7 @@ public void onMarkerDragEnd(Marker marker) { LatLng markerLatlng = marker.getPosition(); if (((mOTPApp.getSelectedServer() != null) && LocationUtil - .checkPointInBoundingBox(markerLatlng, mOTPApp.getSelectedServer(), - OTPApp.CHECK_BOUNDS_ACCEPTABLE_ERROR)) + .checkPointInBoundingBox(markerLatlng, mOTPApp.getSelectedServer())) || (mOTPApp.getSelectedServer() == null)) { if ((mStartMarker != null) && (marker.hashCode() == mStartMarker.hashCode())) { if (mPrefs @@ -826,12 +827,20 @@ public void onDrawerSlide(View arg0, float arg1) { .getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mTbEndLocation.getWindowToken(), 0); imm.hideSoftInputFromWindow(mTbStartLocation.getWindowToken(), 0); + if (isGPSEnabled()) { + mBtnGPS.setText(R.string.menu_button_disable_gps); + } else { + mBtnGPS.setText(R.string.menu_button_enable_gps); + } + + if (mDrawerLayout != null && mDrawerLayout.isDrawerOpen(Gravity.LEFT)){ + mDrawerLayout.closeDrawer(Gravity.LEFT); + } } @Override public void onDrawerOpened(View arg0) { - previousOptimization = ((OptimizeSpinnerItem) mDdlOptimization - .getItemAtPosition(mDdlOptimization.getCheckedItemPosition())).getOptimizeType(); + previousOptimization = getSelectedOptimization(); previousModes = getSelectedTraverseModeSet(); previousBikeTriangleMinValue = mBikeTriangleMinValue; previousBikeTriangleMaxValue = mBikeTriangleMaxValue; @@ -840,9 +849,7 @@ public void onDrawerOpened(View arg0) { @Override public void onDrawerClosed(View arg0) { TraverseModeSet newModes = getSelectedTraverseModeSet(); - OptimizeType newOptimization = ((OptimizeSpinnerItem) mDdlOptimization - .getItemAtPosition(mDdlOptimization.getCheckedItemPosition())).getOptimizeType(); - boolean sameOptimization = previousOptimization.equals(newOptimization); + boolean sameOptimization = previousOptimization.equals(getSelectedOptimization()); boolean sameTraverseMode = previousModes.getModes().equals(newModes.getModes()); boolean sameBikeTriangle = previousBikeTriangleMinValue == mBikeTriangleMinValue && previousBikeTriangleMaxValue == mBikeTriangleMaxValue; @@ -1371,28 +1378,181 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { } }); - mDdlOptimization.setOnItemClickListener(new OnItemClickListener() { - public void onItemClick(AdapterView parent, View view, - int position, long id) { - if (getSelectedTraverseModeSet().getBicycle()) { - mOptimizationValueToRestoreWhenNoBike = position; - } + mBtnModeQuick.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { SharedPreferences.Editor editor = mPrefs.edit(); - editor.putInt(OTPApp.PREFERENCE_KEY_LAST_OPTIMIZATION, position); + editor.putInt(OTPApp.PREFERENCE_KEY_LAST_OPTIMIZATION, + mOTPApp.OPTIMIZATION_QUICK); editor.commit(); - OptimizeSpinnerItem optimizeSpinnerItem = (OptimizeSpinnerItem) mDdlOptimization - .getItemAtPosition(position); - if (optimizeSpinnerItem != null) { - showBikeParameters( - optimizeSpinnerItem.getOptimizeType().equals(OptimizeType.TRIANGLE)); - } else { - Log.e(OTPApp.TAG, "Not possible to change optimization mode because selected" - + "optimization is unknown"); + } + }); + + mBtnModeSafe.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SharedPreferences.Editor editor = mPrefs.edit(); + editor.putInt(OTPApp.PREFERENCE_KEY_LAST_OPTIMIZATION, + mOTPApp.OPTIMIZATION_SAFE); + editor.commit(); + } + }); + + mBtnModeTransfersOrBike.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SharedPreferences.Editor editor = mPrefs.edit(); + if (mBtnModeBike.isChecked() || mBtnModeRentedBike.isChecked()){ + editor.putInt(OTPApp.PREFERENCE_KEY_LAST_OPTIMIZATION, + mOTPApp.OPTIMIZATION_TRIANGLE); + showBikeParameters(isChecked); + } + else{ + editor.putInt(OTPApp.PREFERENCE_KEY_LAST_OPTIMIZATION, + mOTPApp.OPTIMIZATION_TRANSFERS); } + editor.commit(); } }); mBikeTriangleParameters.setOnRangeSeekBarChangeListener(this); + + OnClickListener oclSettingsButton = new OnClickListener() { + @Override + public void onClick(View arg0) { + getActivity().startActivityForResult( + new Intent(getActivity(), SettingsActivity.class), + OTPApp.SETTINGS_REQUEST_CODE); + if (mDrawerLayout != null && mDrawerLayout.isDrawerOpen(Gravity.LEFT)){ + mDrawerLayout.closeDrawer(Gravity.LEFT); + } + } + }; + mBtnSettings.setOnClickListener(oclSettingsButton); + + OnClickListener oclFeedback = new OnClickListener() { + @Override + public void onClick(View arg0) { + Server selectedServer = mOTPApp.getSelectedServer(); + + String[] recipients = {selectedServer.getContactEmail(), + getString(R.string.feedback_email_android_developer)}; + + String uriText = "mailto:"; + for (String recipient : recipients) { + uriText += recipient + ";"; + } + + String subject = ""; + subject += getResources().getString(R.string.menu_button_feedback_subject); + Date d = Calendar.getInstance().getTime(); + subject += "[" + d.toString() + "]"; + uriText += "?subject=" + subject; + + String content = ((MyActivity) getActivity()).getCurrentRequestString(); + + try { + uriText += "&body=" + URLEncoder.encode(content, OTPApp.URL_ENCODING); + } catch (UnsupportedEncodingException e1) { + e1.printStackTrace(); + return; + } + + Uri uri = Uri.parse(uriText); + + Intent sendIntent = new Intent(Intent.ACTION_SENDTO); + sendIntent.setData(uri); + startActivity(Intent.createChooser(sendIntent, + getResources().getString(R.string.menu_button_feedback_send_email))); + + if (mDrawerLayout != null && mDrawerLayout.isDrawerOpen(Gravity.LEFT)){ + mDrawerLayout.closeDrawer(Gravity.LEFT); + } + } + }; + mBtnFeedback.setOnClickListener(oclFeedback); + + OnClickListener oclServerInfo = new OnClickListener() { + @Override + public void onClick(View arg0) { + + Server server = mOTPApp.getSelectedServer(); + + if (server == null) { + Log.w(OTPApp.TAG, + "Tried to get server info when no server was selected"); + Toast.makeText(mApplicationContext, mApplicationContext.getResources() + .getString(R.string.toast_no_server_selected_error), Toast.LENGTH_SHORT) + .show(); + return; + } + + WeakReference weakContext = new WeakReference(getActivity()); + + ServerChecker serverChecker = new ServerChecker(weakContext, mApplicationContext, + true); + serverChecker.execute(server); + + + if (mDrawerLayout != null && mDrawerLayout.isDrawerOpen(Gravity.LEFT)){ + mDrawerLayout.closeDrawer(Gravity.LEFT); + } + + } + }; + mBtnServerInfo.setOnClickListener(oclServerInfo); + + OnClickListener oclGPSButton = new OnClickListener() { + @Override + public void onClick(View arg0) { + + Intent myIntent = new Intent( + Settings.ACTION_LOCATION_SOURCE_SETTINGS); + startActivity(myIntent); + + if (mDrawerLayout != null && mDrawerLayout.isDrawerOpen(Gravity.LEFT)){ + mDrawerLayout.closeDrawer(Gravity.LEFT); + } + + } + }; + mBtnGPS.setOnClickListener(oclGPSButton); + } + + private OptimizeType getSelectedOptimization(){ + OptimizeType selectedOptimization = OptimizeType.QUICK; + if (mBtnModeSafe.isChecked()){ + selectedOptimization = OptimizeType.SAFE; + } + else{ + if (mBtnModeTransfersOrBike.isChecked()){ + if (mBtnModeBike.isChecked() || mBtnModeRentedBike.isChecked()){ + selectedOptimization = OptimizeType.TRIANGLE; + } + else{ + selectedOptimization = OptimizeType.TRANSFERS; + } + } + } + return selectedOptimization; + } + + private int getSelectedOptimizationIntValue(){ + int selectedOptimization = mOTPApp.OPTIMIZATION_QUICK; + if (mBtnModeSafe.isChecked()){ + selectedOptimization = mOTPApp.OPTIMIZATION_SAFE; + } + else{ + if (mBtnModeTransfersOrBike.isChecked()){ + if (mBtnModeBike.isChecked() || mBtnModeRentedBike.isChecked()){ + selectedOptimization = mOTPApp.OPTIMIZATION_TRIANGLE; + } + else{ + selectedOptimization = mOTPApp.OPTIMIZATION_TRANSFERS; + } + } + } + return selectedOptimization; } /** @@ -1413,14 +1573,26 @@ private void restorePanelUI(){ private void restoreOptimization(){ int previousOptimization; if ((previousOptimization = - mPrefs.getInt(mOTPApp.PREFERENCE_KEY_LAST_OPTIMIZATION, -1)) != -1){ - mDdlOptimization.setItemChecked(previousOptimization, true); + mPrefs.getInt(mOTPApp.PREFERENCE_KEY_LAST_OPTIMIZATION, -1)) != -1) { + checkOptimization(previousOptimization); } else{ SharedPreferences.Editor editor = mPrefs.edit(); - editor.putInt(OTPApp.PREFERENCE_KEY_LAST_OPTIMIZATION, 0); + editor.putInt(OTPApp.PREFERENCE_KEY_LAST_OPTIMIZATION, OTPApp.OPTIMIZATION_QUICK); editor.commit(); - mDdlOptimization.setItemChecked(0, true); + checkOptimization(OTPApp.OPTIMIZATION_QUICK); + } + } + + private void checkOptimization(int intOptimizationValue){ + if (intOptimizationValue == OTPApp.OPTIMIZATION_QUICK){ + mBtnModeQuick.setChecked(true); + } + else if (intOptimizationValue == OTPApp.OPTIMIZATION_SAFE){ + mBtnModeSafe.setChecked(true); + } + else { + mBtnModeTransfersOrBike.setChecked(true); } } @@ -1804,23 +1976,12 @@ private void requestTrip() { request.setArriveBy(mArriveBy); - OptimizeSpinnerItem optimizeSpinnerItem = (OptimizeSpinnerItem) mDdlOptimization - .getItemAtPosition(mDdlOptimization.getCheckedItemPosition()); - if (optimizeSpinnerItem == null) { - optimizeSpinnerItem = (OptimizeSpinnerItem) mDdlOptimization.getItemAtPosition(0); - } - - if (optimizeSpinnerItem != null) { - request.setOptimize(optimizeSpinnerItem.getOptimizeType()); - if (optimizeSpinnerItem.getOptimizeType().equals(OptimizeType.TRIANGLE)) { - request.setTriangleTimeFactor(mBikeTriangleMinValue); - request.setTriangleSlopeFactor(mBikeTriangleMaxValue - mBikeTriangleMinValue); - request.setTriangleSafetyFactor(1 - mBikeTriangleMaxValue); - } - } else { - Log.e(OTPApp.TAG, - "Optimization not found, not possible to add it to the request so, most" - + "likely results will be incorrect"); + OptimizeType selectedOptimization = getSelectedOptimization(); + request.setOptimize(selectedOptimization); + if (selectedOptimization.equals(OptimizeType.TRIANGLE)) { + request.setTriangleTimeFactor(mBikeTriangleMinValue); + request.setTriangleSlopeFactor(mBikeTriangleMaxValue - mBikeTriangleMinValue); + request.setTriangleSafetyFactor(1 - mBikeTriangleMaxValue); } request.setModes(getSelectedTraverseModeSet()); @@ -1892,7 +2053,7 @@ private GoogleMap retrieveMap(GoogleMap mMap) { mMapFailed = false; if (mMap == null) { - mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)) + mMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)) .getMap(); // Check if we were successful in obtaining the map. if (mMap == null) { @@ -1937,49 +2098,22 @@ private void showBikeParameters(boolean enable) { * when bike mode is abandoned */ private void setBikeOptimizationAdapter(boolean enable, boolean updateOptimizationValue) { - ArrayAdapter optimizationAdapter; int newOptimizationValue; if (updateOptimizationValue){ if (enable){ - mOptimizationValueToRestoreWhenNoBike = mDdlOptimization.getCheckedItemPosition(); + mOptimizationValueToRestoreWhenNoBike = getSelectedOptimizationIntValue(); } } if (enable) { - optimizationAdapter = new ArrayAdapter( - getActivity(), - android.R.layout.simple_list_item_single_choice, - new OptimizeSpinnerItem[]{ - new OptimizeSpinnerItem( - getResources().getString(R.string.left_panel_optimization_quick), - OptimizeType.QUICK), - new OptimizeSpinnerItem( - getResources().getString(R.string.left_panel_optimization_safe), - OptimizeType.SAFE), - new OptimizeSpinnerItem( - getResources().getString(R.string.left_panel_optimization_bike_triangle), - OptimizeType.TRIANGLE)}); - mDdlOptimization.setAdapter(optimizationAdapter); + mBtnModeTransfersOrBike.setText(R.string.left_panel_optimization_bike_triangle); } else { - optimizationAdapter = new ArrayAdapter( - getActivity(), - android.R.layout.simple_list_item_single_choice, - new OptimizeSpinnerItem[]{ - new OptimizeSpinnerItem( - getResources().getString(R.string.left_panel_optimization_quick), - OptimizeType.QUICK), - new OptimizeSpinnerItem( - getResources().getString(R.string.left_panel_optimization_safe), - OptimizeType.SAFE), - new OptimizeSpinnerItem(getResources() - .getString(R.string.left_panel_optimization_fewest_transfers), - OptimizeType.TRANSFERS)}); - mDdlOptimization.setAdapter(optimizationAdapter); + mBtnModeTransfersOrBike.setText(R.string.left_panel_optimization_fewest_transfers); } if (updateOptimizationValue){ if (enable){ - newOptimizationValue = 2; + newOptimizationValue = OTPApp.OPTIMIZATION_TRIANGLE; } else{ if (mOptimizationValueToRestoreWhenNoBike != -1){ @@ -1989,10 +2123,10 @@ else if (mPrefs.getInt(OTPApp.PREFERENCE_KEY_LAST_OPTIMIZATION, -1) != -1){ newOptimizationValue = mPrefs.getInt(OTPApp.PREFERENCE_KEY_LAST_OPTIMIZATION, -1); } else{ - newOptimizationValue = 0; + newOptimizationValue = OTPApp.OPTIMIZATION_QUICK; } } - mDdlOptimization.setItemChecked(newOptimizationValue, true); + checkOptimization(newOptimizationValue); SharedPreferences.Editor editor = mPrefs.edit(); editor.putInt(OTPApp.PREFERENCE_KEY_LAST_OPTIMIZATION, newOptimizationValue); editor.commit(); @@ -2244,8 +2378,7 @@ private void setMarker(boolean isStartMarker, LatLng latlng, boolean showMessage SharedPreferences.Editor prefsEditor = mPrefs.edit(); if (((mOTPApp.getSelectedServer() != null) && LocationUtil - .checkPointInBoundingBox(latlng, mOTPApp.getSelectedServer(), - OTPApp.CHECK_BOUNDS_ACCEPTABLE_ERROR)) + .checkPointInBoundingBox(latlng, mOTPApp.getSelectedServer())) || (mOTPApp.getSelectedServer() == null)) { if (showMessage) { String toastText; @@ -2408,10 +2541,14 @@ private void updateMarkerPosition(LatLng newLatLng, boolean isStartMarker) { public void onStart() { super.onStart(); - mLocationClient = new LocationClient(mApplicationContext, this, this); + mGoogleApiClient = new GoogleApiClient.Builder(getActivity()) + .addApi(API) + .addConnectionCallbacks(this) + .addOnConnectionFailedListener(this) + .build(); if (mMapFailed) { - mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)) + mMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)) .getMap(); // Check if we were successful in obtaining the map. if (mMap != null) { @@ -2433,8 +2570,8 @@ public void onStart() { * request or is disconnected. */ public void connectLocationClient() { - if (!mLocationClient.isConnected() && !mLocationClient.isConnecting()) { - mLocationClient.connect(); + if (!mGoogleApiClient.isConnected() && !mGoogleApiClient.isConnecting()) { + mGoogleApiClient.connect(); } } @@ -2444,8 +2581,8 @@ public void connectLocationClient() { * To avoid errors only tries if it's connected. */ public void disconnectLocationClient() { - if (mLocationClient.isConnected()) { - mLocationClient.disconnect(); + if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) { + mGoogleApiClient.disconnect(); } } @@ -2676,8 +2813,7 @@ public void updateSelectedServer(boolean updateUI) { LatLng mCurrentLatLng = getLastLocation(); if ((mCurrentLatLng != null) && (LocationUtil - .checkPointInBoundingBox(mCurrentLatLng, server, - OTPApp.CHECK_BOUNDS_ACCEPTABLE_ERROR))) { + .checkPointInBoundingBox(mCurrentLatLng, server))) { mMap.animateCamera(CameraUpdateFactory .newLatLngZoom(mCurrentLatLng, getServerInitialZoom(server))); } else { @@ -2718,97 +2854,6 @@ public void updateSelectedServer(boolean updateUI) { } } - @Override - public void onCreateOptionsMenu(Menu pMenu, MenuInflater inflater) { - super.onCreateOptionsMenu(pMenu, inflater); - inflater.inflate(R.menu.menu, pMenu); - mGPS = pMenu.getItem(0); - } - - @Override - public void onPrepareOptionsMenu(final Menu pMenu) { - if (isGPSEnabled()) { - mGPS.setTitle(R.string.menu_button_disable_gps); - } else { - mGPS.setTitle(R.string.menu_button_enable_gps); - } - super.onPrepareOptionsMenu(pMenu); - } - - @Override - public boolean onOptionsItemSelected(final MenuItem pItem) { - OTPApp app = ((OTPApp) getActivity().getApplication()); - switch (pItem.getItemId()) { - case R.id.gps_settings: - Intent myIntent = new Intent( - Settings.ACTION_LOCATION_SOURCE_SETTINGS); - startActivity(myIntent); - break; - case R.id.settings: - getActivity().startActivityForResult( - new Intent(getActivity(), SettingsActivity.class), - OTPApp.SETTINGS_REQUEST_CODE); - break; - case R.id.feedback: - Server selectedServer = app.getSelectedServer(); - - String[] recipients = {selectedServer.getContactEmail(), - getString(R.string.feedback_email_android_developer)}; - - String uriText = "mailto:"; - for (String recipient : recipients) { - uriText += recipient + ";"; - } - - String subject = ""; - subject += getResources().getString(R.string.menu_button_feedback_subject); - Date d = Calendar.getInstance().getTime(); - subject += "[" + d.toString() + "]"; - uriText += "?subject=" + subject; - - String content = ((MyActivity) getActivity()).getCurrentRequestString(); - - try { - uriText += "&body=" + URLEncoder.encode(content, OTPApp.URL_ENCODING); - } catch (UnsupportedEncodingException e1) { - e1.printStackTrace(); - return false; - } - - Uri uri = Uri.parse(uriText); - - Intent sendIntent = new Intent(Intent.ACTION_SENDTO); - sendIntent.setData(uri); - startActivity(Intent.createChooser(sendIntent, - getResources().getString(R.string.menu_button_feedback_send_email))); - - break; - case R.id.server_info: - Server server = app.getSelectedServer(); - - if (server == null) { - Log.w(OTPApp.TAG, - "Tried to get server info when no server was selected"); - Toast.makeText(mApplicationContext, mApplicationContext.getResources() - .getString(R.string.toast_no_server_selected_error), Toast.LENGTH_SHORT) - .show(); - break; - } - - WeakReference weakContext = new WeakReference(getActivity()); - - ServerChecker serverChecker = new ServerChecker(weakContext, mApplicationContext, - true); - serverChecker.execute(server); - - break; - default: - break; - } - - return false; - } - private Boolean isGPSEnabled() { return sLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); } @@ -3083,7 +3128,8 @@ public void showRouteOnMap(List itinerary, int animateCamera) { } if (animateCamera > 0) { LatLngBounds routeBounds = boundsCreator.build(); - if (((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap() + if (((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map)) + .getMap() != null){ showRouteOnMapAnimateCamera(routeBounds, firstTransitMarker, animateCamera); } @@ -3549,8 +3595,7 @@ public void onMetadataRequestComplete(GraphMetadata metadata, boolean updateUI) if (updateUI){ if ((mCurrentLatLng != null) && (LocationUtil - .checkPointInBoundingBox(mCurrentLatLng, selectedServer, - OTPApp.CHECK_BOUNDS_ACCEPTABLE_ERROR))) { + .checkPointInBoundingBox(mCurrentLatLng, selectedServer))) { mMap.animateCamera(CameraUpdateFactory .newLatLngZoom(mCurrentLatLng, getServerInitialZoom(selectedServer))); } else { @@ -3633,9 +3678,9 @@ public void updateOverlay(String overlayString) { * @return a LatLng object with the most updated user coordinates */ public LatLng getLastLocation() { - if (mLocationClient != null){ - if (mLocationClient.isConnected()) { - Location loc = mLocationClient.getLastLocation(); + if (mGoogleApiClient != null) { + if (mGoogleApiClient.isConnected()) { + Location loc = FusedLocationApi.getLastLocation(mGoogleApiClient); if (loc != null) { LatLng mCurrentLocation = new LatLng(loc.getLatitude(), loc.getLongitude()); @@ -3695,7 +3740,7 @@ public void onConnectionFailed(ConnectionResult connectionResult) { */ @Override public void onConnected(Bundle connectionHint) { - Location mCurrentLocation = mLocationClient.getLastLocation(); + Location mCurrentLocation = FusedLocationApi.getLastLocation(mGoogleApiClient); boolean autodetectServerTriggered = false; if ((!mMapFailed)) { @@ -3726,8 +3771,7 @@ public void onConnected(Bundle connectionHint) { if ((mOTPApp.getSelectedServer() != null) && (!LocationUtil .checkPointInBoundingBox(mCurrentLatLng, - mOTPApp.getSelectedServer(), - OTPApp.CHECK_BOUNDS_ACCEPTABLE_ERROR)) + mOTPApp.getSelectedServer())) && (((mSavedLastLocationCheckedForServer != null) && (distance[0] > OTPApp.COORDINATES_IMPORTANT_DIFFERENCE)) || (mSavedLastLocationCheckedForServer == null))) { @@ -3743,8 +3787,7 @@ public void onConnected(Bundle connectionHint) { Server selectedServer = mOTPApp.getSelectedServer(); if ((selectedServer != null) && selectedServer.areBoundsSet()) { if (LocationUtil - .checkPointInBoundingBox(mCurrentLatLng, selectedServer, - OTPApp.CHECK_BOUNDS_ACCEPTABLE_ERROR)) { + .checkPointInBoundingBox(mCurrentLatLng, selectedServer)) { mMap.animateCamera(CameraUpdateFactory .newLatLngZoom(mCurrentLatLng, getServerInitialZoom(selectedServer))); @@ -3787,7 +3830,7 @@ private boolean checkServersAreUpdated() { } @Override - public void onDisconnected() { + public void onConnectionSuspended(int i) { } /** diff --git a/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/pois/Nominatim.java b/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/pois/Nominatim.java index 647c4123..ded6a836 100644 --- a/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/pois/Nominatim.java +++ b/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/pois/Nominatim.java @@ -16,12 +16,12 @@ package edu.usf.cutr.opentripplanner.android.pois; -import android.util.Log; - import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; +import android.util.Log; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -63,7 +63,10 @@ public class Nominatim implements Places { private static final String TAG_NAME = "display_name"; - public Nominatim() { + private String mApiKey; + + public Nominatim(String apiKey) { + mApiKey = apiKey; } // http://open.mapquestapi.com/nominatim/v1/search?format=json&q=Walmart&viewbox=-82.8511308,27.6236434,-82.0559399,28.3251809&bounded=1 @@ -100,6 +103,8 @@ public JSONArray requestPlaces(String paramName, String left, String top, String request += "&bounded=1"; } + request += "&key=" + mApiKey; + Log.d(OTPApp.TAG, request); HttpURLConnection urlConnection = null; diff --git a/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/tasks/ServerSelector.java b/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/tasks/ServerSelector.java index 65204301..c8d1929a 100644 --- a/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/tasks/ServerSelector.java +++ b/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/tasks/ServerSelector.java @@ -16,6 +16,8 @@ package edu.usf.cutr.opentripplanner.android.tasks; +import com.google.android.gms.maps.model.LatLng; + import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; @@ -30,8 +32,6 @@ import android.widget.EditText; import android.widget.Toast; -import com.google.android.gms.maps.model.LatLng; - import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -317,9 +317,7 @@ private Server findOptimalSever(LatLng currentLocation) { boolean isInBoundingBox; Server server = null; for (Server knownServer : knownServers) { - // Check bounds here to find server - acceptable error is set to 1000m = 1km - isInBoundingBox = LocationUtil - .checkPointInBoundingBox(currentLocation, knownServer, 1000); + isInBoundingBox = LocationUtil.checkPointInBoundingBox(currentLocation, knownServer); if (isInBoundingBox) { server = knownServer; diff --git a/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/util/LocationUtil.java b/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/util/LocationUtil.java index 6442b382..cc710209 100644 --- a/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/util/LocationUtil.java +++ b/opentripplanner-android/src/main/java/edu/usf/cutr/opentripplanner/android/util/LocationUtil.java @@ -17,6 +17,7 @@ package edu.usf.cutr.opentripplanner.android.util; import com.google.android.gms.maps.model.LatLng; +import com.google.maps.android.PolyUtil; import android.content.Context; import android.content.SharedPreferences; @@ -36,7 +37,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; import edu.usf.cutr.opentripplanner.android.OTPApp; import edu.usf.cutr.opentripplanner.android.R; @@ -45,7 +45,6 @@ import edu.usf.cutr.opentripplanner.android.pois.Nominatim; import edu.usf.cutr.opentripplanner.android.pois.POI; import edu.usf.cutr.opentripplanner.android.pois.Places; -import edu.usf.cutr.opentripplanner.android.util.CustomAddress; /** * Various utilities related to location data @@ -104,48 +103,26 @@ public static List decodePoly(String encoded) { * * @param location current location of the user * @param selectedServer OTP server being compared to the current location - * @param acceptableError the amount of allowed error, in meters * @return true if the location of the user is within the bounding box of the selectedServer, * false if it is not */ - public static boolean checkPointInBoundingBox(LatLng location, Server selectedServer, - int acceptableError) { - float[] resultLeft = new float[3]; - float[] resultRight = new float[3]; - float[] resultUp = new float[3]; - float[] resultDown = new float[3]; - float[] resultHorizontal = new float[3]; - float[] resultVertical = new float[3]; - - double locationLat = location.latitude; - double locationLon = location.longitude; - - double leftLat = locationLat; - double leftLon = selectedServer.getLowerLeftLongitude(); - double rightLat = locationLat; - double rightLon = selectedServer.getUpperRightLongitude(); - - Location.distanceBetween(locationLat, locationLon, leftLat, leftLon, resultLeft); - Location.distanceBetween(locationLat, locationLon, rightLat, rightLon, resultRight); - - double upLat = selectedServer.getUpperRightLatitude(); - double upLon = locationLon; - double downLat = selectedServer.getLowerLeftLatitude(); - double downLon = locationLon; - - Location.distanceBetween(locationLat, locationLon, upLat, upLon, resultUp); - Location.distanceBetween(locationLat, locationLon, downLat, downLon, resultDown); - - Location.distanceBetween(locationLat, leftLon, locationLat, rightLon, resultHorizontal); - Location.distanceBetween(upLat, locationLon, downLat, locationLon, resultVertical); - - if (resultLeft[0] + resultRight[0] - resultHorizontal[0] > acceptableError) { - return false; - } else if (resultUp[0] + resultDown[0] - resultVertical[0] > acceptableError) { - return false; - } - - return true; + public static boolean checkPointInBoundingBox(LatLng location, Server selectedServer) { + LatLng lowerLeft = new LatLng(selectedServer.getLowerLeftLatitude(), + selectedServer.getLowerLeftLongitude()); + LatLng upperLeft = new LatLng(selectedServer.getUpperRightLatitude(), + selectedServer.getLowerLeftLongitude()); + LatLng upperRight = new LatLng(selectedServer.getUpperRightLatitude(), + selectedServer.getUpperRightLongitude()); + LatLng lowerRight = new LatLng(selectedServer.getLowerLeftLatitude(), + selectedServer.getUpperRightLongitude()); + + List rectangle = new ArrayList(2); + rectangle.add(lowerLeft); + rectangle.add(upperLeft); + rectangle.add(upperRight); + rectangle.add(lowerRight); + + return PolyUtil.containsLocation(location, rectangle, true); } public static ArrayList processGeocoding(Context context, Server selectedServer, @@ -198,8 +175,7 @@ public static ArrayList processGeocoding(Context context, Server Geocoder gc = new Geocoder(context); try { List
androidTypeAddresses; - //TODO Temporary workaround while Google does not solve the problem with Android Geocoder, see issue #396 - /*if (selectedServer != null) { + if (selectedServer != null) { androidTypeAddresses = gc.getFromLocationName(address, context.getResources().getInteger(R.integer.geocoder_max_results), selectedServer.getLowerLeftLatitude(), @@ -209,13 +185,6 @@ public static ArrayList processGeocoding(Context context, Server } else { androidTypeAddresses = gc.getFromLocationName(address, context.getResources().getInteger(R.integer.geocoder_max_results)); - }*/ - if (geocodingForMarker){ - androidTypeAddresses = gc.getFromLocationName(address, - context.getResources().getInteger(R.integer.geocoder_max_results)); - } - else{ - androidTypeAddresses = new ArrayList
(); } for (Address androidTypeAddress : androidTypeAddresses){ addresses.add(new CustomAddress(androidTypeAddress)); @@ -294,8 +263,8 @@ private static List filterAddressesBBox(Server selectedServer, Li for (Iterator it=addresses.iterator(); it.hasNext();) { CustomAddress address = it.next(); if (!LocationUtil.checkPointInBoundingBox( - new LatLng(address.getLatitude(), address.getLongitude()), selectedServer, - OTPApp.CHECK_BOUNDS_ACCEPTABLE_ERROR)) { + new LatLng(address.getLatitude(), address.getLongitude()), + selectedServer)) { it.remove(); } } @@ -306,14 +275,16 @@ private static List filterAddressesBBox(Server selectedServer, Li /** * Try to grab the developer key from an unversioned resource file, if it exists * - * @return the developer key from an unversioned resource file, or empty string if it doesn't + * @param context + * @param apiKeyResourceId Resource ID of the raw file containing the API key + * @return the developer key from a resource file, or empty string if it doesn't * exist */ - private static String getKeyFromResource(Context context) { + private static String getKeyFromResource(Context context, int apiKeyResourceId) { String strKey = ""; try { - InputStream in = context.getResources().openRawResource(R.raw.googleplaceskey); + InputStream in = context.getResources().openRawResource(apiKeyResourceId); BufferedReader r = new BufferedReader(new InputStreamReader(in)); StringBuilder total = new StringBuilder(); @@ -351,7 +322,7 @@ private static List searchPlaces(Context context, Server selected ); params.put(GooglePlaces.PARAM_RADIUS, Double.toString(selectedServer.getRadius())); } - p = new GooglePlaces(getKeyFromResource(context)); + p = new GooglePlaces(getKeyFromResource(context, R.raw.googleplaceskey)); Log.d(OTPApp.TAG, "Using Google Places!"); } else { @@ -367,7 +338,7 @@ private static List searchPlaces(Context context, Server selected Double.toString(selectedServer.getUpperRightLatitude())); } - p = new Nominatim(); + p = new Nominatim(getKeyFromResource(context, R.raw.mapquestgeocoderkey)); Log.d(OTPApp.TAG, "Using Nominatim!"); } diff --git a/opentripplanner-android/src/main/res/drawable/arrow.3.png b/opentripplanner-android/src/main/res/drawable/arrow.3.png deleted file mode 100644 index 052468ae..00000000 Binary files a/opentripplanner-android/src/main/res/drawable/arrow.3.png and /dev/null differ diff --git a/opentripplanner-android/src/main/res/layout-land-ldpi-v14/main.xml b/opentripplanner-android/src/main/res/layout-land-ldpi-v14/main.xml deleted file mode 100644 index 41241b4d..00000000 --- a/opentripplanner-android/src/main/res/layout-land-ldpi-v14/main.xml +++ /dev/null @@ -1,371 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - android:visibility="gone"> - - - android:padding="4dp"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/opentripplanner-android/src/main/res/layout-land-ldpi/main.xml b/opentripplanner-android/src/main/res/layout-land-ldpi/main.xml deleted file mode 100644 index e13ec618..00000000 --- a/opentripplanner-android/src/main/res/layout-land-ldpi/main.xml +++ /dev/null @@ -1,377 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - android:visibility="gone"> - - - android:padding="4dp"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/opentripplanner-android/src/main/res/layout-land-v14/main.xml b/opentripplanner-android/src/main/res/layout-land-v14/main.xml deleted file mode 100644 index 0689befd..00000000 --- a/opentripplanner-android/src/main/res/layout-land-v14/main.xml +++ /dev/null @@ -1,371 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - android:padding="4dp"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/opentripplanner-android/src/main/res/layout-land/main.xml b/opentripplanner-android/src/main/res/layout-land/main.xml deleted file mode 100644 index 6381afb3..00000000 --- a/opentripplanner-android/src/main/res/layout-land/main.xml +++ /dev/null @@ -1,377 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - android:padding="4dp"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/opentripplanner-android/src/main/res/layout-ldpi-v14/main.xml b/opentripplanner-android/src/main/res/layout-ldpi-v14/main.xml index 36cd3cb3..676c0199 100644 --- a/opentripplanner-android/src/main/res/layout-ldpi-v14/main.xml +++ b/opentripplanner-android/src/main/res/layout-ldpi-v14/main.xml @@ -58,7 +58,7 @@ - - - - - - - - - - - - - - android:padding="4dp"> - - - - - - - - - - - + android:scrollbarStyle="outsideOverlay"> - - + android:orientation="vertical" + android:padding="8dp"> - - - + + + + + + + + + + + + + + + + + + android:orientation="vertical" + android:layout_below="@id/layoutOptimization" + android:paddingBottom="8dp"> - - - + + android:padding="4dp"> + - + + + + + + + + + - + + + + + + + + + + + - + - + - + - + - + - - - + + + + + + + + + + + + + + + + + + + + + android:orientation="vertical" + android:divider="?android:attr/dividerHorizontal" + android:showDividers="middle"> - - + android:layout_below="@id/bikeParametersLayout" + android:text="@string/menu_button_settings" + android:background="?android:attr/selectableItemBackground" + android:padding="16dp"/> + +