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

Android Studio(Java)中Maps Directions API路线不显示求助

问题诊断与修复方案

从代码和描述来看,Directions API调用成功(Cloud后台有调用量)但地图不显示路线,核心问题集中在路径点收集、线程操作和标记管理上,以下是具体诊断和修复方案:

核心问题分析

  1. 路径点收集不完整:仅提取每个DirectionsStep的startLocation,未解析step中包含完整路线的encodedPolyline,导致生成的折线只有零散节点,无法形成连续路线。
  2. 后台线程操作UI:Google Maps Services的回调运行在后台线程,直接调用mMap.addPolyline违反Android UI线程规则,折线无法正确绘制。
  3. 初始Marker未加入列表:onMapReady中首次添加的"Ubicación actual" Marker未加入markers集合,导致点击按钮时getCurrentLocation可能返回null。
  4. 错误回调未处理:onFailure无任何日志提示,无法排查API返回的潜在错误。

修复后的完整代码

package com.example.mapa;

import android.Manifest;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;

import com.example.mapa.databinding.RutaLocalBinding;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
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.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import com.google.maps.DirectionsApi;
import com.google.maps.DirectionsApiRequest;
import com.google.maps.GeoApiContext;
import com.google.maps.PendingResult;
import com.google.maps.android.PolyUtil;
import com.google.maps.model.DirectionsResult;
import com.google.maps.model.DirectionsRoute;
import com.google.maps.model.DirectionsStep;
import com.google.maps.model.TravelMode;

import java.util.ArrayList;
import java.util.List;

public class RutaLocal extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    private RutaLocalBinding binding;
    private FusedLocationProviderClient fusedLocationProviderClient;
    private Polyline routePolyline;
    private List<Marker> markers = new ArrayList<>();
    private Handler mainHandler = new Handler(Looper.getMainLooper()); // 主线程Handler


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = RutaLocalBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        Button btnRuta = binding.btnRuta;
        btnRuta.setOnClickListener(v -> {
            LatLng currentLocation = getCurrentLocation();
            LatLng destination = getDestinationLocation();

            if (currentLocation != null && destination != null) {
                getDirections(currentLocation, destination);
            } else {
                Toast.makeText(RutaLocal.this, "No hay puntos", Toast.LENGTH_SHORT).show();
            }
        });

        // 合并权限请求,避免重复弹窗
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                    100);
        }

        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);

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

    private LatLng getCurrentLocation() {
        for (Marker marker : markers) {
            if (marker.getTitle().equals("Ubicación actual")) {
                return marker.getPosition();
            }
        }
        return null;
    }

    private LatLng getDestinationLocation() {
        for (Marker marker : markers) {
            if (marker.getTitle().equals("Destino")) {
                return marker.getPosition();
            }
        }
        return null;
    }


    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        fusedLocationProviderClient.getLastLocation()
                .addOnSuccessListener(this, location -> {
                    if (location != null) {
                        double latitude = location.getLatitude();
                        double longitude = location.getLongitude();

                        LatLng currentLocation = new LatLng(latitude, longitude);
                        // 将初始Marker加入markers列表
                        Marker currentMarker = mMap.addMarker(new MarkerOptions().position(currentLocation).title("Ubicación actual"));
                        markers.add(currentMarker);
                        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLocation, 15));

                        mMap.setOnMapClickListener(point -> {
                            mMap.clear();
                            markers.clear();
                            LatLng currentLoc = new LatLng(latitude, longitude);
                            Marker currMarker = mMap.addMarker(new MarkerOptions().position(currentLoc).title("Ubicación actual"));
                            markers.add(currMarker);
                            Marker destinationMarker = mMap.addMarker(new MarkerOptions().position(point).title("Destino"));
                            markers.add(destinationMarker);
                            getDirections(currentLoc, point);
                        });
                    }
                });
    }

    private void getDirections(LatLng origin, LatLng destination) {
        GeoApiContext context = new GeoApiContext.Builder()
                .apiKey("你的API Key")
                .build();

        DirectionsApiRequest request = DirectionsApi.newRequest(context)
                .mode(TravelMode.DRIVING)
                .origin(new com.google.maps.model.LatLng(origin.latitude, origin.longitude))
                .destination(new com.google.maps.model.LatLng(destination.latitude, destination.longitude));

        request.setCallback(new PendingResult.Callback<DirectionsResult>() {
            @Override
            public void onResult(DirectionsResult result) {
                mainHandler.post(() -> { // 切换到主线程操作UI
                    if (routePolyline != null) {
                        routePolyline.remove();
                    }

                    if (result.routes == null || result.routes.length == 0) {
                        Toast.makeText(RutaLocal.this, "未找到可用路线", Toast.LENGTH_SHORT).show();
                        return;
                    }

                    DirectionsRoute route = result.routes[0];
                    List<LatLng> points = new ArrayList<>();

                    // 解析每个step的encodedPolyline,获取完整路径点
                    for (DirectionsStep step : route.legs[0].steps) {
                        points.addAll(PolyUtil.decode(step.polyline.getEncodedPath()));
                    }

                    PolylineOptions polylineOptions = new PolylineOptions()
                            .addAll(points)
                            .color(Color.BLUE)
                            .width(8); // 加宽折线,更容易看到
                    routePolyline = mMap.addPolyline(polylineOptions);
                });
            }

            @Override
            public void onFailure(Throwable e) {
                mainHandler.post(() -> {
                    Toast.makeText(RutaLocal.this, "路线请求失败:" + e.getMessage(), Toast.LENGTH_LONG).show();
                    e.printStackTrace();
                });
            }
        });
    }
}

关键修复说明

  1. 完整解析路径点:使用PolyUtil.decode(step.polyline.getEncodedPath())解析每个step的编码折线,获取路线的所有坐标点,替代之前仅取startLocation的方式。
  2. 主线程操作UI:通过Handler将添加折线的操作切换到主线程,符合Android UI线程规则。
  3. 完善Marker管理:初始添加的当前位置Marker加入markers集合,保证按钮点击时能正确获取起点。
  4. 错误处理:在onFailure中添加错误提示和日志,方便排查API调用异常。
  5. 合并权限请求:将两个位置权限请求合并,避免重复弹窗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:24:57