代码无报错但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
相关产品推荐
相关产品推荐

