package com.purvotara.airbnbmapexample.ui.activity; import android.Manifest; import android.app.ProgressDialog; import android.content.Context; import android.content.pm.PackageManager; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.AdapterView; import android.widget.AutoCompleteTextView; import android.widget.ImageView; import android.widget.Toast; import com.directions.route.AbstractRouting; import com.directions.route.Route; import com.directions.route.RouteException; import com.directions.route.Routing; import com.directions.route.RoutingListener; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.PendingResult; import com.google.android.gms.common.api.ResultCallback; import com.google.android.gms.location.places.Place; import com.google.android.gms.location.places.PlaceBuffer; import com.google.android.gms.location.places.Places; import com.google.android.gms.maps.CameraUpdate; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapsInitializer; import com.google.android.gms.maps.SupportMapFragment; 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.MarkerOptions; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; import com.purvotara.airbnbmapexample.R; import com.purvotara.airbnbmapexample.ui.adapter.PlaceAutocompleteAdapter; import com.purvotara.airbnbmapexample.ui.util.Util; import java.util.ArrayList; import java.util.List; import butterknife.ButterKnife; import butterknife.InjectView; import butterknife.OnClick; /** * Created by skyrreasure on 12/5/16. */ public class ShowDirectionActivity extends AppCompatActivity implements RoutingListener, GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks { protected GoogleMap map; protected LatLng start; protected LatLng end; @InjectView(R.id.start) AutoCompleteTextView starting; @InjectView(R.id.destination) AutoCompleteTextView destination; @InjectView(R.id.send) ImageView send; private PlaceAutocompleteAdapter mAdapter; private ProgressDialog progressDialog; private static final String LOG_TAG = "ShowDirectionActivity"; protected GoogleApiClient mGoogleApiClient; private List<Polyline> polylines; private double mLatitude = 12.321432423, mLongitude = 77.2342345; private double toLatitude, toLongitude; private static final int[] COLORS = new int[]{R.color.primary_dark, R.color.primary, R.color.primary_light, R.color.accent, R.color.primary_dark_material_light}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_show_direction); ButterKnife.inject(this); getSupportActionBar().setDisplayShowHomeEnabled(true); getSupportActionBar().setTitle("Show Direction Example"); polylines = new ArrayList<>(); mGoogleApiClient = new GoogleApiClient.Builder(this) .addApi(Places.GEO_DATA_API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); MapsInitializer.initialize(this); mGoogleApiClient.connect(); SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); if (mapFragment == null) { mapFragment = SupportMapFragment.newInstance(); getSupportFragmentManager().beginTransaction().replace(R.id.map, mapFragment).commit(); } map = mapFragment.getMap(); mAdapter = new PlaceAutocompleteAdapter(this, android.R.layout.simple_list_item_1, mGoogleApiClient, null, null); /* * Updates the bounds being used by the auto complete adapter based on the position of the * map. * */ map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() { @Override public void onCameraChange(CameraPosition position) { LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds; mAdapter.setBounds(bounds); } }); LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } locationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, 5000, 0, new LocationListener() { @Override public void onLocationChanged(Location location) { mLatitude = location.getLatitude(); mLongitude = location.getLongitude(); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } }); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 0, new LocationListener() { @Override public void onLocationChanged(Location location) { mLatitude = location.getLatitude(); mLongitude = location.getLongitude(); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } }); /* * Adds auto complete adapter to both auto complete * text views. * */ starting.setAdapter(mAdapter); destination.setAdapter(mAdapter); /* * Sets the start and destination points based on the values selected * from the autocomplete text views. * */ starting.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { final PlaceAutocompleteAdapter.PlaceAutocomplete item = mAdapter.getItem(position); final String placeId = String.valueOf(item.placeId); Log.i(LOG_TAG, "Autocomplete item selected: " + item.description); /* Issue a request to the Places Geo Data API to retrieve a Place object with additional details about the place. */ PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi .getPlaceById(mGoogleApiClient, placeId); placeResult.setResultCallback(new ResultCallback<PlaceBuffer>() { @Override public void onResult(PlaceBuffer places) { if (!places.getStatus().isSuccess()) { // Request did not complete successfully Log.e(LOG_TAG, "Place query did not complete. Error: " + places.getStatus().toString()); places.release(); return; } // Get the Place object from the buffer. final Place place = places.get(0); start = place.getLatLng(); mLatitude = place.getLatLng().latitude; mLongitude = place.getLatLng().longitude; } }); } }); destination.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { final PlaceAutocompleteAdapter.PlaceAutocomplete item = mAdapter.getItem(position); final String placeId = String.valueOf(item.placeId); Log.i(LOG_TAG, "Autocomplete item selected: " + item.description); /* Issue a request to the Places Geo Data API to retrieve a Place object with additional details about the place. */ PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi .getPlaceById(mGoogleApiClient, placeId); placeResult.setResultCallback(new ResultCallback<PlaceBuffer>() { @Override public void onResult(PlaceBuffer places) { if (!places.getStatus().isSuccess()) { // Request did not complete successfully Log.e(LOG_TAG, "Place query did not complete. Error: " + places.getStatus().toString()); places.release(); return; } // Get the Place object from the buffer. final Place place = places.get(0); toLatitude = place.getLatLng().latitude; toLongitude = place.getLatLng().longitude; end = place.getLatLng(); } }); } }); /* These text watchers set the start and end points to null because once there's * a change after a value has been selected from the dropdown * then the value has to reselected from dropdown to get * the correct location. * */ starting.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int startNum, int before, int count) { if (start != null) { start = null; } } @Override public void afterTextChanged(Editable s) { } }); destination.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { if (end != null) { end = null; } } @Override public void afterTextChanged(Editable s) { } }); } @OnClick(R.id.send) public void sendRequest() { if (Util.Operations.isOnline(this)) { route(); } else { Toast.makeText(this, "No internet connectivity", Toast.LENGTH_SHORT).show(); } } public void route() { if (start == null || end == null) { if (start == null) { if (starting.getText().length() > 0) { starting.setError("Choose location from dropdown."); } else { Toast.makeText(this, "Please choose a starting point.", Toast.LENGTH_SHORT).show(); } } if (end == null) { if (destination.getText().length() > 0) { destination.setError("Choose location from dropdown."); } else { Toast.makeText(this, "Please choose a destination.", Toast.LENGTH_SHORT).show(); } } } else { progressDialog = ProgressDialog.show(this, "Please wait.", "Fetching route information.", true); Routing routing = new Routing.Builder() .travelMode(AbstractRouting.TravelMode.DRIVING) .withListener(this) .alternativeRoutes(true) .waypoints(start, end) .build(); routing.execute(); CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(mLatitude, mLongitude)); CameraUpdate zoom = CameraUpdateFactory.zoomTo(14); map.moveCamera(center); map.animateCamera(zoom); hideKeyboard(); } } @Override public void onRoutingFailure(RouteException e) { // The Routing request failed progressDialog.dismiss(); if (e != null) { Toast.makeText(this, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show(); } else { Toast.makeText(this, "Something went wrong, Try again", Toast.LENGTH_SHORT).show(); } } @Override public void onRoutingStart() { // The Routing Request starts } @Override public void onRoutingSuccess(ArrayList<Route> route, int ii) { progressDialog.dismiss(); CameraUpdate center = CameraUpdateFactory.newLatLng(start); CameraUpdate zoom = CameraUpdateFactory.zoomTo(16); map.moveCamera(center); if (polylines.size() > 0) { for (Polyline poly : polylines) { poly.remove(); } } polylines = new ArrayList<>(); //add route(s) to the map. for (int i = 0; i < route.size(); i++) { //In case of more than 5 alternative routes int colorIndex = i % COLORS.length; PolylineOptions polyOptions = new PolylineOptions(); polyOptions.color(getResources().getColor(COLORS[colorIndex])); polyOptions.width(10 + i * 3); polyOptions.addAll(route.get(i).getPoints()); Polyline polyline = map.addPolyline(polyOptions); polylines.add(polyline); Toast.makeText(getApplicationContext(), "Route " + (i + 1) + ": distance - " + route.get(i).getDistanceValue() + ": duration - " + route.get(i).getDurationValue(), Toast.LENGTH_SHORT).show(); } // Start marker MarkerOptions options = new MarkerOptions(); options.position(start); options.icon(BitmapDescriptorFactory.fromResource(R.drawable.start_blue)); map.addMarker(options); // End marker options = new MarkerOptions(); options.position(end); options.icon(BitmapDescriptorFactory.fromResource(R.drawable.end_green)); map.addMarker(options); } @Override public void onRoutingCancelled() { Log.i(LOG_TAG, "Routing was cancelled."); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.v(LOG_TAG, connectionResult.toString()); } @Override public void onConnected(Bundle bundle) { } @Override public void onConnectionSuspended(int i) { } public void hideKeyboard() { // Check if no view has focus: View view = this.getCurrentFocus(); if (view != null) { InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE); inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS); } } }