You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

代码无报错但Google Map无法加载,路线绘制功能失效求助

问题描述

我想实现当前位置与指定点之间的路线绘制功能,但Google Map完全无法加载。我已获取Google Map API并启用了Directions API和Google Maps API,但尚未开通计费服务,怀疑这是否是问题诱因。代码运行无报错,但未实现预期功能。相关代码如下:

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
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.MapFragment;
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.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class MapsFragment extends Fragment implements OnMapReadyCallback {

    SupportMapFragment mapFragment;

    private GoogleMap mMap;
    private LocationManager locationManager;
    private LocationListener locationListener;
    private static final String TAG = "MapsFragment";

    private static final int PERMISSIONS_REQUEST_LOCATION = 100;


    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
        locationListener = new LocationListener() {
            @Override
            public void onLocationChanged(@NonNull Location location) {

            }

            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
            }

            @Override
            public void onProviderEnabled(String provider) {
            }
        };
    }


    @SuppressLint("MissingPermission")
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setMyLocationEnabled(true);

        mMap.getUiSettings().setMyLocationButtonEnabled(true);
        mMap.getUiSettings().setZoomControlsEnabled(true);

        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

        Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if (lastKnownLocation != null) {
            LatLng currentLatLng = new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude());
            mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 15));
        }
    }

    private void drawRoute(LatLng origin, LatLng destination) {
        String apiKey = "AIzaSyB7Dxn7v2_8vyFin-mIq7Fms6qZy72Azfo";
        String url = "https://maps.googleapis.com/maps/api/directions/json?origin=" + origin.latitude + "," + origin.longitude + "&destination=" + destination.latitude + "," + destination.longitude + "&key=" + apiKey;

        RequestQueue queue = Volley.newRequestQueue(getActivity());

        JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONArray routes = response.getJSONArray("routes");
                    if (routes.length() > 0) {
                        JSONArray legs = routes.getJSONObject(0).getJSONArray("legs");
                        if (legs.length() > 0) {
                            JSONArray steps = legs.getJSONObject(0).getJSONArray("steps");
                            if (steps.length() > 0) {
                                PolylineOptions polylineOptions = new PolylineOptions();
                                for (int i = 0; i < steps.length(); i++) {
                                    JSONObject step = steps.getJSONObject(i);
                                    if (step.has("start_location")) {
                                        JSONObject startLocation = step.getJSONObject("start_location");
                                        LatLng startLatLng = new LatLng(startLocation.getDouble("lat"), startLocation.getDouble("lng"));
                                        polylineOptions.add(startLatLng);
                                    }
                                    if (i == steps.length() - 1 && step.has("end_location")) {
                                        JSONObject endLocation = step.getJSONObject("end_location");
                                        LatLng endLatLng = new LatLng(endLocation.getDouble("lat"), endLocation.getDouble("lng"));
                                        polylineOptions.add(endLatLng);
                                    }
                                }

                                polylineOptions.color(Color.BLUE);
                                polylineOptions.width(10);
                                mMap.clear(); // clear existing polylines
                                mMap.addPolyline(polylineOptions);
                            }
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Error getting directions", error);
            }
        });

        queue.add(request);
    }

    // Call this method wherever you want to draw the route
    @SuppressLint("MissingPermission")
    private void showRoute() {
        LatLng originLatLng = new LatLng(9.2879, 4.1489);

            @SuppressLint("MissingPermission") Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            if (lastKnownLocation != null) {
                LatLng currentLatLng = new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude());
                drawRoute(currentLatLng, originLatLng);
            } else {
                // Last known location not available, request location updates
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
            }

    }
}
解决方案

1. 必须开通Google Cloud计费账户

目前Google Maps Platform要求所有使用API的项目都必须绑定计费账户,即使仅使用免费额度。未开通计费的情况下,地图加载和Directions API请求都会被直接拒绝,这是地图无法加载的核心原因。

2. 补全动态权限申请逻辑

代码中直接用@SuppressLint("MissingPermission")跳过权限检查,但Android系统需要动态申请位置权限,否则无法获取位置信息,也会影响地图正常加载。添加以下逻辑:

private void checkLocationPermission() {
    if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_REQUEST_LOCATION);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == PERMISSIONS_REQUEST_LOCATION) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            if (mMap != null) {
                try {
                    mMap.setMyLocationEnabled(true);
                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
                    showRoute();
                } catch (SecurityException e) {
                    Log.e(TAG, "Permission denied", e);
                }
            }
        }
    }
}

并在onMapReady方法开头调用checkLocationPermission()。

3. 触发路线绘制方法

代码中showRoute()仅定义未调用,需在地图加载完成且权限通过后触发,比如在onMapReady或权限回调中调用。

4. 补全LocationListener回调逻辑

当前onLocationChanged方法为空,当lastKnownLocation为空时,获取到新位置后无法触发路线绘制,补充逻辑:

locationListener = new LocationListener() {
    @Override
    public void onLocationChanged(@NonNull Location location) {
        LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
        LatLng originLatLng = new LatLng(9.2879, 4.1489);
        drawRoute(currentLatLng, originLatLng);
        locationManager.removeUpdates(this);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {}

    @Override
    public void onProviderEnabled(String provider) {}
};

5. 增强错误排查能力

在Directions API错误回调中打印详细响应内容,帮助定位问题:

new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        Log.e(TAG, "Error getting directions", error);
        if (error.networkResponse != null) {
            String errorMsg = new String(error.networkResponse.data);
            Log.e(TAG, "Error response: " + errorMsg);
        }
    }
}

内容的提问来源于stack exchange,提问作者Ngulle Nanga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:47:23