简体   繁体   English

如何使用Google Maps Android API在MapFragment中的两点之间绘制路线

[英]How to draw route between two points in MapFragment using Google Maps Android API

My target is to complete the following tasks in one single class. 我的目标是在一个单独的课程中完成以下任务。

I want to give direction between two pointers (current location & prefixed location in navigation drawer) in Google Android Map API. 我想在Google Android Map API中指出两个指针(导航抽屉中的当前位置和前缀位置)之间的方向。

  1. Is it possible or do I need Directions API? 是可能还是我需要Directions API? Can't direction be done in Android Maps API itself? 无法在Android Maps API中完成指导吗?

  2. My goal is to use only one activity or java file for all tasks like fetch current location and show the destination pointer in map (which I have done). 我的目标是只使用一个活动或java文件来执行所有任务,例如获取当前位置并在地图中显示目标指针(我已经完成)。 Now I want to give the route for these two pointers and the route must change when the prefixed pointer or location is changed by the used. 现在我想给这两个指针指定路由,并且当使用前缀指针或位置改变时,路径必须改变。

By prefixed, I mean the location I have already given in the if else in onNavigationItemSelected(). 通过前缀,我的意思是我已经在onNavigationItemSelected()中的if else中给出的位置。

Please refer the below code which is the MainActivity.java - My target is to complete all the tasks in one java class itself. 请参考以下代码,即MainActivity.java - 我的目标是完成一个java类本身的所有任务。

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.
    }
}
}

I would like to iterate the reason from my similar question in spite of available solutions is that - my target is to use only one java class, there are solutions using multiple java classes and files. 我想从我的类似问题迭代原因,尽管可用的解决方案是 - 我的目标是只使用一个java类,有使用多个java类和文件的解决方案。

You will need direction api. 你需要方向api。 Here is good tutorial: 这是一个很好的教程:

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

You can put all code in one class. 您可以将所有代码放在一个类中。 But it is better to use multiple class. 但最好使用多个类。

If you are already using the Google Maps Fragment and just want to add lines to the map (ie record a route vs plot a route), adding a line (called a poly line) is trivial. 如果您已经在使用谷歌地图片段 ,只想在地图上添加线条(即记录路线与绘制路线),添加一条线(称为多边线)是微不足道的。

Start by creating a PolyLineOptions (saving the reference allows you to update it later): 首先创建PolyLineOptions(保存引用允许您稍后更新):

PolylineOptions routeLine;
LatLng pos = new LatLng(location.getLatitude(), location.getLongitude());
routeLine = new PolylineOptions().add(pos);

At this point the line won't show, to make it show there are two requirements: Add it to the map and Add at least one more point: 此时线条将不会显示,以显示有两个要求:将其添加到地图并添加至少一个点:

routeLine.add(new LatLng(nextLocation.getLatitude(), nextLocation.getLongitude()));
map.addPolyline(routeLine);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM