I'm trying to make an app with places and directions I have done that but after 1 or 2 direction calls I just get onFailure: timeout and nothing shows on the screen. I am using firebase for markers but that's not the issue also the marker changes to another marker when using direction and even that isn't working anymore any help would be greatly appreciated
everything works but you have to wait like 5 seconds each time you make a routes but that might be the emulator but after 1 or 2 routes it says onFailure: timeout I was expecting it to work as i was following a tutorial but morphing it into my app
It works it works then
it doesn't then it doesnt
this error also only sometimes happens some times I can do a lot of trips and I can re click on it and try doing the direction again and sometimes that works it's really weird
Map Activity
package au.com.tutorialmaps;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.FusedLocationProviderClient;
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.MapStyleOptions;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.libraries.places.api.Places;
import com.google.android.libraries.places.api.model.Place;
import com.google.android.libraries.places.api.net.PlacesClient;
import com.google.android.libraries.places.widget.Autocomplete;
import com.google.android.libraries.places.widget.AutocompleteActivity;
import com.google.android.libraries.places.widget.model.AutocompleteActivityMode;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.GeoPoint;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import com.google.maps.DirectionsApiRequest;
import com.google.maps.GeoApiContext;
import com.google.maps.PendingResult;
import com.google.maps.android.SphericalUtil;
import com.google.maps.internal.PolylineEncoding;
import com.google.maps.model.DirectionsResult;
import com.google.maps.model.DirectionsRoute;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class MapActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleMap.OnPolylineClickListener {
@SuppressLint({"SuspiciousIndentation", "PotentialBehaviorOverride"})
@Override
public void onMapReady(GoogleMap googleMap) {
Toast.makeText(this, "Map is Ready", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onMapReady: map is ready");
mMap = googleMap;
if (mLocationPermissionsGranted) {
getDeviceLocation();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.getUiSettings().setZoomGesturesEnabled(true);
mMap.isBuildingsEnabled();
mMap.setOnPolylineClickListener(this);
init();
//mMap.setInfoWindowAdapter(new CustomInfoViewAdapter(this));
CollectionReference shrinesRef = db.collection("Shrines");
Query shrine = shrinesRef.whereEqualTo("isShrine", true);
shrine.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Log.i(TAG, Objects.requireNonNull(document.getData().get("LatLing")).toString());
GeoPoint geoPoint = document.getGeoPoint("LatLing");
String name = document.getString("Name");
String description = document.getString("Description");
if (geoPoint != null && name != null) {
LatLng latLng = new LatLng(geoPoint.getLatitude(), geoPoint.getLongitude());
Log.i(TAG, "the latLing is " + latLng);
Log.i(TAG, "the name is " + name);
Log.i(TAG, "the description is " + description);
firebaseMarker = mMap.addMarker(new MarkerOptions()
.position(latLng)
.title(name)
.snippet(description)
);
}
}
}else{
Log.w(TAG, "Error getting documents", task.getException());
}
}
});
mMap.setOnInfoWindowLongClickListener(new GoogleMap.OnInfoWindowLongClickListener() {
@Override
public void onInfoWindowLongClick(@NonNull Marker marker) {
final AlertDialog.Builder builder = new AlertDialog.Builder(MapActivity.this);
builder.setMessage("More Info or Directions?")
.setCancelable(true)
.setPositiveButton("Directions", (dialog, id) -> {
mSelectedMarker = marker;
calculateDirections(mSelectedMarker);
dialog.dismiss();
})
.setNegativeButton("More Info", (dialog, id) -> {
dialog.dismiss();
});
final AlertDialog alert = builder.create();
alert.show();
}
});
}
}
private void addPolylinesToMap(final DirectionsResult result){
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Log.d(TAG, "run: result routes: " + result.routes.length);
if (mPolylinesData.size() > 0){
for (PolylineData polylineData : mPolylinesData){
polylineData.getPolyline().remove();
}
mPolylinesData.clear();
mPolylinesData = new ArrayList<>();
}
double duration = 999999999;
for(DirectionsRoute route: result.routes){
Log.d(TAG, "run: leg: " + route.legs[0].toString());
List<com.google.maps.model.LatLng> decodedPath = PolylineEncoding.decode(route.overviewPolyline.getEncodedPath());
List<LatLng> newDecodedPath = new ArrayList<>();
// This loops through all the LatLng coordinates of ONE polyline.
for(com.google.maps.model.LatLng latLng: decodedPath){
// Log.d(TAG, "run: latlng: " + latLng.toString());
newDecodedPath.add(new LatLng(
latLng.lat,
latLng.lng
));
}
Polyline polyline = mMap.addPolyline(new PolylineOptions().addAll(newDecodedPath));
polyline.setColor(ContextCompat.getColor(MapActivity.this, R.color.grey));
polyline.setClickable(true);
mPolylinesData.add(new PolylineData(polyline, route.legs[0]));
onPolylineClick(polyline);
double tempDuration = route.legs[0].duration.inSeconds;
if (tempDuration < duration) {
duration = tempDuration;
onPolylineClick(polyline);
}
mSelectedMarker.setVisible(false);
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.map_types_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.normal:
mMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(this, R.raw.daymap));
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
break;
case R.id.hybrid:
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
break;
case R.id.satellite:
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
break;
case R.id.terrain:
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
break;
case R.id.normalnight:
mMap.setMapStyle(MapStyleOptions.loadRawResourceStyle(this, R.raw.nightmap));
break;
}
return true;
}
private static final String TAG = "MapActivity";
private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
private static final String COURSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
private static final float DEFAULT_ZOOM = 7f;
//widgets
private AutoCompleteTextView mSearchText;
private ImageView mGps;
private Button mSRearchFiller;
//vars
private Boolean mLocationPermissionsGranted = false;
private GoogleMap mMap;
private FusedLocationProviderClient mFusedLocationProviderClient;
private PlacesClient mplacesclient;
private Autocomplete autocomplete;
private static int AUTOCOMPLETE_REQUEST_CODE = 1079;
private FirebaseFirestore db;
private GeoApiContext mGeoApiContext = null;
private Location userCurrentLocation;
private Marker firebaseMarker;
private ArrayList<PolylineData> mPolylinesData = new ArrayList<>();
private Marker mSelectedMarker = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
mSRearchFiller = (Button) findViewById(R.id.btn2);
mGps = (ImageView) findViewById(R.id.ic_gps);
Places.initialize(getApplicationContext(), "AIzaSyDa-r-kB83q9XM0CjCaRx7uQqSeSxs-m0Q");
PlacesClient placesClient = Places.createClient(this);
FirebaseFirestore firestore = FirebaseFirestore.getInstance();
db = firestore;
getLocationPermission();
CollectionReference shrinesRef = firestore.collection("Shrines");
// Create a query against the collection.
Query query = shrinesRef.whereEqualTo("Name", "Imam Ali");
}
public void startAutocompleteActivity(View view) {
// Start the autocomplete intent.
Intent intent = new Autocomplete.IntentBuilder(AutocompleteActivityMode.OVERLAY, Arrays.asList(Place.Field.ID, Place.Field.NAME))
.setCountries(Arrays.asList("IQ"))
.build(this);
startActivityForResult(intent, AUTOCOMPLETE_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == AUTOCOMPLETE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Place place = Autocomplete.getPlaceFromIntent(data);
Log.i(TAG, "Place:"+ place.getName() + ", " + place.getId());
LatLng placelatling = place.getLatLng();
String placetitle = place.getName();
moveCamera(placelatling, DEFAULT_ZOOM, placetitle);
}else if (resultCode == AutocompleteActivity.RESULT_ERROR){
Status status = Autocomplete.getStatusFromIntent(data);
Log.i(TAG, status.getStatusMessage());
}else if (resultCode == RESULT_CANCELED) {
// user has cancelled do nothing
}
}
}
private void init(){
Log.d(TAG, "init: initializing");
mGps.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d(TAG, "onClick: clicked gps icon");
getDeviceLocation();
}
});
}
private void getDeviceLocation(){
Log.d(TAG, "getDeviceLocation: getting the devices current location");
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
try{
if(mLocationPermissionsGranted){
final Task<Location> location = mFusedLocationProviderClient.getLastLocation();
location.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if(task.isSuccessful()){
Log.d(TAG, "onComplete: found location!");
Location currentLocation = (Location) task.getResult();
userCurrentLocation = currentLocation;
moveCamera(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()),
DEFAULT_ZOOM,
"My Location");
}else{
Log.d(TAG, "onComplete: current location is null");
Toast.makeText(MapActivity.this, "unable to get current location", Toast.LENGTH_SHORT).show();
}
}
});
}
}catch (SecurityException e){
Log.e(TAG, "getDeviceLocation: SecurityException: " + e.getMessage() );
}
}
private void moveCamera(LatLng latLng, float zoom, String title){
Log.d(TAG, "moveCamera: moving the camera to: lat: " + latLng.latitude + ", lng: " + latLng.longitude );
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoom));
if(!title.equals("My Location")){
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title(title);
mMap.addMarker(options);
}
}
private void initMap(){
Log.d(TAG, "initMap: initializing map");
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(MapActivity.this);
if (mGeoApiContext == null){
mGeoApiContext = new GeoApiContext.Builder()
.apiKey("AIzaSyAmytqSCGeWxEQMOAeI6SB7nPNH8UayubA")
.build();
}
}
private void getLocationPermission(){
Log.d(TAG, "getLocationPermission: getting location permissions");
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION};
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
mLocationPermissionsGranted = true;
initMap();
}else{
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
}
}else{
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Log.d(TAG, "onRequestPermissionsResult: called.");
mLocationPermissionsGranted = false;
switch (requestCode) {
case LOCATION_PERMISSION_REQUEST_CODE: {
if (grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
mLocationPermissionsGranted = false;
Log.d(TAG, "onRequestPermissionsResult: permission failed");
return;
}
}
Log.d(TAG, "onRequestPermissionsResult: permission granted");
mLocationPermissionsGranted = true;
//initialize our map
initMap();
}
}
}
}
private void hideSoftKeyboard(){
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager)getSystemService(MapActivity.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
private void calculateDirections(Marker marker){
Log.d(TAG, "calculateDirections: calculating directions.");
com.google.maps.model.LatLng destination = new com.google.maps.model.LatLng(
marker.getPosition().latitude,
marker.getPosition().longitude
);
DirectionsApiRequest directions = new DirectionsApiRequest(mGeoApiContext);
directions.alternatives(true);
directions.origin(
new com.google.maps.model.LatLng(
userCurrentLocation.getLatitude(),
userCurrentLocation.getLongitude()
)
);
Log.d(TAG, "calculateDirections: destination: " + destination.toString());
directions.destination(destination).setCallback(new PendingResult.Callback<DirectionsResult>() {
@Override
public void onResult(DirectionsResult result) {
Log.d(TAG, "onResult: routes: " + result.routes[0].toString());
Log.d(TAG, "onResult: geocodedWayPoints: " + result.geocodedWaypoints[0].toString());
addPolylinesToMap(result);
}
@Override
public void onFailure(Throwable e) {
Log.e(TAG, "onFailure: " + e.getMessage() );
}
});
}
@Override
public void onPolylineClick(@NonNull Polyline polyline) {
int index = 0;
for(PolylineData polylineData: mPolylinesData){
index++;
Log.d(TAG, "onPolylineClick: toString: " + polylineData.toString());
if(polyline.getId().equals(polylineData.getPolyline().getId())){
polylineData.getPolyline().setColor(ContextCompat.getColor(MapActivity.this, com.google.android.libraries.places.R.color.quantum_googblue));
polylineData.getPolyline().setZIndex(1);
LatLng endLocation = new LatLng(
polylineData.getLeg().endLocation.lat,
polylineData.getLeg().endLocation.lng
);
Marker marker = mMap.addMarker(new MarkerOptions()
.position(endLocation)
.title("Trip: #" + index)
.snippet("Duration: " + polylineData.getLeg().duration)
);
marker.showInfoWindow();
}
else{
polylineData.getPolyline().setColor(ContextCompat.getColor(MapActivity.this, R.color.grey));
polylineData.getPolyline().setZIndex(0);
}
}
}
}