I have a map activity which loads too slow and I want to have a faster map activity. How can I achieve this? I heard pre-loading the map is effective but I am not sure how to do this. I am not going to post my whole map activity because it is a little confusing but I will post a base sample(from Github) which I used the same way to load the map.
import android.app.ProgressDialog;
import android.graphics.Color;
import android.location.Location;
import android.net.Uri;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.android.gms.appindexing.Action;
import com.google.android.gms.appindexing.AppIndex;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
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.maps.android.SphericalUtil;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class MapsActivity extends FragmentActivity implements
OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
GoogleMap.OnMarkerDragListener,
GoogleMap.OnMapLongClickListener,
View.OnClickListener{
//Our Map
private GoogleMap mMap;
//To store longitude and latitude from map
private double longitude;
private double latitude;
//From -> the first coordinate from where we need to calculate the distance
private double fromLongitude;
private double fromLatitude;
//To -> the second coordinate to where we need to calculate the distance
private double toLongitude;
private double toLatitude;
//Google ApiClient
private GoogleApiClient googleApiClient;
//Our buttons
private Button buttonSetTo;
private Button buttonSetFrom;
private Button buttonCalcDistance;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
//Initializing googleapi client
// ATTENTION: This "addApi(AppIndex.API)"was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.addApi(AppIndex.API).build();
buttonSetTo = (Button) findViewById(R.id.buttonSetTo);
buttonSetFrom = (Button) findViewById(R.id.buttonSetFrom);
buttonCalcDistance = (Button) findViewById(R.id.buttonCalcDistance);
buttonSetTo.setOnClickListener(this);
buttonSetFrom.setOnClickListener(this);
buttonCalcDistance.setOnClickListener(this);
}
#Override
protected void onStart() {
googleApiClient.connect();
super.onStart();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Maps Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://net.simplifiedcoding.googlemapsdistancecalc/http/host/path")
);
AppIndex.AppIndexApi.start(googleApiClient, viewAction);
}
#Override
protected void onStop() {
googleApiClient.disconnect();
super.onStop();
// ATTENTION: This was auto-generated to implement the App Indexing API.
// See https://g.co/AppIndexing/AndroidStudio for more information.
Action viewAction = Action.newAction(
Action.TYPE_VIEW, // TODO: choose an action type.
"Maps Page", // TODO: Define a title for the content shown.
// TODO: If you have web page content that matches this app activity's content,
// make sure this auto-generated web page URL is correct.
// Otherwise, set the URL to null.
Uri.parse("http://host/path"),
// TODO: Make sure this auto-generated app deep link URI is correct.
Uri.parse("android-app://net.simplifiedcoding.googlemapsdistancecalc/http/host/path")
);
AppIndex.AppIndexApi.end(googleApiClient, viewAction);
}
//Getting current location
private void getCurrentLocation() {
mMap.clear();
//Creating a location object
Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (location != null) {
//Getting longitude and latitude
longitude = location.getLongitude();
latitude = location.getLatitude();
//moving the map to location
moveMap();
}
}
//Function to move the map
private void moveMap() {
//Creating a LatLng Object to store Coordinates
LatLng latLng = new LatLng(latitude, longitude);
//Adding marker to map
mMap.addMarker(new MarkerOptions()
.position(latLng) //setting position
.draggable(true) //Making the marker draggable
.title("Current Location")); //Adding a title
//Moving the camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
//Animating the camera
mMap.animateCamera(CameraUpdateFactory.zoomTo(15));
}
public String makeURL (double sourcelat, double sourcelog, double destlat, double destlog ){
StringBuilder urlString = new StringBuilder();
urlString.append("https://maps.googleapis.com/maps/api/directions/json");
urlString.append("?origin=");// from
urlString.append(Double.toString(sourcelat));
urlString.append(",");
urlString
.append(Double.toString( sourcelog));
urlString.append("&destination=");// to
urlString
.append(Double.toString( destlat));
urlString.append(",");
urlString.append(Double.toString(destlog));
urlString.append("&sensor=false&mode=driving&alternatives=true");
urlString.append("&key=AIzaSyCJVpM7-ayGMraxFRzq4U8Dt1uRNsmiaws");
return urlString.toString();
}
private void getDirection(){
//Getting the URL
String url = makeURL(fromLatitude, fromLongitude, toLatitude, toLongitude);
//Showing a dialog till we get the route
final ProgressDialog loading = ProgressDialog.show(this, "Getting Route", "Please wait...", false, false);
//Creating a string request
StringRequest stringRequest = new StringRequest(url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
loading.dismiss();
//Calling the method drawPath to draw the path
drawPath(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
loading.dismiss();
}
});
//Adding the request to request queue
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
//The parameter is the server response
public void drawPath(String result) {
//Getting both the coordinates
LatLng from = new LatLng(fromLatitude,fromLongitude);
LatLng to = new LatLng(toLatitude,toLongitude);
//Calculating the distance in meters
Double distance = SphericalUtil.computeDistanceBetween(from, to);
//Displaying the distance
Toast.makeText(this,String.valueOf(distance+" Meters"),Toast.LENGTH_SHORT).show();
try {
//Parsing json
final JSONObject json = new JSONObject(result);
JSONArray routeArray = json.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
List<LatLng> list = decodePoly(encodedString);
Polyline line = mMap.addPolyline(new PolylineOptions()
.addAll(list)
.width(20)
.color(Color.RED)
.geodesic(true)
);
}
catch (JSONException e) {
}
}
private List<LatLng> decodePoly(String encoded) {
List<LatLng> poly = new ArrayList<LatLng>();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
LatLng p = new LatLng( (((double) lat / 1E5)),
(((double) lng / 1E5) ));
poly.add(p);
}
return poly;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng latLng = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.setOnMarkerDragListener(this);
mMap.setOnMapLongClickListener(this);
}
#Override
public void onConnected(Bundle bundle) {
getCurrentLocation();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onMapLongClick(LatLng latLng) {
//Clearing all the markers
mMap.clear();
//Adding a new marker to the current pressed position
mMap.addMarker(new MarkerOptions()
.position(latLng)
.draggable(true));
latitude = latLng.latitude;
longitude = latLng.longitude;
}
#Override
public void onMarkerDragStart(Marker marker) {
}
#Override
public void onMarkerDrag(Marker marker) {
}
#Override
public void onMarkerDragEnd(Marker marker) {
//Getting the coordinates
latitude = marker.getPosition().latitude;
longitude = marker.getPosition().longitude;
//Moving the map
moveMap();
}
#Override
public void onClick(View v) {
if(v == buttonSetFrom){
fromLatitude = latitude;
fromLongitude = longitude;
Toast.makeText(this,"From set",Toast.LENGTH_SHORT).show();
}
if(v == buttonSetTo){
toLatitude = latitude;
toLongitude = longitude;
Toast.makeText(this,"To set",Toast.LENGTH_SHORT).show();
}
if(v == buttonCalcDistance){
getDirection();
}
}
}
Thank you in advance.
Use hardware acceleration.
For entire application put this in manifest file:
<application android:hardwareAccelerated="true">
Disable acceleration for some activities where you don't want to:
<application android:hardwareAccelerated="true">
<activity ... />
<activity android:hardwareAccelerated="false" />
</application>
I found an answer to my question but I know it is not the best answer because of that I won't mark it as the true answer in order to make a motivation for others to find better answers. I added the following code in onMapReady:
googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
I changed the map type from normal to terrain and this solution caused the map to load faster.
Related
Here is my manifest of how i declared my MapsActivity
<activity android:name=".MapsActivity"/>
It still shows an error Validates resource references inside android xml files Android And the activity crashes. Here is my MapsActivity
package com.todaysfuture.autometer;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.IntentSender;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
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 java.io.IOException;
import java.util.List;
import java.util.Locale;
public class MapsActivity extends Fragment implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
public static final String TAG = MapsActivity.class.getSimpleName();
/*
* Define a request code to send to Google Play services
* This code is returned in Activity.onActivityResult
*/
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private TextView tvStartRide;
private TextView tvStopRide;
private Location startingLocation;
private Location endingLocation;
private String origin = null ;
private String destination = null ;
private Location location1 ;
private Location location2 ;
private LatLng loc1 ;
private LatLng loc2 ;
private float distance = 0 ;
private float fare = 0 ;
private double startLatitude ;
private double startLongitude ;
private double endLatitude ;
private double endLongitude ;
private float[] results ;
public MapsActivity(){
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.activity_maps, container, false);
setUpMapIfNeeded();
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
tvStartRide = (TextView) view.findViewById(R.id.startRideText);
tvStopRide = (TextView) view.findViewById(R.id.stopRideText);
tvStopRide.setVisibility(View.INVISIBLE);
tvStartRide.setOnClickListener(startRideOnClickListener);
tvStopRide.setOnClickListener(stopRideOnClickListener);
return view;
}
View.OnClickListener startRideOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
tvStartRide.setVisibility(View.INVISIBLE);
tvStopRide.setVisibility(View.VISIBLE);
startingLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
location1 = startingLocation ;
startLatitude = location1.getLatitude();
startLongitude = location1.getLongitude();
loc1 = new LatLng(startLatitude, startLongitude) ;
try {
origin = retrieveAddress(startingLocation) ;
Toast.makeText(getContext(), "Ride starting from: " + origin, Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
}
};
View.OnClickListener stopRideOnClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
endingLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
try {
destination = retrieveAddress(endingLocation) ;
Toast.makeText(getContext(), "Ride ended at: " + destination, Toast.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
fare = calculateFare(distance) ;
}
};
public String retrieveAddress(Location location) throws IOException {
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(getActivity(), Locale.getDefault());
double latitude = location.getLatitude();
double longitude = location.getLongitude();
addresses = geocoder.getFromLocation(latitude, longitude, 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5
String address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
/*String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode(); */
String knownName = addresses.get(0).getFeatureName(); // Only if available else return NULL
if (address != null)
return address;
else if (knownName != null)
return knownName;
else
return null;
}
public void drawPolyline(LatLng location1, LatLng location2){
Polyline line = mMap.addPolyline(new PolylineOptions()
.add(location1, location2)
.width(5)
.color(Color.RED));
}
/*#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
} */
#Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
mGoogleApiClient.connect();
}
#Override
public void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
/**
* Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
* installed) and the map has not already been instantiated.. This will ensure that we only ever
* call {#link #setUpMap()} once when {#link #mMap} is not null.
* <p/>
* If it isn't installed {#link SupportMapFragment} (and
* {#link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
* install/update the Google Play services APK on their device.
* <p/>
* A user can return to this FragmentActivity after following the prompt and correctly
* installing/updating/enabling the Google Play services. Since the FragmentActivity may not
* have been completely destroyed during this process (it is likely that it would only be
* stopped or paused), {#link #onCreate(Bundle)} may not be called again so we should call this
* method in {#link #onResume()} to guarantee that it will be called.
*/
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
//mMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
mMap = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
/**
* This is where we can add markers or lines, add listeners or move the camera. In this case, we
* just add a marker near Africa.
* <p/>
* This should only be called once and when we are sure that {#link #mMap} is not null.
*/
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
private void handleNewLocation(Location location) {
Log.d(TAG, location.toString());
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
LatLng latLng = new LatLng(currentLatitude, currentLongitude);
//mMap.addMarker(new MarkerOptions().position(new LatLng(currentLatitude, currentLongitude)).title("Current Location"));
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title("I am here!");
mMap.addMarker(options);
//mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14.0f));
if (location2 == null) {
location2 = location ;
loc2 = latLng ;
endLatitude = loc2.latitude ;
endLongitude = loc2.longitude ;
//drawPolyline(loc1, loc2);
//android.location.Location.distanceBetween(startLatitude, startLongitude, endLatitude, endLongitude, results);
//if ( results != null )
//distance += results[0] ;
Toast.makeText(getActivity(), "Distance: " + distance, Toast.LENGTH_SHORT).show();
}
else {
loc1 = loc2 ;
loc2 = latLng ;
startLatitude = loc1.latitude ;
startLongitude = loc1.longitude ;
endLatitude = loc2.latitude ;
endLongitude = loc2.longitude ;
drawPolyline(loc1, loc2);
android.location.Location.distanceBetween(startLatitude, startLongitude, endLatitude, endLongitude, results);
distance += results[0] ;
Toast.makeText(getActivity(), "Distance: " + distance, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onConnected(Bundle bundle) {
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
} else {
handleNewLocation(location);
}
}
#Override
public void onConnectionSuspended(int i) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Oops!");
builder.setMessage("An error occurred.");
AlertDialog dialog = builder.create();
dialog.show();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(getActivity(), CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
/*
* If no resolution is available, display a dialog to the
* user with the error.
*/
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Oops!");
builder.setMessage("An error occurred.");
AlertDialog dialog = builder.create();
dialog.show();
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
#Override
public void onLocationChanged(Location location) {
handleNewLocation(location);
}
public float calculateFare(float distance) {
float distanceInkm = distance/1000 ;
float firstTwokm = 2 ;
float restOfDistance = distanceInkm - firstTwokm ;
if (distanceInkm >= firstTwokm)
{
fare = 25 ;
while (restOfDistance>=0) {
fare += 0.8 ;
restOfDistance -= 0.1 ;
}
return fare ;
}
else {
while (distanceInkm>=0) {
fare += 1.25 ;
distanceInkm -= 0.1 ;
}
return fare ;
}
}
}
What could be the solution? It is extending a fragment hence it should still be an activity. When i hover the cursor on the declare of the activity in the manifest it says 'com.todaysfuture.autometer.MapsActivity' is not assignable to 'android.app.Activity'
I have used the following code to get the current location and path the route in google map. The problem i faced is that the current device location is not stable all the time. It shows correct location sometime but shows different location like 1km away from actual location.
package com.colors.organisatiom.activity.colors;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.colors.organisatiom.activity.colors.classes.ConnectionManager;
import com.colors.organisatiom.activity.colors.interfaces.PolyLineCallback;
import com.colors.organisatiom.activity.colors.json.GetDistanceFromServer;
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.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
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.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
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 java.util.ArrayList;
import java.util.List;
public class LocationMap extends AppCompatActivity implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private GoogleMap map;
private String serviceCentreLongitude, serviceCentreLatitude, serviceCenhterLocation;
final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
private RelativeLayout connectingParent;
private PolylineOptions polylineOptions;
private Polyline polyline;
private List<Polyline> polylines = new ArrayList<>();
private GoogleApiClient googleApiClient;
private LocationRequest locationRequest;
private static final long INTERVAL = 1 * 5;
private static final long FASTEST_INTERVAL = 10;
protected BroadcastReceiver mNotificationReceiver;
private Marker currentLocationMarker;
protected void createLocationRequest() {
locationRequest = new LocationRequest();
locationRequest.setInterval(INTERVAL);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
serviceCentreLatitude = getIntent().getStringExtra("latitude");
serviceCentreLongitude = getIntent().getStringExtra("longitude");
serviceCenhterLocation = getIntent().getStringExtra("service_center_location");
setContentView(R.layout.content_google_map);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Window window = this.getWindow();
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.setStatusBarColor(ContextCompat.getColor(this, R.color.colorPrimaryDark));
}
mNotificationReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (!LocationMap.this.isFinishing()) {
AlertDialog.Builder builder = new AlertDialog.Builder(LocationMap.this);
builder.setTitle(intent.getStringExtra("title"));
builder.setMessage(intent.getStringExtra("message"));
builder.setPositiveButton("Dismiss", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//alertDialog.dismiss();
}
});
final AlertDialog alertDialog = builder.create();
alertDialog.show();
}
}
};
if (!isGooglePlayServicesAvailable()) {
Toast.makeText(this, "Google play service not supported", Toast.LENGTH_LONG).show();
}
createLocationRequest();
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
connectingParent = (RelativeLayout) findViewById(R.id.connecting_parent);
if (!new ConnectionManager(this).isConnectionToInternet()) {
connectingParent.setVisibility(View.GONE);
Toast.makeText(LocationMap.this, "No internet connection to route path", Toast.LENGTH_LONG).show();
}
ImageView search = (ImageView) findViewById(R.id.search);
search.setVisibility(View.INVISIBLE);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int hasAccessCoarseLocationPermission = checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION);
int hasAccessFineLocationPermission = checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION);
if (hasAccessCoarseLocationPermission != PackageManager.PERMISSION_GRANTED && hasAccessFineLocationPermission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_ASK_PERMISSIONS);
} else {
showMapWithLocation();
if (googleApiClient.isConnected()) {
startLocationUpdates();
}
}
} else {
showMapWithLocation();
if (googleApiClient.isConnected()) {
startLocationUpdates();
}
}
}
#Override
public void onStart() {
super.onStart();
Log.d("Started:", "onStart fired ..............");
googleApiClient.connect();
}
#Override
public void onStop() {
super.onStop();
Log.d("Stopped", "onStop fired ..............");
googleApiClient.disconnect();
Log.d("Is connected status", "isConnected ...............: " + googleApiClient.isConnected());
}
private void showMapWithLocation() {
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
LatLng latLng = new LatLng(Double.parseDouble(serviceCentreLatitude), Double.parseDouble(serviceCentreLongitude));
map.addMarker(new MarkerOptions()
.position(latLng)
.title(serviceCenhterLocation)).showInfoWindow();
map.getUiSettings().setMapToolbarEnabled(false);
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 14);
map.animateCamera(cameraUpdate);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
startLocationUpdates();
if (googleApiClient.isConnected()) {
startLocationUpdates();
}
} else {
Toast.makeText(LocationMap.this, "Cannot show map", Toast.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private List<LatLng> decodePoly(String encoded) {
List<LatLng> poly = new ArrayList<>();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
LatLng p = new LatLng((((double) lat / 1E5)),
(((double) lng / 1E5)));
poly.add(p);
}
return poly;
}
#Override
public void onConnected(Bundle bundle) {
Log.e("Connection status:", "onConnected - isConnected ...............: " + googleApiClient.isConnected());
startLocationUpdates();
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
Log.e("Update started:", "Location update started ..............: ");
}
#Override
public void onLocationChanged(Location location) {
final double myLocationlatitude = location.getLatitude();
final double myLocationlongitude = location.getLongitude();
Log.e("Latitude", String.valueOf(myLocationlatitude));
Log.e("Longitude", String.valueOf(myLocationlongitude));
LatLng latLng = new LatLng(myLocationlatitude, myLocationlongitude);
//drawing the path in google map
//zoom the camera for the first time
if (currentLocationMarker != null) {
currentLocationMarker.remove();
}
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("My current location");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
currentLocationMarker = map.addMarker(markerOptions);
if (polylines == null) {
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 14);
map.animateCamera(cameraUpdate);
}
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
new GetDistanceFromServer(String.valueOf(myLocationlatitude), String.valueOf(myLocationlongitude), serviceCentreLatitude, serviceCentreLongitude).drawPath(new PolyLineCallback() {
#Override
public void polyLinePointsHolder(String points) {
//remove the path and draw the path in google map while updating
if (polylines != null) {
for (Polyline line : polylines) {
line.remove();
}
}
List<LatLng> list = decodePoly(points);
polylineOptions = new PolylineOptions()
.addAll(list)
.width(12)
.color(Color.parseColor("#05b1fb"))
.geodesic(true);
polyline = map.addPolyline(polylineOptions);
polylines.add(polyline);
}
});
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
connectingParent.setVisibility(View.GONE);
super.onPostExecute(aVoid);
}
}.execute();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e("Connection Failed", connectionResult.getErrorMessage());
}
#Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
googleApiClient, this);
Log.d("TAG", "Location update stopped .......................");
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
#Override
public void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mNotificationReceiver, new IntentFilter("1000"));
if (googleApiClient.isConnected()) {
startLocationUpdates();
Log.d("TAG", "Location update resumed .....................");
}
}
}
The accuracy of location can be affected due to many factors including GPS coverage, device quality and wifi availability around the area. What you can do is to check the accuracy of the location you obtained and decide whether to proceed or not. For this you can use hasAccuracy() and getAccuracy() methods of the Location object.
Here is a quote from the documentation about getAccuracy method
Get the estimated accuracy of this location, in meters.
We define accuracy as the radius of 68% confidence. In other words, if
you draw a circle centered at this location's latitude and longitude,
and with a radius equal to the accuracy, then there is a 68%
probability that the true location is inside the circle.
In statistical terms, it is assumed that location errors are random
with a normal distribution, so the 68% confidence circle represents
one standard deviation. Note that in practice, location errors do not
always follow such a simple distribution.
This accuracy estimation is only concerned with horizontal accuracy,
and does not indicate the accuracy of bearing, velocity or altitude if
those are included in this Location.
If this location does not have an accuracy, then 0.0 is returned. All
locations generated by the LocationManager include an accuracy.
In your onLocationChanged method, you can do the following
#Override
public void onLocationChanged(Location location) {
if(location.hasAccuracy() && location.getAccuracy() < 100F) {
// the location has accuracy and has an accuracy span within 100m radius
// do whatever you want with this location and stop location listener
stopLocationUpdates();
}
// if the above code did not get executed, the location listener will work
// until a location with acceptable accuracy is obtained
}
I have this class to get actual location , the second point (marker) is set by another fragment.
I really need to update my location automatically instead clicking the google button for it.
How can I make this? What is the best way to make this? I donĀ“t figure out where to place it.
I was thinking in placing a timer or something like that. I would prefer to make it with just google maps functionalities.
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
}
}, 0, 500000);
Or with a handler
final Runnable r = new Runnable() {
public void run() {
//Here add your code location listener call
handler.postDelayed(this, 300000 );
}
};
handler.postDelayed(r, 300000 );
Here is the googleXdon class:
package com.example.mysqltest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import org.json.JSONObject;
import android.content.Context;
import android.graphics.Color;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.Toast;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
public class googleXdon extends Fragment {
static GoogleMap map;
static LatLng myPosition;
static RadioButton rbDriving;
static RadioButton rbBiCycling;
static RadioButton rbWalking;
RadioGroup rgModes;
static ArrayList<LatLng> markerPoints;
static int mMode=0;
final static int MODE_DRIVING=0;
final static int MODE_BICYCLING=1;
final static int MODE_WALKING=2;
int fragVal;
static Context ontext2;
static googleXdon init(int val, Context contexts) {
googleXdon X = new googleXdon();
ontext2 = contexts;
// Supply val input as an argument.
Bundle args = new Bundle();
args.putInt("val", val);
X.setArguments(args);
return X;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View layoutView = inflater.inflate(R.layout.actgooglex, container,
false);
fragVal = getArguments() != null ? getArguments().getInt("val") : 1;
// Getting reference to rb_driving
rbDriving = (RadioButton) layoutView.findViewById(R.id.rb_driving);
// Getting reference to rb_bicylcing
rbBiCycling = (RadioButton) layoutView.findViewById(R.id.rb_bicycling);
// Getting reference to rb_walking
rbWalking = (RadioButton) layoutView.findViewById(R.id.rb_walking);
// Getting Reference to rg_modes
rgModes = (RadioGroup) layoutView.findViewById(R.id.rg_modes);
rgModes.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
// Checks, whether start and end locations are captured
if(markerPoints.size() >= 2){
LatLng origin = markerPoints.get(0);
LatLng dest = markerPoints.get(1);
// Getting URL to the Google Directions API
String url = getDirectionsUrl(origin, dest);
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
}
}
});
// Initializing
markerPoints = new ArrayList<LatLng>();
// Getting reference to SupportMapFragment of the activity_main
SupportMapFragment fm = (SupportMapFragment)getFragmentManager().findFragmentById(R.id.map);
// Getting Map for the SupportMapFragment
map = fm.getMap();
// Enable MyLocation Button in the Map
map.setMyLocationEnabled(true);
// Getting LocationManager object from System Service LOCATION_SERVICE
/*LocationManager locationManager = (LocationManager) ontext2.getSystemService(Context.LOCATION_SERVICE);
// Creating a criteria object to retrieve provider
Criteria criteria = new Criteria();
// Getting the name of the best provider
String provider = locationManager.getBestProvider(criteria, true);
// Getting Current Location
Location location = locationManager.getLastKnownLocation(provider);
if(location!=null) {
// Getting latitude of the current location
double latitude = location.getLatitude();
// Getting longitude of the current location
double longitude = location.getLongitude();
// Creating a LatLng object for the current location
LatLng latLng = new LatLng(latitude, longitude);
myPosition = new LatLng(latitude, longitude);
markerPoints.add(myPosition);*/
// Setting onclick event listener for the map
/* map.setOnMapClickListener(new OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
// Already two locations value is 1
if(markerPoints.size()>1){
markerPoints.clear();
map.clear();
}
// Adding new item to the ArrayList
markerPoints.add(point);
// Draws Start and Stop markers on the Google Map
drawStartStopMarkers();
// Checks, whether start and end locations are captured
if(markerPoints.size() >= 2){
LatLng origin = markerPoints.get(0);
LatLng dest = markerPoints.get(1);
// Getting URL to the Google Directions API
String url = getDirectionsUrl(origin, dest);
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
}
}
});
}*/
return layoutView;
}
//este antes no era final
public static void agregarMarket( LatLng point) {
// Already two locations
if(markerPoints.size()>1){
markerPoints.clear();
map.clear();
}
// Getting LocationManager object from System Service LOCATION_SERVICE
LocationManager locationManager = (LocationManager) ontext2.getSystemService(Context.LOCATION_SERVICE);
// Creating a criteria object to retrieve provider
Criteria criteria = new Criteria();
// Getting the name of the best provider
String provider = locationManager.getBestProvider(criteria, true);
// Getting Current Location
Location location = locationManager.getLastKnownLocation(provider);
if(location!=null) {
// Getting latitude of the current location
double latitude = location.getLatitude();
// Getting longitude of the current location
double longitude = location.getLongitude();
// Creating a LatLng object for the current location
LatLng latLng = new LatLng(latitude, longitude);
myPosition = new LatLng(latitude, longitude);
markerPoints.add(myPosition);
// Adding new item to the ArrayList
markerPoints.add(point);
// Draws Start and Stop markers on the Google Map
drawStartStopMarkers();
// Checks, whether start and end locations are captured
if(markerPoints.size() >= 2){
LatLng origin = markerPoints.get(0);
LatLng dest = markerPoints.get(1);
// Getting URL to the Google Directions API
String url = getDirectionsUrl(origin, dest);
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
}
}
}
// Drawing Start and Stop locations
private static void drawStartStopMarkers(){
for(int i=0;i<markerPoints.size();i++){
// Creating MarkerOptions
MarkerOptions options = new MarkerOptions();
// Setting the position of the marker
options.position(markerPoints.get(i) );
/**
* For the start location, the color of marker is GREEN and
* for the end location, the color of marker is RED.
*/
if(i==0){
options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
}else if(i==1){
options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
}
// Add new marker to the Google Map Android API V2
map.addMarker(options);
}
}
private static String getDirectionsUrl(LatLng origin,LatLng dest){
// Origin of route
String str_origin = "origin="+origin.latitude+","+origin.longitude;
// Destination of route
String str_dest = "destination="+dest.latitude+","+dest.longitude;
// Sensor enabled
String sensor = "sensor=false";
// Travelling Mode
String mode = "mode=driving";
if(rbDriving.isChecked()){
mode = "mode=driving";
mMode = 0 ;
}else if(rbBiCycling.isChecked()){
mode = "mode=bicycling";
mMode = 1;
}else if(rbWalking.isChecked()){
mode = "mode=walking";
mMode = 2;
}
// Building the parameters to the web service
String parameters = str_origin+"&"+str_dest+"&"+sensor+"&"+mode;
// Output format
String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;
return url;
}
/** A method to download json data from url */
private static String downloadUrl(String strUrl) throws IOException{
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try{
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while( ( line = br.readLine()) != null){
sb.append(line);
}
data = sb.toString();
br.close();
}catch(Exception e){
Log.d("Exception while downloading url", e.toString());
}finally{
iStream.close();
urlConnection.disconnect();
}
return data;
}
// Fetches data from url passed
static class DownloadTask extends AsyncTask<String, Void, String>{
// Downloading data in non-ui thread
#Override
protected String doInBackground(String... url) {
// For storing data from web service
String data = "";
try{
// Fetching the data from web service
data = downloadUrl(url[0]);
}catch(Exception e){
Log.d("Background Task",e.toString());
}
return data;
}
// Executes in UI thread, after the execution of
// doInBackground()
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
ParserTask parserTask = new ParserTask();
// Invokes the thread for parsing the JSON data
parserTask.execute(result);
}
}
/** A class to parse the Google Places in JSON format */
static class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{
// Parsing the data in non-ui thread
#Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try{
jObject = new JSONObject(jsonData[0]);
DirectionsJSONParser parser = new DirectionsJSONParser();
// Starts parsing data
routes = parser.parse(jObject);
}catch(Exception e){
e.printStackTrace();
}
return routes;
}
// Executes in UI thread, after the parsing process
#Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = null;
MarkerOptions markerOptions = new MarkerOptions();
// Traversing through all the routes
for(int i=0;i<result.size();i++){
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for(int j=0;j<path.size();j++){
HashMap<String,String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(2);
// Changing the color polyline according to the mode
if(mMode==MODE_DRIVING)
lineOptions.color(Color.RED);
else if(mMode==MODE_BICYCLING)
lineOptions.color(Color.GREEN);
else if(mMode==MODE_WALKING)
lineOptions.color(Color.BLUE);
}
if(result.size()<1){
Toast.makeText(ontext2, "No Points", Toast.LENGTH_SHORT).show();
return;
}
// Drawing polyline in the Google Map for the i-th route
map.addPolyline(lineOptions);
}
}
/*#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} */
}
First of all see this link which says to use a Handler to request one update with requestSingleUpdate() every 5 minutes.
Here is an example for the onLocationChanged()...
inside onCreate()
mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, 0, 0, mlocListener);
MyLocationListener class
public class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(Location location)
{
//Set marker here
LatLng pos=new LatLng(location.getLatitude(), location.getLongitude());
map.addMarker(new MarkerOptions().position(pos).icon(BitmapDescriptorFactory.fromResource(markericon)));
}
#Override
public void onProviderDisabled(String provider)
{
}
#Override
public void onProviderEnabled(String provider)
{
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}
There is no any guarantee how often the location changes will come. And you can make it in two ways.
You do not need to read the location every X seconds. Just save the last location from onLocationChanged() and use it on your timer ticks. You can also check if this location is different from the last used, if this matters
The other way is to use LocationClient and its method getLastLocation(). You can use getLastLocation() in any time (after proper initialization), like every 5 sec.
Something like this:
timer.scheduleAtFixedRate( new UpdateLocationTask(), 1000, 5000 );
class UpdateLocationTask extends TimerTask
{
public void run()
{
final Location location = mLocationClient.getLastLocation();
if ( location != null )
{
runOnUiThread( new Runnable()
{
public void run()
{
// do whatever you want here
}
});
}
}
}
I want to draw a Free Hand Polygon on the Map in Google Map V2.
This task was possible with Overlay Map V1 but Google Map has removed that class from V2. (Per this Google Map V2 has Remove Overlay Class).
Good Example for Google Map V1 to draw free style polygon.
In Map V2, we can draw a polygon programmatically with the help of Google Official Doc but what should a user do? I have found Unclear answer for Map V2
I started with simple Google Map & draw polygon to do this programmatically & it is working properly but now I am looking for how a user can draw? I don't want to draw based on the marker on the polygon.
// Instantiates a new Polygon object and adds points to define a rectangle
PolygonOptions rectOptions = new PolygonOptions()
.add(new LatLng(37.35, -122.0),
new LatLng(37.45, -122.0),
new LatLng(37.45, -122.2),
new LatLng(37.35, -122.2),
new LatLng(37.35, -122.0));
// Get back the mutable Polygon
Polygon polygon = myMap.addPolygon(rectOptions);
I have done lots of Research and Development on this topic but didn't get a perfect way to implement such a thing in Map V2.
Some Questions
How to draw freestyle polygon in Map V2 (as we can do with Map V1)?
Is there any trick or alternative to achieve this? If yes how?
Can we get a touch event on the map & draw polygon?
Is it feasible in Map V2?
Is it possible with a touch event which returns array of lat-long?
How can I get Lat-long based on screen coordinates on setOnDragListener?
Each new version has something extra compared to the older one so I am expecting that I can achieve the same thing in Map v2 also.
I am not asking to give me some sample code or post your code, just some proper direction & documentation.
I have provided all documents and evidence I found during the Research and Development.
After spending a whole day in Rnd and testing some alternatives I have found a solution. Actually I have found two alternatives for the same issue but I would like to suggest the using of Alternative 2 because that is really very easy compared to Alternative 1.
Actually I have found Alternative 1 with the help of TheLittleNaruto , AndroidHacker and some other developers & Alternative 2 with the help of Khan so thanks to all.
Alternative 1
How to Draw Free style polygon in Map V2 (as we can do with Map V1) ? Is it feasible in Map V2 ?
Yes, that is feasible but you can't get directly OnTouch() & OnDraw() on the map. So we must have to think some other way to achieve this.
Is there any trick or alternative way to achieve this thing , if yes how ?
Yes, Google Map V2 doesn't support OnTouch() or OnDraw() on a Map using class="com.google.android.gms.maps.SupportMapFragment" so we have to plan for a custom Fragment.
Is it possible to return array of lat-long with touch event ?
Yes, if we create any custom map fragment and use it we can get that Touch or Drag event over the map.
How can I get Lat-long base on screen coordinates on setOnDragListener ?
setOnDragListener will return screen coordinates (x,y). Now for that, there are some techniques to convert (x,y) to LatLng and they include Projection along with Point & LatLng.
customMapFragment.setOnDragListener(new MapWrapperLayout.OnDragListener() {#Override
public void onDrag(MotionEvent motionEvent) {
Log.i("ON_DRAG", "X:" + String.valueOf(motionEvent.getX()));
Log.i("ON_DRAG", "Y:" + String.valueOf(motionEvent.getY()));
float x = motionEvent.getX(); // get screen x position or coordinate
float y = motionEvent.getY(); // get screen y position or coordinate
int x_co = Integer.parseInt(String.valueOf(Math.round(x))); // casting float to int
int y_co = Integer.parseInt(String.valueOf(Math.round(y))); // casting float to int
projection = mMap.getProjection(); // Will convert your x,y to LatLng
Point x_y_points = new Point(x_co, y_co);// accept int x,y value
LatLng latLng = mMap.getProjection().fromScreenLocation(x_y_points); // convert x,y to LatLng
latitude = latLng.latitude; // your latitude
longitude = latLng.longitude; // your longitude
Log.i("ON_DRAG", "lat:" + latitude);
Log.i("ON_DRAG", "long:" + longitude);
// Handle motion event:
}
});
How does it work ?
As I have already mentioned before, we have to create a custom root view and using that we can get Touch or Drag Events over the map.
Step 1: We Create MySupportMapFragment extends SupportMapFragment and we will use that as our .xml file
<fragment
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
class="pkg_name.MySupportMapFragment" />
Step 2: Create a MapWrapperLayout extends FrameLayout so that we can set a Touch or Drag listener inside and embed its view with map view. So, we need one Interface which we will use in Root_Map.java
MySupportMapFragment.Java
public class MySupportMapFragment extends SupportMapFragment {
public View mOriginalContentView;
public MapWrapperLayout mMapWrapperLayout;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
mOriginalContentView = super.onCreateView(inflater, parent, savedInstanceState);
mMapWrapperLayout = new MapWrapperLayout(getActivity());
mMapWrapperLayout.addView(mOriginalContentView);
return mMapWrapperLayout;
}
#Override
public View getView() {
return mOriginalContentView;
}
public void setOnDragListener(MapWrapperLayout.OnDragListener onDragListener) {
mMapWrapperLayout.setOnDragListener(onDragListener);
}
}
MapWrapperLayout.java
public class MapWrapperLayout extends FrameLayout {
private OnDragListener mOnDragListener;
public MapWrapperLayout(Context context) {
super(context);
}
public interface OnDragListener {
public void onDrag(MotionEvent motionEvent);
}
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mOnDragListener != null) {
mOnDragListener.onDrag(ev);
}
return super.dispatchTouchEvent(ev);
}
public void setOnDragListener(OnDragListener mOnDragListener) {
this.mOnDragListener = mOnDragListener;
}
}
Root_Map.Java
public class Root_Map extends FragmentActivity {
private GoogleMap mMap;
public static boolean mMapIsTouched = false;
MySupportMapFragment customMapFragment;
Projection projection;
public double latitude;
public double longitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.root_map);
MySupportMapFragment customMapFragment = ((MySupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));
mMap = customMapFragment.getMap();
customMapFragment.setOnDragListener(new MapWrapperLayout.OnDragListener() { #Override
public void onDrag(MotionEvent motionEvent) {
Log.i("ON_DRAG", "X:" + String.valueOf(motionEvent.getX()));
Log.i("ON_DRAG", "Y:" + String.valueOf(motionEvent.getY()));
float x = motionEvent.getX();
float y = motionEvent.getY();
int x_co = Integer.parseInt(String.valueOf(Math.round(x)));
int y_co = Integer.parseInt(String.valueOf(Math.round(y)));
projection = mMap.getProjection();
Point x_y_points = new Point(x_co, y_co);
LatLng latLng = mMap.getProjection().fromScreenLocation(x_y_points);
latitude = latLng.latitude;
longitude = latLng.longitude;
Log.i("ON_DRAG", "lat:" + latitude);
Log.i("ON_DRAG", "long:" + longitude);
// Handle motion event:
}
});
}}
Reference Link1 , Link2
Up to here I am able to get LatLong based on X,Y screen coordinates. Now I just have to store it in Array. That array will be used for drawing on the map and finally it will look like a free shape polygon.
I hope this will definitely help you.
Update:
Alternative 2
As we know, Frame layout is a transparent layout so I have achieved this using Frame Layout.
In this case, there is no need to create a custom fragment. I have just used Frame Layout as root layout. So basically I will get Touch Events in the root layout and that will return screen coordinates, as we got in custom fragment previously.
Now, I have created a Button inside the "Free Draw". So when you click on that you can move your fingers on the map and draw a free hand polygon and that will disable your map being movable on screen. When you re-click the same button, the screen goes in ideal mode.
root_map.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
<FrameLayout
android:id="#+id/fram_map"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="#+id/btn_draw_State"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Free Draw" />
</FrameLayout>
</FrameLayout>
Root_Map.java
FrameLayout fram_map = (FrameLayout) findViewById(R.id.fram_map);
Button btn_draw_State = (Button) findViewById(R.id.btn_draw_State);
Boolean Is_MAP_Moveable = false; // to detect map is movable
// Button will change Map movable state
btn_draw_State.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Is_MAP_Moveable = !Is_MAP_Moveable;
}
});
Touch Click of Frame Layout and with the help of the do some task
fram_map.setOnTouchListener(new View.OnTouchListener() { #Override
public boolean onTouch(View v, MotionEvent event) {
float x = event.getX();
float y = event.getY();
int x_co = Math.round(x);
int y_co = Math.round(y);
projection = mMap.getProjection();
Point x_y_points = new Point(x_co, y_co);
LatLng latLng = mMap.getProjection().fromScreenLocation(x_y_points);
latitude = latLng.latitude;
longitude = latLng.longitude;
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
// finger touches the screen
val.add(new LatLng(latitude, longitude));
case MotionEvent.ACTION_MOVE:
// finger moves on the screen
val.add(new LatLng(latitude, longitude));
case MotionEvent.ACTION_UP:
// finger leaves the screen
Draw_Map();
break;
}
return Is_MAP_Moveable;
}
});
// Draw your map
public void Draw_Map() {
rectOptions = new PolygonOptions();
rectOptions.addAll(val);
rectOptions.strokeColor(Color.BLUE);
rectOptions.strokeWidth(7);
rectOptions.fillColor(Color.CYAN);
polygon = mMap.addPolygon(rectOptions);
}
Yet, now you have to maintain your list while you draw, so you have to clear your previous list data.
Check this out .. I believe U are capable of showing Google Map v2
Check out "decodePoly" and "drawPath" method in AsyncTask
Main Imphasis in "drawPath" ..
PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
for (int z = 0; z < list.size(); z++) {
LatLng point = list.get(z);
options.add(point);
}
line = myMap.addPolyline(options);
Complete class for your reference ..
package com.example.androidhackergooglemap;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
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 android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
public class MainActivity extends FragmentActivity implements OnClickListener {
private GoogleMap myMap;
Polyline line;
Context context;
Location location;
boolean check_provider_enabled = false;
// Static LatLng
LatLng startLatLng = new LatLng(30.707104, 76.690749);
LatLng endLatLng = new LatLng(30.721419, 76.730017);
public void onCreate(Bundle bd) {
super.onCreate(bd);
setContentView(R.layout.activity_main);
context = MainActivity.this;
// GoogleMap myMap
myMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
myMap.setMyLocationEnabled(true);
myMap.moveCamera(CameraUpdateFactory.newLatLng(startLatLng));
myMap.animateCamera(CameraUpdateFactory.zoomTo(12));
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean enabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER);
location = service.getLastKnownLocation(LocationManager.GPS_PROVIDER);
// check if enabled and if not send user to the GSP settings
// Better solution would be to display a dialog and suggesting to
// go to the settings
if (!enabled) {
/*Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);*/
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
Toast.makeText(getApplicationContext(), "Enable GPS servcies to use this app.", Toast.LENGTH_LONG).show();
} else {
try {
String urlTopass = makeURL(startLatLng.latitude,
startLatLng.longitude, endLatLng.latitude,
endLatLng.longitude);
new connectAsyncTask(urlTopass).execute();
} catch (Exception e) {
e.printStackTrace();
}
}
// Now auto clicking the button
// btntemp.performClick();
}
private class connectAsyncTask extends AsyncTask < Void, Void, String > {
private ProgressDialog progressDialog;
String url;
connectAsyncTask(String urlPass) {
url = urlPass;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
progressDialog = new ProgressDialog(context);
progressDialog.setMessage("Fetching route, Please wait...");
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected String doInBackground(Void...params) {
JSONParser jParser = new JSONParser();
String json = jParser.getJSONFromUrl(url);
return json;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
progressDialog.hide();
if (result != null) {
drawPath(result);
}
}
}
public String makeURL(double sourcelat, double sourcelog, double destlat,
double destlog) {
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.googleapis.com/maps/api/directions/json");
urlString.append("?origin="); // from
urlString.append(Double.toString(sourcelat));
urlString.append(",");
urlString.append(Double.toString(sourcelog));
urlString.append("&destination="); // to
urlString.append(Double.toString(destlat));
urlString.append(",");
urlString.append(Double.toString(destlog));
urlString.append("&sensor=false&mode=driving&alternatives=true");
return urlString.toString();
}
public class JSONParser {
InputStream is = null;
JSONObject jObj = null;
String json = "";
// constructor
public JSONParser() {}
public String getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
json = sb.toString();
is.close();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
return json;
}
}
public void drawPath(String result) {
if (line != null) {
myMap.clear();
}
myMap.addMarker(new MarkerOptions().position(endLatLng).icon(
BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
myMap.addMarker(new MarkerOptions().position(startLatLng).icon(
BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher)));
try {
// Tranform the string into a json object
final JSONObject json = new JSONObject(result);
JSONArray routeArray = json.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes
.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
List < LatLng > list = decodePoly(encodedString);
PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
for (int z = 0; z < list.size(); z++) {
LatLng point = list.get(z);
options.add(point);
}
line = myMap.addPolyline(options);
/*for (int z = 0; z < list.size() - 1; z++) {
LatLng src = list.get(z);
LatLng dest = list.get(z + 1);
line = myMap.addPolyline(new PolylineOptions()
.add(new LatLng(src.latitude, src.longitude),
new LatLng(dest.latitude, dest.longitude))
.width(5).color(Color.BLUE).geodesic(true));
}*/
} catch (Exception e) {
e.printStackTrace();
}
}
private List < LatLng > decodePoly(String encoded) {
List < LatLng > poly = new ArrayList < LatLng > ();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
LatLng p = new LatLng((((double) lat / 1E5)),
(((double) lng / 1E5)));
poly.add(p);
}
return poly;
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
}
}
Hope it helps. Cheers!
UPDATE
check out this .. Creating OnDragListener for Google Map v2 Fragment
Also check this one ..
How to draw a shape on the map fragment by touching it using google map V2
Some more reference .. How to get screen coordinates from marker in google maps v2 android
So we do have some solution for free hand draw on map v2.
Implement GoogleMap.OnMarkerDragListener in your map activity . It'll override onMarkerDrag function.
#Override
public void onMarkerDrag(Marker marker) {
//add the marker's latlng in a arraylist of LatLng and pass it to the loop
for (int i = 0; i < arraylistoflatlng.size(); i++) {
myMap.addPolyline(new PolylineOptions()
.addAll(arraylistoflatlng)
.width(5)
.color(Color.RED));
}
}
you can pass some kind of hack for free hand like as soon as the user will touch the map, you'll have to detect that coordinates and pass it to the the onMarkerDrag . As you'll have to use the area's information for further process. For touch event you can implement GoogleMap.OnMapClickListener and get the coordinates from it's parameter.
Hope this will help :)
this is google maps API V2 tutorial :
public class MapPane extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_activity);
GoogleMap map = ((MapFragment) getFragmentManager()
.findFragmentById(R.id.map)).getMap();
map.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(-18.142, 178.431), 2));
// Polylines are useful for marking paths and routes on the map.
map.addPolyline(new PolylineOptions().geodesic(true)
.add(new LatLng(-33.866, 151.195)) // Sydney
.add(new LatLng(-18.142, 178.431)) // Fiji
.add(new LatLng(21.291, -157.821)) // Hawaii
.add(new LatLng(37.423, -122.091)) // Mountain View
);
}
}
link : https://developers.google.com/maps/documentation/android/
I Have some code that showing between two directions which the destination has initialized (known position). The full code like this :
package com.my.app;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.FragmentManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
//import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import android.support.v4.app.FragmentActivity;
import com.google.android.gms.maps.SupportMapFragment;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
public class CobaMap2 extends FragmentActivity {
final int RQS_GooglePlayServices = 1;
private GoogleMap myMap;
double src_lat = -7.81016;
double src_long = 110.46860;
double dest_lat = -7.778031;
double dest_long = 110.494180;
MarkerOptions markerOptions;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_layout2);
myMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
myMap.setMyLocationEnabled(true);
// Set Current Location
moveToMyLocation();}
private void moveToMyLocation()
{
LocationManager locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
if (location != null)
{
myMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(location.getLatitude(),
location.getLongitude()), 13));
}
// choose map layout
RadioGroup rgViews = (RadioGroup) findViewById(R.id.rg_views);
rgViews.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if(checkedId == R.id.rb_normal){
myMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}else if(checkedId == R.id.rb_satellite){
myMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}else if(checkedId == R.id.rb_terrain){
myMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
}
}
});
LatLng srcLatLng = new LatLng(src_lat, src_long);
LatLng destLatLng = new LatLng(dest_lat, dest_long);
myMap.addMarker(new MarkerOptions()
.position(srcLatLng).title("Source place"));
myMap.animateCamera(CameraUpdateFactory.newLatLng(srcLatLng));
myMap.addMarker(new MarkerOptions()
.position(destLatLng).title("Destination place"));
// Enabling MyLocation in Google Map
myMap.setMyLocationEnabled(true);
myMap.getUiSettings().setZoomControlsEnabled(true);
myMap.getUiSettings().setCompassEnabled(true);
myMap.getUiSettings().setMyLocationButtonEnabled(true);
myMap.getUiSettings().setAllGesturesEnabled(true);
myMap.setTrafficEnabled(true);
myMap.animateCamera(CameraUpdateFactory.newLatLngZoom(srcLatLng,12));
markerOptions = new MarkerOptions();
// Polyline line = myMap.addPolyline(new PolylineOptions().add(srcLatLng, destLatLng).width(5).color(Color.RED));
connectAsyncTask _connectAsyncTask = new connectAsyncTask();
_connectAsyncTask.execute();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.cobamap, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_legalnotices:
String LicenseInfo = GooglePlayServicesUtil.getOpenSourceSoftwareLicenseInfo(
getApplicationContext());
AlertDialog.Builder LicenseDialog = new AlertDialog.Builder(CobaMap2.this);
LicenseDialog.setTitle("Legal Notices");
LicenseDialog.setMessage(LicenseInfo);
LicenseDialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if (resultCode == ConnectionResult.SUCCESS){
Toast.makeText(getApplicationContext(),
"isGooglePlayServicesAvailable SUCCESS",
Toast.LENGTH_LONG).show();
}else{
GooglePlayServicesUtil.getErrorDialog(resultCode, this, RQS_GooglePlayServices);
}
}
private class connectAsyncTask extends AsyncTask<Void, Void, Void>{
private ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
progressDialog = new ProgressDialog(CobaMap2.this);
progressDialog.setMessage("Fetching route, Please wait...");
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
fetchData();
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(doc!=null){
NodeList _nodelist = doc.getElementsByTagName("status");
Node node1 = _nodelist.item(0);
String _status1 = node1.getChildNodes().item(0).getNodeValue();
if(_status1.equalsIgnoreCase("OK")){
NodeList _nodelist_path = doc.getElementsByTagName("overview_polyline");
Node node_path = _nodelist_path.item(0);
Element _status_path = (Element)node_path;
NodeList _nodelist_destination_path = _status_path.getElementsByTagName("points");
Node _nodelist_dest = _nodelist_destination_path.item(0);
String _path = _nodelist_dest.getChildNodes().item(0).getNodeValue();
List<LatLng> directionPoint = decodePoly(_path);
PolylineOptions rectLine = new PolylineOptions().width(10).color(Color.BLUE);
for (int i = 0; i < directionPoint.size(); i++) {
rectLine.add(directionPoint.get(i));
}
// Adding route on the map
myMap.addPolyline(rectLine);
markerOptions.position(new LatLng(dest_lat, dest_long));
markerOptions.draggable(true);
myMap.addMarker(markerOptions);
}else{
showAlert("Unable to find the route");
}
}else{
showAlert("Unable to find the route");
}
progressDialog.dismiss();
}
}
Document doc = null;
private void fetchData()
{
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.google.com/maps/api/directions/xml?origin=");
urlString.append(src_lat);
urlString.append(",");
urlString.append(src_long);
urlString.append("&destination=");//to
urlString.append(dest_lat);
urlString.append(",");
urlString.append(dest_long);
urlString.append("&sensor=true&mode=driving");
Log.d("url","::"+urlString.toString());
HttpURLConnection urlConnection= null;
URL url = null;
try
{
url = new URL(urlString.toString());
urlConnection=(HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.connect();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
doc = (Document) db.parse(urlConnection.getInputStream());//Util.XMLfromString(response);
}catch (MalformedURLException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}catch (ParserConfigurationException e){
e.printStackTrace();
}
catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void showAlert(String message){
AlertDialog.Builder alert = new AlertDialog.Builder(CobaMap2.this);
alert.setTitle("Error");
alert.setCancelable(false);
alert.setMessage(message);
alert.setPositiveButton("Ok",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
alert.show();
}
private ArrayList<LatLng> decodePoly(String encoded) {
ArrayList<LatLng> poly = new ArrayList<LatLng>();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
LatLng position = new LatLng((double) lat / 1E5, (double) lng / 1E5);
poly.add(position);
}
return poly;
}
}
The code worked perfectly, You can see between two location (source and destination) are known location. then i need change the first location (source location) with my current Location, and current location detected by this code :
// Set Current Location
moveToMyLocation();}
private void moveToMyLocation()
{
LocationManager locationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
if (location != null)
{
myMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(location.getLatitude(),
location.getLongitude()), 13));
}
And code to initialized the location is :
LatLng srcLatLng = new LatLng(src_lat, src_long);
LatLng destLatLng = new LatLng(dest_lat, dest_long);
The problem is, how to passing data from my current location to set the data for the source location and show path between location. (Source : My current Location, Destination : Known Location). What the method must i use ?. I mean the app show from my current location to destination location with modify that code ?
Check this question
How to draw interactive Polyline on route google maps v2 android
in this you will get the code to draw a proper route from one place to another using polyLine, also includes current and destination location !
Edit :
Use
src_lat=location.getLatitude()
src_long=location.getLongitude()
inside
if (location != null)
{
src_lat=location.getLatitude()
src_long=location.getLongitude()
myMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(location.getLatitude(),
location.getLongitude()), 13));
}
Edit:
try by
Changing :
Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
to
Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, true));