Java – How to use the Google Maps Android API to plot a route between two points in MapFragment

How to use the Google Maps Android API to plot a route between two points in MapFragment… here is a solution to the problem.

How to use the Google Maps Android API to plot a route between two points in MapFragment

My goal is to complete the following tasks in one lesson.

I want to give direction between two pointers in the Google Android Map API (current position and prefix position in drawer navigation).

  1. Is it possible or do I need the Directions API? Can’t navigation be done in the Android Maps API itself?

  2. My goal is to use only one activity or java file for all tasks, such as getting the current location and displaying the target pointer in map (which I’ve done). Now I want to give the route for these two pointers, the route must change when the prefix pointer or position is changed by the consumer.

The prefix refers to the position I’ve given in the if else in onNavigationItemSelected().

Please refer to the MainActivity.java code below – my goal is to do everything in one java class itself.

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, OnMapReadyCallback, LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

private GoogleMap mMap;
private GoogleApiClient client;

Location location;
LocationManager locationManager;

Marker marker;

String title;
String subTitle;
LatLng latLon;

double latitude;
double longitude;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_main);

isConnectionAvailable();
    isGpsAvailable();

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

 ATTENTION: This was auto-generated to implement the App Indexing API.
     See https://g.co/AppIndexing/AndroidStudio for more information.
    client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();

}

private boolean isConnectionAvailable() {

boolean netCon = false;

try {

Internet & network information "Object" initialization
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
        Internet enable & connectivity checking
        if ("WIFI".equals(networkInfo.getTypeName()) || "MOBILE".equals(networkInfo.getTypeName()) && networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnectedOrConnecting()) {
            netCon = true;
        }
    } catch (Exception e) {
        new AlertDialog.Builder(this)
                .setIcon(android. R.drawable.ic_dialog_alert)
                .setTitle("No Network Connection!")
                .setMessage("Please connect your device to either WiFi or switch on Mobile Data, operator charges may apply!")
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                        finish();
                    }
                }).show();
    }
    return netCon;
}

private boolean isGpsAvailable() {

boolean gpsCon = false;

locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        Toast.makeText(this, "GPS is Enabled.", Toast.LENGTH_SHORT).show();
        gpsCon = true;
    } else {
        new AlertDialog.Builder(this)
                .setIcon(android. R.drawable.ic_dialog_alert)
                .setTitle("GPS is disabled!")
                .setMessage("Without GPS this application will not work! Would you like to enable the GPS?")
                .setCancelable(false)
                .setPositiveButton("Enable GPS", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        Intent callGpsSetting = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        startActivity(callGpsSetting);
                    }
                })
                .setNegativeButton("Exit.", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                        finish();
                    }
                })
                .show();
    }
    return gpsCon;
}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        client.disconnect();
        super.onBackPressed();
    }
}

@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;
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
     Handle navigation view item clicks here.
    int id = item.getItemId();

if (id == R.id.redBuilding){
        latitude = 13.0827;
        longitude = 80.2707;

title = "Chennai";
        subTitle = "TN";

latLon = new LatLng(latitude, longitude);
    }
    mMap.clear();
    mMap.addMarker(new MarkerOptions().position(latLon).title(title).snippet(subTitle)).showInfoWindow();
    CameraPosition cameraPosition = new CameraPosition.Builder().target(latLon).tilt(30).zoom(20).build();
    mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

if (id == R.id.nav_share) {
    } else if (id == R.id.nav_send) {
    }

DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
    mMap.setMyLocationEnabled(true);
    buildGoogleApiClient();
}

private synchronized void buildGoogleApiClient() {
    client = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    client.connect();
}

public Action getIndexApiAction() {
    Thing object = new Thing.Builder()
            .setName("CEG") // TODO: Define a title for the content shown.
             TODO: Make sure this auto-generated URL is correct.
            .setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
            .build();
    return new Action.Builder(Action.TYPE_VIEW)
            .setObject(object)
            .setActionStatus(Action.STATUS_TYPE_COMPLETED)
            .build();
}

@Override
public void onStart() {
    super.onStart();

 ATTENTION: This was auto-generated to implement the App Indexing API.
     See https://g.co/AppIndexing/AndroidStudio for more information.
    client.connect();
    AppIndex.AppIndexApi.start(client, getIndexApiAction());
}

@Override
public void onStop() {
    super.onStop();

 ATTENTION: This was auto-generated to implement the App Indexing API.
     See https://g.co/AppIndexing/AndroidStudio for more information.
    if (client.isConnected()) {
        AppIndex.AppIndexApi.end(client, getIndexApiAction());
        client.disconnect();
    }
}

@Override
public void onConnected(Bundle bundle) {
    location = LocationServices.FusedLocationApi.getLastLocation(client);
    if (location != null) {
        latitude = location.getLatitude();
        longitude = location.getLongitude();
    }
    LatLng latLon = new LatLng(latitude, longitude);
    mMap.addMarker(new MarkerOptions().position(latLon)
            .title("You are here."). snippet("Choose destination from menu to navigate.")
            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA))
    ).showInfoWindow();
    CameraPosition cameraPosition = new CameraPosition.Builder().target(latLon).tilt(30).zoom(20).build();
    mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onLocationChanged(Location location) {

location = location;

Place current location marker
    LatLng latLon = new LatLng(location.getLatitude(), location.getLongitude());
    mMap.clear();
    mMap.addMarker(new MarkerOptions().position(latLon)
            .title("You are here."). snippet("Choose destination from menu to navigate.")
            .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA))
    ).showInfoWindow();
    CameraPosition cameraPosition = new CameraPosition.Builder().target(latLon).tilt(30).zoom(20).build();
    mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

stop location updates
    if (client != null) {
        LocationServices.FusedLocationApi.removeLocationUpdates(client, this);
    }

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 0;

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

 Asking user if explanation is needed
        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {

 Show an explanation to the user *asynchronously* -- don't block
             this thread waiting for the user's response! After the user
             sees the explanation, try again to request the permission.

Prompt the user once explanation has been shown
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION);

} else {
             No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION);
        }
        return false;
    } else {
        return true;
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_LOCATION: {
             If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

 permission was granted. Do the
                 contacts-related task you need to do.
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    if (client == null) {
                        buildGoogleApiClient();
                    }
                    mMap.setMyLocationEnabled(true);
                }
            } else {
                 Permission denied, Disable the functionality that depends on this permission.
                Toast.makeText(this, "Permission denied", Toast.LENGTH_LONG).show();
            }
            return;
        }
         other 'case' lines to check for other permissions this app might request.
         You can add here other case statements according to your requirement.
    }
}
}

Although there are solutions

available, the reason I want to repeat my similar problem is – my goal is to use only one java class, there are solutions that use multiple java classes and files.

Solution

You will need the Directions API.
This is a good tutorial :

https://www.androidtutorialpoint.com/intermediate/google-maps-draw-path-two-points-using-google-directions-google-map-android-api-v2/

You can put all your code in one class. But it’s better to use multiple classes.

Related Problems and Solutions