android studio google map api no data in route class

Viewed 23

I refer to https://www.kodetr.com/menentukan-rute-terdekat-dari-lokasi-menggunakan-google-map/

No data in My route class and JSON

It only works show current loction

In Mapsactivity, For(Route route:routes) loop is not work in onDirectionFinderSuccess and no data in routes

Also in DirectionFinder.java, for (int i = 0; i < jsonRoutes.length(); i++) jsonRoutes.length return 0

//XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="574dp"
        android:layout_weight="1">

        <fragment
            android:id="@+id/map"
            class="com.google.android.gms.maps.MapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"></fragment>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="43dp"
            android:layout_marginStart="20dp"
            android:layout_marginTop="20dp"
            android:layout_marginEnd="20dp"
            android:layout_marginBottom="20dp"
            android:background="@android:color/white">

            <fragment
                android:id="@+id/place_autocomplete_fragment"
                android:name="com.google.android.libraries.places.compat.ui.PlaceAutocompleteFragment"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"></fragment>


        </LinearLayout>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_marginLeft="5dp"
            android:layout_marginTop="5dp"
            android:layout_marginBottom="25dp"
            android:orientation="vertical"
            android:padding="5dp">

            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">

                <ImageView
                    android:layout_width="130dp"
                    android:layout_height="40dp"
                    android:src="@drawable/distance" />

                <TextView
                    android:id="@+id/tvDistance"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="44dp"
                    android:layout_marginTop="10dp"
                    android:fontFamily="@font/applesdgothicneom"
                    android:text="0 km" />

            </RelativeLayout>

            <RelativeLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">

                <ImageView
                    android:layout_width="130dp"
                    android:layout_height="40dp"
                    android:src="@drawable/time" />

                <TextView
                    android:id="@+id/tvTime"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="44dp"
                    android:layout_marginTop="10dp"
                    android:fontFamily="@font/applesdgothicneom"
                    android:text="0 mins" />

            </RelativeLayout>

        </LinearLayout>

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fbsatelit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"
            android:layout_marginStart="15dp"
            android:layout_marginEnd="15dp"
            android:layout_marginRight="13dp"
            android:layout_marginBottom="156dp"
            android:backgroundTint="@android:color/white"
            android:backgroundTintMode="screen"
            android:src="@drawable/ic_satellite_on" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fbgps"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@+id/fbsatelit"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"
            android:layout_marginStart="15dp"
            android:layout_marginEnd="15dp"
            android:layout_marginRight="13dp"
            android:layout_marginBottom="84dp"
            android:backgroundTint="@android:color/white"
            android:backgroundTintMode="screen"
            android:src="@drawable/ic_my_gps" />

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fblocation"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_above="@+id/fbgps"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"
            android:layout_gravity="bottom|right"
            android:layout_marginStart="15dp"
            android:layout_marginTop="15dp"
            android:layout_marginEnd="15dp"
            android:layout_marginRight="14dp"
            android:layout_marginBottom="11dp"
            android:backgroundTintMode="screen"
            android:src="@drawable/ic_directions" />


    </RelativeLayout>

</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

//MapsActivity

public class MapsActivity extends AppCompatActivity implements GoogleMap.OnMarkerClickListener, GoogleMap.OnMapClickListener,OnMapReadyCallback, DirectionFinderListener {

private static final String TAG = MapsActivity.class.getSimpleName();
private LatLng LocationA = new LatLng(37.56, 126.97);

private static final float DEFAULT_ZOOM = 9.5f;

private static final long UPDATE_INTERVAL = 500;
private static final long FASTEST_UPDATE_INTERVAL = UPDATE_INTERVAL / 5;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;
private static boolean gpsFirstOn = true;

private GoogleMap map;
private FusedLocationProviderClient fusedLocationProvider;
private LocationRequest locationRequest;
private LocationCallback locationCallback;
private Location locationgps;
private ResultReceiver resultReceiver;
private Marker selectedMarker;
private LatLng searchLocation;

private List<Marker> originMarkers = new ArrayList<>();
private List<Marker> destinationMarker = new ArrayList<>();
private List<Polyline> polyLinePaths = new ArrayList<>();

private ProgressDialog progressDialog;

@SuppressLint("SetTextI18n")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        checkLocationPermission();
    }

    if (!Connections.checkConnection(this)) {
        Toast.makeText(this, "네트워크 오류", Toast.LENGTH_SHORT).show();
        finish();
    }

    init();

    fusedLocationProvider = LocationServices.getFusedLocationProviderClient(this);
    resultReceiver = new ResultReceiver(new Handler()) {
        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            String addressOutput = resultData.getString(Constants.RESULT_DATA_KEY);
            Toast.makeText(getApplicationContext(), addressOutput, Toast.LENGTH_SHORT).show();
        }
    };

    locationgps = new Location("Point A");
}

@SuppressLint("SetTextI18n")
private void init() {

    setupAutoCompleteFragment();

    FloatingActionButton fa = findViewById(R.id.fblocation);
    fa.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String origin = locationgps.getLatitude() + "," + locationgps.getLongitude();
            try {
                new DirectionFinder(MapsActivity.this, origin, searchLocation.latitude + "," + searchLocation.longitude).execute();
            }catch (Exception e){e.printStackTrace();}
        }
    });

    final FloatingActionButton ft = findViewById(R.id.fbsatelit);
    ft.setOnClickListener(view -> {
        if (map != null) {
            int MapType = map.getMapType();
            if (MapType == 1) {
                ft.setImageResource(R.drawable.ic_satellite_off);
                map.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
            } else {
                ft.setImageResource(R.drawable.ic_satellite_on);
                map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
            }
        }
    });

    FloatingActionButton fm = findViewById(R.id.fbgps);
    fm.setOnClickListener(view -> {
        getDeviceLocation(true);
        if (!Geocoder.isPresent()) {
            showSnackbar(R.string.no_geocoder_available, Snackbar.LENGTH_LONG, 0, null);
        } else {
            showAddress();
            setCurrentLocation(locationgps);
        }
    });

    locationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            if (locationResult == null)
                return;

            for (Location locationUpdate : locationResult.getLocations()) {
                locationgps = locationUpdate;
                if (gpsFirstOn) {
                    gpsFirstOn = false;
                    getDeviceLocation(true);
                }

            }
        }
    };

    locationRequest = new LocationRequest();
    locationRequest.setInterval(UPDATE_INTERVAL);
    locationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL);
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

private void setupAutoCompleteFragment() {
    PlaceAutocompleteFragment autocompleteFragment = (PlaceAutocompleteFragment)
            getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
    autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
        @Override
        public void onPlaceSelected(Place place) {
            searchLocation = place.getLatLng();
        }

        @Override
        public void onError(Status status) {
            Log.e("Error", status.getStatusMessage());
        }
    });
}

public void setCurrentLocation(Location location) {
    LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
    map.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, DEFAULT_ZOOM));
}

@Override
public void onMapReady(GoogleMap gMap) {
    map = gMap;

    map.setOnMapClickListener(this);
    map.setOnMarkerClickListener(this);

    map.moveCamera(CameraUpdateFactory.newLatLngZoom(LocationA, DEFAULT_ZOOM));//05.27

    map.getUiSettings().setMapToolbarEnabled(false);
    map.getUiSettings().setMyLocationButtonEnabled(false);

    // TODO : location
    map.getProjection().getVisibleRegion();

    if (!checkPermission())
        requestPermission();

    map.setMyLocationEnabled(true);//05.27
}

@Override
public void onDirectionFinderStart() {
    progressDialog = ProgressDialog.show(this, "잠시만요", "가장 가까운 위치를 찾고 있습니다", true);
    if (originMarkers != null) {
        for (Marker marker : originMarkers) {
            marker.remove();
        }
    }
    if (destinationMarker != null) {
        for (Marker marker : destinationMarker) {
            marker.remove();
        }
    }
    if (polyLinePaths != null) {
        for (Polyline polylinePath : polyLinePaths) {
            polylinePath.remove();
        }
    }
}

@Override
public void onDirectionFinderSuccess(List<Route> routes) {
    progressDialog.dismiss();
    polyLinePaths = new ArrayList<>();
    originMarkers = new ArrayList<>();
    destinationMarker = new ArrayList<>();


    for (Route route : routes) {
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(route.startLocation, 15.5f));
        ((TextView) findViewById(R.id.tvDistance)).setText(route.distance.text);
        ((TextView) findViewById(R.id.tvTime)).setText(route.duration.text);


        destinationMarker.add(map.addMarker(new MarkerOptions()
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED))
                .title(route.endAddress)
                .position(route.endLocation)));

        PolylineOptions polylineOptions = new PolylineOptions()
                .geodesic(true)
                .color(getResources().getColor(R.color.purple_200))
                .width(10);

        for (int i = 0; i < route.points.size(); i++) {
            polylineOptions.add(route.points.get(i));
        }

        polyLinePaths.add(map.addPolyline(polylineOptions));
    }
}

private void getDeviceLocation(final boolean MyLocation) {
    if (!MyLocation)

        if (checkPermission()) {
            if (map != null)
                map.setMyLocationEnabled(true);

            final Task<Location> locationResult = fusedLocationProvider.getLastLocation();
            locationResult.addOnCompleteListener(this, task -> {
                if (task.isSuccessful() && task.getResult() != null) {
                    // lastKnownLocation = task.getResult();
                } else {
                    Log.w(TAG, "getLastLocation:exception", task.getException());

                    showSnackbar(R.string.no_location_detected, Snackbar.LENGTH_LONG, 0, null);
                }
            });
        } else // !checkPermission()
            Log.d(TAG, "Current location is null. Permission Denied.");
}

@Override
public void onMapClick(final LatLng point) {
    selectedMarker = null;
}

@Override
public boolean onMarkerClick(Marker marker) {
    if (marker.equals(selectedMarker)) {
        selectedMarker = null;
        return true;
    }

    Toast.makeText(this, marker.getTitle(), Toast.LENGTH_SHORT).show();
    selectedMarker = marker;
    return false;
}

private void showAddress() {
    Intent intent = new Intent(this, FetchAddressIntentService.class);
    intent.putExtra(Constants.RECEIVER, resultReceiver);
    intent.putExtra(Constants.LOCATION_DATA_EXTRA, locationgps);
    startService(intent);
}

@Override
protected void onStart() {
    super.onStart();
    if (Connections.checkConnection(this)) {
        new PermissionGPS(this);
    }
}

@Override
protected void onRestart() {
    super.onRestart();
    if (Connections.checkConnection(this)) {
        new PermissionGPS(this);
    }
}

@Override
protected void onResume() {
    super.onResume();
    if (Connections.checkConnection(this)) {
        if (checkPermission())
            fusedLocationProvider.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper());
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    Log.i(TAG, "onRequestPermissionResult");
    if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
        if (grantResults.length <= 0)
            Log.i(TAG, "User interaction was cancelled.");
        else // grantResults.length > 0
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
                getDeviceLocation(false);
            else
                showSnackbar(R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE, android.R.string.ok,
                        view -> requestPermission());
    }
}

private void showSnackbar(int textStringId, int length, int actionStringId, View.OnClickListener listener) {
    Snackbar snackbar = Snackbar.make(findViewById(android.R.id.content), textStringId, length);
    if (listener != null)
        snackbar.setAction(actionStringId, listener);
    snackbar.show();
}

private void requestPermission() {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);

}

private boolean checkPermission() {
    return ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;

public boolean checkLocationPermission() {
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);


        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);
        }
        return false;
    } else {
        return true;
    }
}

}

//DirectionFinder.java

public class DirectionFinder {


private DirectionFinderListener listener;
private String origin;
private String destination;
public static final String google_api_key="OUR_API_KEY";

public DirectionFinder(DirectionFinderListener listener, String origin, String destination) {
    this.listener = listener;
    this.origin = origin;
    this.destination = destination;
}

public void execute() throws UnsupportedEncodingException {
    listener.onDirectionFinderStart();
    new DownloadRawData().execute(createUrl());
}

private String createUrl() throws UnsupportedEncodingException {
    String urlOrigin = URLEncoder.encode(origin, "utf-8");
    String urlDestination = URLEncoder.encode(destination, "utf-8");

    return Constants.DIRECTION_URL_API + "origin=" + urlOrigin + "&destination=" + urlDestination + "&key=" + google_api_key;
}

@SuppressLint("StaticFieldLeak")
private class DownloadRawData extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        String link = params[0];
        try {
            URL url = new URL(link);
            InputStream is = url.openConnection().getInputStream();
            StringBuilder buffer = new StringBuilder();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));

            String line;
            while ((line = reader.readLine()) != null) {
                buffer.append(line+"\n");
            }

            return buffer.toString();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String res) {
        try {
            parseJSon(res);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
}

private void parseJSon(String data) throws JSONException {
    if (data == null)
        return;

    List<Route> routes = new ArrayList<Route>();
    JSONObject jsonData = new JSONObject(data);
    JSONArray jsonRoutes = jsonData.getJSONArray("routes");
    for (int i = 0; i < jsonRoutes.length(); i++) {
        JSONObject jsonRoute = jsonRoutes.getJSONObject(i);
        Route route = new Route();

        JSONObject overview_polylineJson = jsonRoute.getJSONObject("overview_polyline");
        JSONArray jsonLegs = jsonRoute.getJSONArray("legs");
        JSONObject jsonLeg = jsonLegs.getJSONObject(0);
        JSONObject jsonDistance = jsonLeg.getJSONObject("distance");
        JSONObject jsonDuration = jsonLeg.getJSONObject("duration");
        JSONObject jsonEndLocation = jsonLeg.getJSONObject("end_location");
        JSONObject jsonStartLocation = jsonLeg.getJSONObject("start_location");

        route.distance = new Distance(jsonDistance.getString("text"), jsonDistance.getInt("value"));
        route.duration = new Duration(jsonDuration.getString("text"), jsonDuration.getInt("value"));
        route.endAddress = jsonLeg.getString("end_address");
        route.startAddress = jsonLeg.getString("start_address");
        route.startLocation = new LatLng(jsonStartLocation.getDouble("lat"), jsonStartLocation.getDouble("lng"));
        route.endLocation = new LatLng(jsonEndLocation.getDouble("lat"), jsonEndLocation.getDouble("lng"));
        route.points = decodePolyLine(overview_polylineJson.getString("points"));
        routes.add(route);
    }
    listener.onDirectionFinderSuccess(routes);
}

private List<LatLng> decodePolyLine(final String poly) {
    int len = poly.length();
    int index = 0;
    List<LatLng> decoded = new ArrayList<>();
    int lat = 0;
    int lng = 0;

    while (index < len) {
        int b;
        int shift = 0;
        int result = 0;
        do {
            b = poly.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 = poly.charAt(index++) - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
        lng += dlng;
        decoded.add(new LatLng(lat / 100000d, lng / 100000d));
    }
    return decoded;
}

}

//Route class

public class Route {
public Distance distance;
public Duration duration;
public String endAddress;
public LatLng endLocation;
public String startAddress;
public LatLng startLocation;

public List<LatLng> points;}

//result

{
   "geocoded_waypoints" : [ {}, {} ],
   "routes" : [],
   "status" : "ZERO_RESULTS"
}

It doesn't work when I cliked destination!

0 Answers
Related