如何修改ActivityMain代码:替换起点为当前位置、终点为坐标点
解决方案:替换起点为当前位置、终点为任意坐标的行程应用修改
1. 核心修改思路
要实现你的需求,核心要做两件事:
- 动态获取设备当前位置(需要申请权限+依赖位置服务)
- 将终点设为自定义坐标,调用地图服务API计算行程距离与时长
2. 权限前置配置(AndroidManifest.xml)
首先要在清单文件中添加必要的权限:
<!-- 高精度/粗略位置权限 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 网络权限(调用路线API需要) --> <uses-permission android:name="android.permission.INTERNET" />
3. ActivityMain代码修改示例
假设你的原代码是硬编码了起点坐标,下面是修改后的完整代码,包含当前位置获取、自定义终点和路线计算逻辑:
import android.Manifest; import android.content.pm.PackageManager; import android.location.Location; import android.os.Bundle; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import com.google.android.gms.location.FusedLocationProviderClient; import com.google.android.gms.location.LocationServices; import com.google.android.gms.tasks.OnSuccessListener; import com.google.android.gms.tasks.Task; import com.google.maps.DirectionsApi; import com.google.maps.GeoApiContext; import com.google.maps.model.DirectionsResult; import com.google.maps.model.TravelMode; public class MainActivity extends AppCompatActivity { // 替换为你自己的Google Maps API Key(需在云控制台启用Directions API) private static final String API_KEY = "YOUR_GOOGLE_MAPS_API_KEY"; private FusedLocationProviderClient fusedLocationClient; private TextView distanceTv, durationTv; // 示例自定义终点坐标(可根据业务需求动态修改) private static final double DEST_LAT = 40.7580; // 纽约时代广场纬度 private static final double DEST_LNG = -73.9855; // 纽约时代广场经度 private static final int LOCATION_PERMISSION_CODE = 1001; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); distanceTv = findViewById(R.id.tv_distance); durationTv = findViewById(R.id.tv_duration); fusedLocationClient = LocationServices.getFusedLocationProviderClient(this); // 先检查权限,再获取当前位置 checkLocationPermission(); } // 检查并申请位置权限 private void checkLocationPermission() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_CODE); return; } // 权限已获取,开始拿当前位置 fetchCurrentLocation(); } // 获取设备当前位置 private void fetchCurrentLocation() { Task<Location> locationTask = fusedLocationClient.getLastLocation(); locationTask.addOnSuccessListener(this, location -> { if (location != null) { // 拿到当前位置的经纬度 double startLat = location.getLatitude(); double startLng = location.getLongitude(); // 调用路线计算函数 calculateTripRoute(startLat, startLng, DEST_LAT, DEST_LNG); } else { distanceTv.setText("无法获取当前位置,请开启位置服务"); } }); } // 调用Directions API计算路线 private void calculateTripRoute(double startLat, double startLng, double destLat, double destLng) { // 初始化API上下文 GeoApiContext apiContext = new GeoApiContext.Builder() .apiKey(API_KEY) .build(); // 子线程执行网络请求,避免阻塞主线程 new Thread(() -> { try { DirectionsResult result = DirectionsApi.newRequest(apiContext) .origin(new com.google.maps.model.LatLng(startLat, startLng)) .destination(new com.google.maps.model.LatLng(destLat, destLng)) .mode(TravelMode.DRIVING) // 可替换为WALKING/TRANSIT等 .await(); // 解析返回结果,更新UI必须在主线程 runOnUiThread(() -> { if (result.routes.length > 0) { String distance = result.routes[0].legs[0].distance.humanReadable; String duration = result.routes[0].legs[0].duration.humanReadable; distanceTv.setText("行程距离:" + distance); durationTv.setText("预计时长:" + duration); } else { distanceTv.setText("未找到可行路线"); } }); } catch (Exception e) { e.printStackTrace(); runOnUiThread(() -> distanceTv.setText("路线计算失败:" + e.getMessage())); } }).start(); } // 权限请求回调 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == LOCATION_PERMISSION_CODE) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { fetchCurrentLocation(); } else { distanceTv.setText("需要位置权限才能获取起点"); } } } }
4. 关键函数运行情况记录
checkLocationPermission()
- 运行逻辑:检查位置权限状态,未授权则弹出系统权限请求框
- 运行结果:
- 权限授予:自动调用
fetchCurrentLocation() - 权限拒绝:显示提示文本,无法继续获取起点
- 权限授予:自动调用
fetchCurrentLocation()
- 运行逻辑:通过Google的
FusedLocationProviderClient获取设备最后已知位置 - 运行结果:
- 获取成功:拿到当前经纬度,触发
calculateTripRoute() - 获取失败:提示用户开启位置服务或检查设备设置
- 获取成功:拿到当前经纬度,触发
calculateTripRoute()
- 运行逻辑:在子线程中调用Google Directions API,解析返回的路线数据
- 运行结果:
- 路线存在:解析距离和时长,在主线程更新UI显示
- 无可行路线:显示“未找到可行路线”提示
- API调用失败:显示具体错误信息(如网络异常、API Key无效)
5. 额外注意事项
- 必须在Google Cloud Console中启用Directions API,并为API Key配置Android应用的包名和签名限制
- 若需要实时更新当前位置(如用户移动时),可以改用
LocationCallback监听位置变化,而不是只获取一次最后已知位置 - 网络请求必须放在子线程,否则会触发ANR(应用无响应)
内容的提问来源于stack exchange,提问作者Matheo Espitia
相关产品推荐
相关产品推荐

